はじめに
弊社では、ソフトウェアの品質を高めるために、継続的な自動テスト・E2Eテストを実行しています。
その際、CircleCIというSaaSのCIサービスを利用しています。
また、AWSを利用しているサービスでは、開発用のAWSアカウントと本番用のAWSアカウントを分けて利用しています。
開発用アカウントでは、エンジニアが比較的自由に実験・開発を進めつつ、本番はセキュリティガチガチで守っていこうという方針です。
そのため、サービスの開発環境は開発用AWSアカウントに配置し、本番環境は本番用AWSアカウントに配置したいという要望が生まれます。
そのような複数AWSアカウントをCircleCIでどのように扱えばよいのかという記事です。
結論
- CircleCIのContexts機能が便利。
結果は以上です。
その過程で試した方法があるのでまとめておきます。
方法1: ProjectのAWS Permissionを利用する方法
スクショの文言通り、AWSのIAMユーザーを登録すると、よしなにやってくれる機能です。
これの問題点としては
- 1つのアカウントしか登録できない。
- 2018年8月31日でサポートが終了する。
などが上げられるかと思います。
方法2: ProjectのEnvironment Variablesを利用する方法
CircleCIのUI的にもEnvironment Variablesは目立つところにあるので、使っている方は多いのではないでしょうか。
Environment Variablesを使った場合には
Name | Value |
---|---|
DEV_AWS_ACCESS_KEY_ID | dev-hogehoge |
DEV_AWS_SECRET_ACCESS_KEY | dev-piyopiyo |
PRD_AWS_ACCESS_KEY_ID | prd-hogehoge |
PRD_AWS_SECRET_ACCESS_KEY | prd-piyopiyo |
こんな感じの環境変数を設定します。画面的にはこんな感じになります。
jobの中で環境変数の AWS_ACCESS_KEY_ID
と AWS_SECRET_ACCESS_KEY
を設定するか、~/.aws/credentials
を書き換える事になると思います。
例えばこんな感じ。
mkdir -p ~/.aws
echo "[default]" > ~/.aws/credentials
if [[ "${CIRCLE_BRANCH}" == "master" ]]; then
echo "aws_access_key_id = ${PRD_AWS_ACCESS_KEY_ID}" >> ~/.aws/credentials
echo "aws_secret_access_key = ${PRD_AWS_SECRET_ACCESS_KEY}" >> ~/.aws/credentials
echo "region = ap-northeast-1" >> ~/.aws/credentials
else
echo "aws_access_key_id = ${DEV_AWS_ACCESS_KEY_ID}" >> ~/.aws/credentials
echo "aws_secret_access_key = ${DEV_AWS_SECRET_ACCESS_KEY}" >> ~/.aws/credentials
echo "region = ap-northeast-1" >> ~/.aws/credentials
fi
この方法の問題点としては
- ステージング環境を増やす時に面倒です。
- 上記シェルスクリプトがちゃんと意図した動きするか不安。開発環境へのデプロイのつもりが、うっかり本番デプロイなんて怖すぎます。
などが上げられるかと思います。
方法3: CircleCIのContexts機能を利用する方法
OrganizationのSettings画面の下の方にひっそりとContexts機能があります。
Environment Variablesだとプロジェクトごとに定義するが、Contexts機能ではプロジェクト横断で環境変数を利用できます。
ここでは、こんな感じに設定します。
Context: aws-dev
Name | Value |
---|---|
AWS_ACCESS_KEY_ID | dev-hogehoge |
AWS_SECRET_ACCESS_KEY | dev-piyopiyo |
Context: aws-prd
Name | Value |
---|---|
AWS_ACCESS_KEY_ID | prd-hogehoge |
AWS_SECRET_ACCESS_KEY | prd-piyopiyo |
config.ymlでは以下の様に記述します。
anchors:
- &anchor-deploy
steps:
- deploy:
name: deploy
command: |
echo 'hello deploy'
jobs:
deploy-dev:
docker:
- image: circleci/python:3.6.1
<<: *anchor-deploy
deploy-prd:
docker:
- image: circleci/python:3.6.1
<<: *anchor-deploy
workflows:
version: 2
workflow1:
jobs:
- deploy-dev:
context: aws-dev
filters:
branches:
only: /develop/
- deploy-prd:
context: aws-prd
filters:
branches:
only: /master/
このように記述すると、同じdeployスクリプトをAWSのアカウントだけ変更して実行できます。スクリプト自体が環境ごとに異なってしまうと検証が大変なので、できるだけ設定の変更程度に抑えたいですが、この方法だとそれが実現できます。
この方法の場合だと、ステージング環境が増えた際にも修正は少なくて済みます
最近、弊社のyamlファイルがかなり大きくなってきたので、yamlファイル自体をテンプレートエンジンから作っていたりします。テンプレートエンジンを使っていると環境が増えた時の対応も少なく、安心できます。
また、実行中のjobをみて、ちゃんと想定どおりのアカウントにデプロイしているか確認できます。これもまた安心機能です。