こんにちは。
CircleCI カスタマーサクセスチームの Chisato です。
最近個人的に幸せを感じた出来事は、ビリヤニをつくったことです。
本場のハイデラバードでビリヤニを食べることが目標の1つに加わりました。
今回は、CircleCI を使用して、Amazon Elastic Container Registry (ECR) から Amazon Elastic Container Service (ECS) にデプロイします。
CircleCI のドキュメンテーション 「AWS ECR/ECS へのデプロイ 」を参考に進めます。
準備するもの
- CircleCI アカウント
- AWSアカウント
- Terraform
- サンプルプロジェクト(クローンしておく) ― "CircleCI-Public/circleci-demo-aws-ecs-ecr"
Terraform のインストール
Terraform は、HashiCorp社 が提供する IaC (Infrastructure as Code)のツールで、構築、変更、バージョン管理といったインフラの構成管理を安全かつ効率的に実行可能にします。
こちらのページ にアクセスして、Terraform をインストールします。
今回は macOS のオープンソース版をインストールしました。
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
CircleCI 環境変数の設定
CircleCI のサンプルプロジェクト をクローンして、CircleCI の [Project Settings] ページに移動します。
[Environment Variables] タブをクリックして、[Add Environment Variables] をクリックします。
下記テーブルの環境変数を設定していきます。
環境変数の値の確認方法は後述します。
設定する環境変数一覧
変数 | 説明 |
---|---|
AWS_ACCESS_KEY_ID |
AWS のセキュリティ認証情報です。 |
AWS_SECRET_ACCESS_KEY |
AWS のセキュリティ認証情報です。 |
AWS_DEFAULT_REGION |
AWS CLI によって使用されます。 |
AWS_ACCOUNT_ID |
デプロイに必要です。 AWS アカウント ID はこちらで確認してください。 |
AWS_RESOURCE_NAME_PREFIX |
必須の AWS リソースのプレフィックスです。 terraform_setup/terraform.tfvars の aws_resource_prefix の値に対応する必要があります。 |
AWS_ECR_REGISTRY_ID |
ECR アカウントに関連づけられた 12 桁の AWS ID です。 |
上記のうち AWS_DEFAULT_REGION
について、「CircleCI 環境変数を設定する」のページでは AWS_REGION
という表記ですが、今回は Config.yml ファイル内の記述に合わせて AWS_DEFAULT_REGION
としています。
環境変数の値の確認方法
1. AWS_ACCESS_KEY_ID
と AWS_SECRET_ACCESS_KEY
は、AWS のコンソールから [IAM]、[Users]、対象のユーザーのページに移動して、[Security Credentials]タブをクリックします。
スクロールダウンすると、Access Keys
の項目があります。
アクセスキーは、Create Access Key
をクリックして作成できます。
Access key
, Secret Access Key
をそれぞれコピーして環境変数として登録します。
2. AWS_ACCOUNT_ID
はこちらに確認方法が記載されています。
コンソールから確認するには、[サポート]、[サポートセンター]と進み、ナビゲーションペインをチェックします。
Terraform ファイルの設定
~/terraform_setup/terraform.tfvars
のファイルを開き、各項目に実際の値を入力します。環境変数名ではなく、実際の値であることに注意してください。
AWS のリソースの作成
Terraform を下記手順で実行します。
cd terraform_setup
terraform init
terraform plan # プランをレビューします
terraform apply # プランを適用して AWS リソースを作成します
私は最初、ECR の Repository を手動で作成してしまったことによりエラーが出ました。 上記コマンドで、 ECR の Repository まで自動生成してくれます。
最後まで進むと下記メッセージが表示されます。
AWSのコンソールを見てみると、ばっちり作成されています。
Config.yml ファイルの編集
今回、このプロジェクトで幾度となくエラーに苦しみ、しばらく田舎に帰ろうかなと思い始めたとき、目の前にひと筋の光が差し込みました。
CircleCIが誇る素晴らしいエンジニアの方々、Jasurさん、Kelvinさん、Jenningsさんです。
彼らにご指導いただきながら、一緒にConfig.yml ファイルを見ていくなかで、一部の記述を変えることになりました。
このため、サンプルプロジェクトのものを下記のように変更しています。
変更箇所にコメントを追記しています。
version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@8.2.1 # orbのバージョン変更
aws-ecs: circleci/aws-ecs@3.2.0 # orbのバージョン変更
workflows:
build-and-deploy:
jobs:
- aws-ecr/build-and-push-image: # build_and_push_image を build-and-push-imageに変更
repo: "${AWS_RESOURCE_NAME_PREFIX}" #account_url, regionの記述を削除
tag: "${CIRCLE_SHA1}"
- aws-ecs/deploy-service-update:
requires:
- aws-ecr/build-and-push-image # build_and_push_image を build-and-push-imageに変更
aws-region: AWS_DEFAULT_REGION # ${AWS_DEFAULT_REGION} を AWS_DEFAULT_REGIONに変更
family: "${AWS_RESOURCE_NAME_PREFIX}-service"
cluster: "${AWS_RESOURCE_NAME_PREFIX}-cluster" #cluster_name をclusterに変更
container-image-name-updates: "container=${AWS_RESOURCE_NAME_PREFIX}-service,image-and-tag=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${AWS_RESOURCE_NAME_PREFIX}:${CIRCLE_SHA1}"
verify-revision-is-deployed: true
post-steps:
- run:
name: Test the deployment
command: |
TARGET_GROUP_ARN=$(aws ecs describe-services --cluster ${AWS_RESOURCE_NAME_PREFIX}-cluster --services ${AWS_RESOURCE_NAME_PREFIX}-service | jq -r '.services[0].loadBalancers[0].targetGroupArn')
ELB_ARN=$(aws elbv2 describe-target-groups --target-group-arns $TARGET_GROUP_ARN | jq -r '.TargetGroups[0].LoadBalancerArns[0]')
ELB_DNS_NAME=$(aws elbv2 describe-load-balancers --load-balancer-arns $ELB_ARN | jq -r '.LoadBalancers[0].DNSName')
curl -s --retry 10 http://$ELB_DNS_NAME | grep "Welcome to nginx!"
ちなみに、下記は途中出てきたエラーの一部です。
1. 環境変数の値ではなく環境変数名を入れてね、というメッセージ。${}
部分を取り除きました。
Type error for argument region: expected type: env_var_name, actual value: "${AWS_DEFAULT_REGION}" (type string)
2. Cluster という引数が見つからないよ、というメッセージ。cluster_name
をcluster
に変えました。
Error calling job: 'aws-ecs/deploy-service-update'
Missing required argument(s): cluster
こうして、ビルド37回目にしてようやく成功しました。 こんなに Success の文字が美しく見えたことはありません。 背景の洗練されたグリーンがいい仕事してます。
まとめ
今回初めて、 CircleCI と AWS、そして Terraform を組み合わせたプロジェクトにトライしてみました。
ビルド37回目にしてようやく成功した背景には、CircleCIの素晴らしいエンジニアたち、Jasurさん、Kelvinさん、Jenningsさんのご指導があります。
ほんとうにありがとうございました。
次回以降もぜひ、CircleCI と AWS、Terraform を使用したプロジェクトに挑戦してみたいと思います。
CircleCIへのご質問がありましたら、サポートセンターまでお気軽にお問い合わせください。