search
LoginSignup
0

More than 1 year has passed since last update.

posted at

updated at

Organization

CiecleCI の Workflow job に名前をつけて依存を管理する

動機: CircleCI Orbs を使ったときに困ったこと

CircleCI Orbs を使うことで、AWS ECRへのイメージPushなどを行ってくれますが、ブランチごとに別々のリポジトリにpushしたい場合などは少し困ったことになります。

以下、正しく動作しないケースです。

.circleci/config.yml
version: 2.1
orbs:
  aws-ecr: circleci/aws-ecr@6.15.1
  aws-ecs: circleci/aws-ecs@1.4.0
# 中略
workflows:
  build:
    jobs:
      # 中略
      # Staging 用のデプロイ
      - aws-ecr/build-and-push-image
          repo: "Staging用リポジトリ"
          tag: "${CIRCLE_SHA1}"
          requires:
            - test
            - lint
          filters: &staging-filter
            branches:
              only:
                - staging
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          family: 'Staging用ファミリー'
          cluster-name: 'Staging用クラスター名'
          container-image-name-updates: 'container=Staging用コンテナ名,tag=${CIRCLE_SHA1}'
          filters: *staging-filter
      # Production用のデプロイ
      - aws-ecr/build-and-push-image
          repo: "Production用リポジトリ"
          tag: "${CIRCLE_SHA1}"
          requires:
            - test
            - lint
          filters: &master-filter
            branches:
              only:
                - master
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          family: 'Production用ファミリー'
          cluster-name: 'Production用クラスター名'
          container-image-name-updates: 'container=Production用コンテナ名,tag=${CIRCLE_SHA1}'
          filters: *master-filter

こんなかんじのエラーが出てしまいます。

Job 'aws-ecs/deploy-service-update' requires 'aws-ecr/build-and-push-image', which is the name of 2 other jobs in workflow 'build'

You can give a job within a workflow an explicit name by adding a `name` key

Orbs に定義されている、 aws-ecs/deploy-service-update job 実行の前提として必要としている、aws-ecr/build-and-push-image が Staging 用と、Production 用の2つ用意してしまっているため、うまく動作しないとのことです。

ヘルプメッセージに従って、name を Workflow の job に指定すれば良さそうです。

ひとまず、ドキュメントを読んでみたのですが、 今の所 (2021年1月8日現在) この点についての記載はなさそうです。。。

2021/1/9 14:00 修正

ドキュメントに記載はありました。 ドキュメントの解釈を誤っており、namerequires の下で使えるものだと勘違いしておりました。
job の下で namerequires のために使えるという記載っぽいです。 @PanonCotta さんご指摘ありがとうございます。

image.png

修正後

.circleci/config.yml
version: 2.1
orbs:
  aws-ecr: circleci/aws-ecr@6.15.1
  aws-ecs: circleci/aws-ecs@1.4.0
# 中略
workflows:
  build:
    jobs:
      # 中略
      # Staging 用のデプロイ
      - aws-ecr/build-and-push-image
          name: "ecr-build-and-push-image-stg"
          repo: "Staging用リポジトリ"
          tag: "${CIRCLE_SHA1}"
          requires:
            - test
            - lint
          filters: &staging-filter
            branches:
              only:
                - staging
      - aws-ecs/deploy-service-update:
          name: "ecs-deploy-stg"
          requires:
            - ecr-build-and-push-image-stg
          family: 'Staging用ファミリー'
          cluster-name: 'Staging用クラスター名'
          container-image-name-updates: 'container=Staging用コンテナ名,tag=${CIRCLE_SHA1}'
          filters: *staging-filter
      # Production用のデプロイ
      - aws-ecr/build-and-push-image
          name: "ecr-build-and-push-image-prod"
          repo: "Production用リポジトリ"
          tag: "${CIRCLE_SHA1}"
          requires:
            - test
            - lint
          filters: &master-filter
            branches:
              only:
                - master
      - aws-ecs/deploy-service-update:
          name: "ecs-deploy-prod"
          requires:
            - ecr-build-and-push-image-prod
          family: 'Production用ファミリー'
          cluster-name: 'Production用クラスター名'
          container-image-name-updates: 'container=Production用コンテナ名,tag=${CIRCLE_SHA1}'
          filters: *master-filter

これで、ECRにpushするイメージ作成と、ECSによるサービス展開までについてを環境別に分けることができました。

この設定のやりかたは、同じjobを再利用しつつ、環境別にパラメータを変えるといったときにも便利そうです。
検証用に、以下のようなサンプルを作ってみて実行してみたところ、job1, job2 を再利用することができました。

.circleci/config.yml
version: 2.1

executors:
  ruby-executor:
    docker:
      - image: circleci/ruby:3.0.0

jobs:
  job1:
    executor: ruby-executor
    # https://circleci.com/docs/2.0/reusing-config/#authoring-parameterized-jobs
    # Workflow からパラメータを渡すことができる
    parameters:
      env:
        type: string
        default: development
    steps:
      - checkout
      - run: 'ruby --version'
      # パラメータを使う時は、<<parameters.キー>> で呼び出しできる
      - run: 'echo <<parameters.env>>'
  job2:
    executor: ruby-executor
    parameters:
      env:
        type: string
        default: development
    steps:
      - checkout
      - run: 'ruby --version'
      - run: 'echo <<parameters.env>>'

workflows:
  build:
    jobs:
      # master のみ
      - job1:
          name: job1-master
          # env パラメータを production として job にわたす
          env: production
          filters: &master-filter
            branches:
              only:
                - master
      - job2:
          name: job2-master
          env: production
          filters: *master-filter
          requires:
            - job1-master
      # master 以外
      - job1:
          name: job1-non-master
          # env パラメータを指定してないので、job の `<<parameters.env>>` は、
          # default にセットしている、development に置き換わる
          filters: &non-master-filter
            branches:
              ignore:
                - master
      - job2:
          name: job2-non-master
          filters: *non-master-filter
          requires:
            - job1-non-master

まとめ

Workflow Job に名前が使えるようになったのも、Jobにパラメータが渡せるようになったのも、
ドキュメントの雰囲気を見るに2.1からのようです。

昔から運用している、 .circleci/config.yml の場合、環境ごとに別々にjobを作ったり、
command で以下のように書いているケースがありました。

          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
                bundle exec cap production deploy
            elif [ "${CIRCLE_BRANCH}" == "staging" ]; then
                bundle exec cap staging deploy
            fi

なかなか難儀なのでコンパクトに

          command: bundle exec cap <<parameters.env>> deploy

などに変更するなどして、スマートなCiecleCI設定ライフを送りたいものです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0