担当しているプロジェクトがテストの実行もデプロイも手動だったので、
テストとデプロイの自動化に挑戦してみました。
バージョン管理はGitHub、サーバーはEC2を使っていることもあり、
今回のケースでは無料で実現できるCircleCI
とAWS CodeDeploy
を使います。
こちらの記事に沿う形で行いました。
CircleCIとAWS(CodeDeploy/S3)で作るCI環境
構築したいこと
- 特定ブランチにpushすると、CircleCIでテストされ、OKなら指定のEC2インスタンスにデプロイする
- cronはgitで管理し、デプロイ毎にcronを更新する
- デプロイ毎に
pip install requirements.txt
など依存ライブラリのインストールを行う
0. 事前準備
- aws account作成
- GitHub account作成
-
GitHub にデプロイしたいのリポジトリを作成(今回は
codedeploy-test
とする)
1. AWS IAM 設定
1.1 IAM Policy 作成
- 以下4つのIAM Policyを作成する。
- 今回は
s3
のtest-codedeploy-bucket
というbucketのtest/
下にrevision(ソースコード)を置くため、そこにアクセスできるようにする。権限は必要最小限にしたほうが良い。
EC2用S3_Policy(※1)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:Get*",
"s3:List*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::test-codedeploy-bucket/test",
"arn:aws:s3:::test-codedeploy-bucket/test/*"
]
}
]
}
CodeDeploy用S3_Policy(※2)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:Get*",
"s3:List*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::test-codedeploy-bucket/test",
"arn:aws:s3:::test-codedeploy-bucket/test/*"
]
}
]
}
CircleCI用S3_Policy(※3)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::test-codedeploy-bucket/test",
"arn:aws:s3:::test-codedeploy-bucket/test/*"
]
}
]
}
CircleCI用CodeDeploy_Policy(※4)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codedeploy:RegisterApplicationRevision",
"codedeploy:GetApplicationRevision"
],
"Resource": [
"arn:aws:codedeploy:ap-northeast-1:{aws account id}:application:test-app"
]
},
{
"Effect": "Allow",
"Action": [
"codedeploy:CreateDeployment",
"codedeploy:GetDeployment"
],
"Resource": [
"arn:aws:codedeploy:ap-northeast-1:{aws account id}:deploymentgroup:test-app/*"
]
},
{
"Effect": "Allow",
"Action": [
"codedeploy:GetDeploymentConfig"
],
"Resource": [
"arn:aws:codedeploy:ap-northeast-1:{aws account id}:deploymentconfig:CodeDeployDefault.OneAtATime",
"arn:aws:codedeploy:ap-northeast-1:{aws account id}:deploymentconfig:CodeDeployDefault.HalfAtATime",
"arn:aws:codedeploy:ap-northeast-1:{aws account id}:deploymentconfig:CodeDeployDefault.AllAtOnce"
]
}
]
}
1.2 IAM Role作成
以下2つのIAM Roleを作成する。これも権限は最小限にしたほうがよい。
- InstanceProfile(※8)
- ポリシー
- EC2用S3_Policy(※1)
- 信頼関係
- ポリシー
InstanceProfile用信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- ServiceRole(※9)
- ポリシー
- CodeDeploy用S3_Policy(※2)
- AWSCodeDeployRole
- AmazonEC2FullAccess
- 信頼関係
- ポリシー
ServiceRole用信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "codedeploy.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
1.4 CircleCI用IAM User作成
- circleci_user
- ポリシー
- CircleCI用S3_Policy(※3)
- CircleCI用CodeDeploy_Policy(※4)
- アクセスキー(※5)を作成して覚えておく
- ポリシー
2. AWS S3 bucket作成
- bucketの作成
- 今回は
test-codedeploy-bucket
というbucket名にした。 - region: ap-northeast-1(Tokyo)
- 今回は
3. EC2 instance作成
- 今回は t2-micro/AmazonLinux で作成
- IAM Roleに 1.2で作成したRole
InstanceProfile(※8)
を使用 - key pair作成(※6)
- ElasticIP付与
- Tagsでインスタンス名つける (今回は
test-server
)
4. CodeDeploy agentのインストール
-
鍵(※6)
を使ってSSHログインし、code deploy agentをインストールする。
test-server(EC2)
$ sudo yum update
$ cd ~
$ aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
$ chmod +x ./install
$ sudo ./install auto
5. CodeDeploy Application作成
- Application Name:
test-app
※7 - Deployment Group Name:
test-deploy-group
※7 - Add Instances:
test-server
3.で設定したインスタンス名 - Deployment Config:
CodeDeployDefault.OneAtATime
- Service Role:
ServiceRole(※9)
6. CircleCIの設定
- Add ProjectsでGitHubのリポジトリを追加
- Settings >> {user name} >> codedeploy-test
- Permissions >> AWS Permissions でアクセスキーとシークレットキー(※5)をセット(いらない?)
- Continuous Deployment >> AWS CodeDeploy
- Step 1: アクセスキーとシークレットキー(※5)をセット
- Step 2: circle.ymlで記述するのでスキップ
7. CircleCIとCodeDeployの設定ファイルを作成する
- GitHubに作成したサンプルリポジトリを記述します。
ディレクトリ構成
codedeploy-testリポジトリのディレクトリ構成
■ scripts
□ setup.sh
□ run.py
■ tests
□ __init__.py
□ test.py
□ README.md
□ appspec.yml
□ circle.yml
□ cron
appspec.yml
- デプロイ対象とデプロイ先を記述する。
- インストール後(S3からソースコードをpullした後)に実行させることを
AfterInstall
に記述する。- 今回は
scripts/setup.sh
でpip install
&cron更新
を行わせる
- 今回は
appspec.yml
version: 0.0
os: linux
files:
- source: / # デプロイ対象
destination: /app # デプロイ先のディレクトリパス
hooks:
AfterInstall:
- location: scripts/setup.sh
circle.yml
- CI環境でテストする内容を
test
に記述する -
CodeDeploy
によるデプロイ内容をdeployment
に記述する
circle.yml
test:
override:
- python -m unittest -v tests.test
deployment:
master:
branch: master
codedeploy:
test-app: #※7
deployment_group: test-deploy-group #※7
application_root: /
region: ap-northeast-1
revision_location:
revision_type: S3
s3_location:
bucket: test-code-deploy-bucket
key_pattern: test/master/test-app-{BRANCH}-{SHORT_COMMIT}
staging:
branch: staging
codedeploy:
test-app:
deployment_group: test-deploy-group
application_root: /
region: ap-northeast-1
revision_location:
revision_type: S3
s3_location:
bucket: test-codedeploy-bucket
key_pattern: test/staging/test-app-{BRANCH}-{SHORT_COMMIT}
インストール後に実行する内容
- 依存ライブラリのinstallとcronの登録・更新を行うscriptを作成する
setup.sh
#!/bin/bash
CURRENT_DIR=`dirname $0`
sudo pip install -r ${CURRENT_DIR}/../requirements.txt
sudo cp ${CURRENT_DIR}/../cron /etc/cron.d/test-cron
- 今回は
cron
が登録できたか確認するため、run.py
を実行させる
cron
* * * * * root /tmp/scripts/run.py >> /tmp/cron.log >2&1
実行結果
GitHub master/staging branchへのcommitによってCircleCIによるテストが行われ、
失敗すればデプロイされず、成功なら自動的にデプロイする仕組みを構築できました。
参考文献
- AWS CodeDeployのドキュメント
- circle ciのドキュメント
- 本記事がベースとしたQiitaの記事