内容
AWS Fargateを導入することになり、CircleCI Orbsを使ったデプロイが便利だったのでご紹介。
内容は、AWS Fargateが構築済であることを想定しており、AWS Fargateについては説明していません。
また、本番での本格的な運用は行っていないのであくまで参考程度でお願いします。
大まかな流れとしては、
- ECRにリポジトリを作成
- IAM User作成
- CircleCIの環境変数の設定
- .circleci/config.yamlの設定
となります。
CircleCI Orbsとは
CircleCI Orbs は、ジョブ、コマンド、Executor のような設定要素をまとめた共有可能なパッケージです。 CircleCI 独自の認証済み Orbs のほか、パートナー企業によるサードパーティ製 Orbs を用意しています。
引用元:https://circleci.com/docs/ja/2.0/orb-intro/
こちらからパッケージを検索できます。
例えば今回使用するaws-ecr
のリポジトリはこちら
今までだと、CircleCI上からECRにイメージをPushしようとするとAWS CLIのインストールとかやってた?かと思うんですが
orbsを使うことで決められたジョブに必要なパラメーターさえ渡せばよろしくやってくれます。
コード量を減らして可読性のあるconfig.yamlが作れる点がいいですね。
要件
今回の要件を以下に整理します。
- とあるブランチ(例としてstagingブランチ)にマージされたら特定のClusterのTask定義を更新し、自動でデプロイしたい。
- db migrationは不要(別処理ですでに実装されているため)
事前準備
- CircleCIとGithubのインテグレーションは設定しておく。
設定
ECRにリポジトリを作成
まずはDockerイメージを保存するリポジトリを作成。
$ aws ecr create-repository --repository-name <ECRのリポジトリ名>
IAM User作成
CircleCIからデプロイさせるために、IAM Userを作成し、以下のAWS 管理ポリシーを付与します。
- AmazonEC2ContainerRegistryFullAccess
- AmazonECS_FullAccess
アカウント作成後、アクセスキーを作成し、Credentials(Access key ID,Secret access key)を保存します。
CircleCIの環境変数設定
必要なAWS関連の情報をCircleCIの環境変数に設定します。
Name | Value |
---|---|
AWS_ACCESS_KEY_ID | 保存した Access key ID |
AWS_SECRET_ACCESS_KEY | 保存した Secret access key |
AWS_ECR_ACCOUNT_URL | AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com |
AWS_REGION | AWS Region(今回はap-northeast-1) |
.circleci/config.yaml の設定
以下のように設定しました。
version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@1.0.0 (1)使用するOrbsを設定
aws-ecs: circleci/aws-ecs@0.0.6
executors:
docker_build:
machine:
docker_layer_caching: true (2)キャッシュを有効化
workflows:
build-and-deploy:
jobs:
- build
- aws-ecr/build_and_push_image:
executor: docker_build
name: 'build-staging'
account-url: AWS_ECR_ACCOUNT_URL
region: AWS_REGION
repo: '<ECRのリポジトリ名>' (3)作成したリポジトリ名を入れる
tag: "${CIRCLE_SHA1}" (4)イメージのタグにコミットのハッシュ値付与
path: ./
dockerfile: Dockerfile-staging (5)ビルドに使用したいDockerFileを指定
requires:
- build
filters:
branches:
only:
- staging (6)stagingブランチにpushがあった時のみ発火
- aws-ecs/deploy-service-update:
requires:
- build-staging
family: '<Fargateのタスク定義名>'
service-name: '<Fargateのサービス名>'
cluster-name: '<Fargateのクラスタ名>'
container-image-name-updates: 'container=<タスク定義で設定したコンテナ名>,image-and-tag=${AWS_ECR_ACCOUNT_URL}/<ECRのリポジトリ名>:${CIRCLE_SHA1}' (7)イメージのPush
filters:
branches:
only:
- staging
ざっくり解説すると、
-
aws-ecs/aws-ecr/build_and_push_image
で指定したDockerfileでイメージのビルドとECRへのプッシュ -
aws-ecs/deploy-service-update
でタスク定義を新たなリビジョンで作成し、Fargateのサービスで指定しているタスク定義のリビジョンを最新のものに更新
といった動きします。
(7) では、タスク定義で設定しているイメージのURL(AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/ECRのリポジトリ名:CIRCLE_SHA1で付与したタグ
)を最新のものに更新しているようです。
そうして新たに作成したタスク定義のリビジョンをFargateのサービスで設定することでデプロイ(今回はサービスにローリングアップデートを設定)が走るという仕組みです。
課題
今回はマイグレーションする必要がなかったですが、通常であればマイグレーションする処理を入れる必要があるかと思います。
やり方としては、マイグレーション用のタスク定義を用意しておいて、そのタスク定義を走らせる(aws ecs run-task
)みたいなことができないかな?と考えています。
ロールバックは、今のところマネジメントコンソールからやる手動でやることを想定していますが、このあたりも要改善です。
他に良いやり方があれば教えてください。
まとめ
Orbs便利。他にもいろんなOrbsがあるみたいなのでどんどん使っていこうと思います。
参考