AWS Elastic Beanstalkを使ったBlue-Green Deployment
今回は、Blue-Green Deployment(ブルーグリーンデプロイメント)を、AWS Elastic Beanstalkを使ってやってみました。
Blue-Green Deployment
とは
同等の環境を2つ用意して、リリース時にリクエスト先を切り替えることで、ダウンタイムをほぼゼロすることができるデプロイ方法です。
上記の画像では、左側の Blue environment
へアクセスが行くようになっている状態です。
これをリリース時に、新しいバージョンのアプリケーションを配備済みの Green environment
へ切り替える形でデプロイを行います。
【参考】
メリット
Blue-Green Deployment のメリットとしては、下記のものが考えられます。
- リリース時のダウンタイムがほぼゼロ
- 本番公開する前に稼働中の環境と同等の環境でしっかりと事前検証できる
- 万が一不具合などが発覚しても切り戻しが簡単
デメリット
一方でデメリットとしては、下記のようなものがあります。
- 同じような環境を2つ作らないといけないため、手間がかかる
- 同じような環境を2つ作るため、コストがかかる
Elastic Beanstalk でやってみる
「同じような環境を2つ作らないといけないため、手間がかかる」として、デメリットの中で記載しましたが、Elastic Beanstalkを使うとAWSインフラをあまり意識しなくてもサクッと作れてしまうので、インフラの構築が苦手、という方にとっては、重宝するかと思います。
前提
今回はAWS公式ページのDocker用のサンプルアプリを使用しました。
Elastic Beanstalk CLI インストール
Elastic Beanstalk CLIのインストールは、こちらのページやこちらのぺーじを参考に行います。
個人的には環境に依存しない形で使えるのが好きなので、 Dockerfile
と docker-compose.yml
を用意して、Docker環境にインストールを行いました。
以下は、Dockerを使う際のインストール方法ですが、お好みの方法でインストールしてみてください。
【Dockerfile
】
FROM alpine:latest
RUN apk add --no-cache make g++ libffi-dev openssl-dev python3 py3-pip python3-dev git &&
pip3 install --upgrade --ignore-installed awsebcli
VOLUME /app
WORKDIR /app
ENTRYPOINT ["eb"]
【docker-compose.yml
】
version: "3.8"
services:
eb:
build:
context: ./
dockerfile: ./Dockerfile
volumes:
- .:/app
env_file:
- .env
.env
ファイルに、 AWS_ACCESS_KEY_ID
や AWS_SECRET_ACCESS_KEY
を下記のように書いておき、
AWS_ACCESS_KEY_ID=AKIAJOUAASEXAMPLE
AWS_SECRET_ACCESS_KEY=5ZRIrtTM4ciIAvd4EXAMPLEDtm+PiPSzpoK
docker-compose build
コマンドでDockerのビルドをします。
$ docker-compose build
eb
コマンドを実行する際には、 docker-compose run eb xxx
で実行できます。
【eb init
を実行したい際の例】
$ docker-compose run eb init
Elastic Beanstalk 初期設定
まず始めに eb init
を実行して、Elastic Beanstalkの初期設定を行います。
リージョンを聞かれるので、東京リージョンである 9
を入力します。
$ eb init
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
18) eu-north-1 : EU (Stockholm)
19) eu-south-1 : EU (Milano)
20) ap-east-1 : Asia Pacific (Hong Kong)
21) me-south-1 : Middle East (Bahrain)
22) af-south-1 : Africa (Cape Town)
(default is 3): 9
リージョンを選択すると、AWSアクセスキーとシークレットキーを聞かれます。
適切な権限を持ったIAMユーザーを作成して、アクセスキーとシークレットキーを入力してください。
※ 環境変数に設定済みの場合は、聞かれません。
You have not yet set up your credentials or your credentials are incorrect.
You must provide your credentials.
(aws-access-id): AKIAJOUAASEXAMPLE
(aws-secret-key): 5ZRIrtTM4ciIAvd4EXAMPLEDtm+PiPSzpoK
次に、利用するアプリケーションを聞かれます。
何もアプリケーションが無い場合は、 [ Create new Application ]
選択後、アプリケーション名を聞かれるので、入力します。
今回は、事前に作成済みの app
を利用しました。
Select an application to use
1) app
2) uchiko-test-app
3) lightsail_to_eb
4) Go-Car-API
5) [ Create new Application ]
(default is 1):
「Dockerを利用しているようですが、正しいですか?」と問われるので、 y
と入力します。
デフォルト設定の Amazon Linux 2
の 1
を選択しました。
It appears you are using Docker. Is this correct?
(Y/n): y
Select a platform branch.
1) Docker running on 64bit Amazon Linux 2
2) Multi-container Docker running on 64bit Amazon Linux
3) Docker running on 64bit Amazon Linux
(default is 1):
CodeCommit
を利用するか?と聞かれますが、今回は利用しないので n
を入力します。
Do you wish to continue with CodeCommit? (Y/n): n
続いて SSH
の設定について聞かれます。
今回は SSH
をする必要は無いので n
を入力します。
Do you want to set up SSH for your instances?
(Y/n): n
以上で、初期設定は完了です。.elasticbeanstalk/
ディレクトリ配下に config.yml
というファイルができます。
これまで入力してきた内容が入っているのが確認できます。
branch-defaults:
master:
environment: null
global:
application_name: app
branch: null
default_ec2_keyname: null
default_platform: Docker running on 64bit Amazon Linux 2
default_region: ap-northeast-1
include_git_submodules: true
instance_profile: null
platform_name: null
platform_version: null
profile: null
repository: null
sc: null
workspace_type: Application
Blue環境作成
次に、 eb create <環境名>
を実行し、 Blue環境を作成します。
環境名は、 envblue
としました。
分かりやすいように、サンプルアプリケーションの application.py
の74行目の background-color
を blue
修正しておきます。
.textColumn {
position: absolute;
top: 0px;
right: 50%;
bottom: 0px;
left: 0px;
text-align: right;
padding-top: 11em;
background-color: blue; //ここを blue に変更
}
コマンド実行して、環境を作ります。
$ eb create envblue
Creating application version archive "app-f56a-200820_045534".
Uploading app/app-f56a-200820_045534.zip to S3. This may take a while.
Upload Complete.
Environment details for: envblue
Application name: app
Region: ap-northeast-1
Deployed Version: app-f56a-200820_045534
Environment ID: e-jywrptwt6c
Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Docker running on 64bit Amazon Linux 2/3.1.0
Tier: WebServer-Standard-1.0
CNAME: UNKNOWN
Updated: 2020-08-20 04:55:37.419000+00:00
Printing Status:
2020-08-20 04:55:36 INFO createEnvironment is starting.
2020-08-20 04:55:37 INFO Using elasticbeanstalk-ap-northeast-1-111111111111 as Amazon S3 storage bucket for environment data.
2020-08-20 04:55:59 INFO Created target group named: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/awseb-AWSEB-AQC6223EWOQ9/0b8483a5d06ccf39
2020-08-20 04:55:59 INFO Created security group named: sg-0929db6bd29b38a61
2020-08-20 04:56:15 INFO Created security group named: awseb-e-jywrptwt6c-stack-AWSEBSecurityGroup-S4Y5PPX8II3I
2020-08-20 04:56:15 INFO Created Auto Scaling launch configuration named: awseb-e-jywrptwt6c-stack-AWSEBAutoScalingLaunchConfiguration-53FXXR9QFA81
2020-08-20 04:57:48 INFO Created Auto Scaling group named: awseb-e-jywrptwt6c-stack-AWSEBAutoScalingGroup-1CZ9R8SWCCMPT
2020-08-20 04:57:48 INFO Waiting for EC2 instances to launch. This may take a few minutes.
2020-08-20 04:57:48 INFO Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:111111111111:scalingPolicy:2a4a7352-11d2-4104-8edd-46c3e1e5f112:autoScalingGroupName/awseb-e-jywrptwt6c-stack-AWSEBAutoScalingGroup-1CZ9R8SWCCMPT:policyName/awseb-e-jywrptwt6c-stack-AWSEBAutoScalingScaleDownPolicy-1XG7ZR7RYCHLD
2020-08-20 04:57:48 INFO Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:111111111111:scalingPolicy:1e833cea-2056-43ed-ad85-81b4d736e173:autoScalingGroupName/awseb-e-jywrptwt6c-stack-AWSEBAutoScalingGroup-1CZ9R8SWCCMPT:policyName/awseb-e-jywrptwt6c-stack-AWSEBAutoScalingScaleUpPolicy-T2H16EIIX9CY
2020-08-20 04:57:48 INFO Created CloudWatch alarm named: awseb-e-jywrptwt6c-stack-AWSEBCloudwatchAlarmLow-OOAK208S5O85
2020-08-20 04:57:48 INFO Created CloudWatch alarm named: awseb-e-jywrptwt6c-stack-AWSEBCloudwatchAlarmHigh-1JYHQZHWCC8CG
2020-08-20 04:58:07 INFO Created load balancer named: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:loadbalancer/app/awseb-AWSEB-K7ARO4RZPPFS/132af7e0b271b51e
2020-08-20 04:58:07 INFO Created Load Balancer listener named: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:listener/app/awseb-AWSEB-K7ARO4RZPPFS/132af7e0b271b51e/179271fd42db6b0b
2020-08-20 04:59:04 INFO Instance deployment completed successfully.
2020-08-20 04:59:20 INFO Application available at envblue.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com.
2020-08-20 04:59:21 INFO Successfully launched environment: envblue
実行ログを見ると、セキュリティーグループの作成や、オートスケーリンググループの作成、EC2インスタンスの作成、CloudWatch Alarmの作成、ロードバランサーの作成などが行われていることが確認できます。
コマンド一発で、いい感じに作成してくれるので、AWSインフラの知識がない人でも楽ちんです。
作成完了後に、ステータスを確認します。
$ eb status envblue
Environment details for: envblue
Application name: app
Region: ap-northeast-1
Deployed Version: app-f56a-200820_045534
Environment ID: e-jywrptwt6c
Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Docker running on 64bit Amazon Linux 2/3.1.0
Tier: WebServer-Standard-1.0
CNAME: envblue.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
Updated: 2020-08-20 04:59:21.579000+00:00
Status: Ready
Health: Green
CNAMEの項目で出力されている http://envblue.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
にブラウザからアクセスしてみると、
サンプルアプリケーションの画面が表示されることが確認できます。
Green環境作成
次に、同じようにGreen環境を作成していきます。
名前は envgreen
としました。
分かりやすいように、先ほどと同様にサンプルアプリケーションの application.py
の74行目の background-color
を green
修正しておきます。
.textColumn {
position: absolute;
top: 0px;
right: 50%;
bottom: 0px;
left: 0px;
text-align: right;
padding-top: 11em;
background-color: green; //ここを green に変更
}
コマンド実行して、環境を作ります。
$ eb create envgreen
Creating application version archive "app-f56a-200820_050403".
Uploading app/app-f56a-200820_050403.zip to S3. This may take a while.
Upload Complete.
Environment details for: envgreen
Application name: app
Region: ap-northeast-1
Deployed Version: app-f56a-200820_050403
Environment ID: e-u6j7ubnf56
Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Docker running on 64bit Amazon Linux 2/3.1.0
Tier: WebServer-Standard-1.0
CNAME: UNKNOWN
Updated: 2020-08-20 05:04:07.009000+00:00
Printing Status:
2020-08-20 05:04:05 INFO createEnvironment is starting.
2020-08-20 05:04:07 INFO Using elasticbeanstalk-ap-northeast-1-111111111111 as Amazon S3 storage bucket for environment data.
2020-08-20 05:04:28 INFO Created target group named: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/awseb-AWSEB-19G3AMQDOPOMM/63866529b59c2db4
2020-08-20 05:04:29 INFO Created security group named: sg-0a29b375fef10adce
2020-08-20 05:04:44 INFO Created security group named: awseb-e-u6j7ubnf56-stack-AWSEBSecurityGroup-1MR72ZIN6S1G6
2020-08-20 05:04:44 INFO Created Auto Scaling launch configuration named: awseb-e-u6j7ubnf56-stack-AWSEBAutoScalingLaunchConfiguration-C6CT6HF14TH5
2020-08-20 05:05:46 INFO Created Auto Scaling group named: awseb-e-u6j7ubnf56-stack-AWSEBAutoScalingGroup-94SRCJPFN5F9
2020-08-20 05:05:46 INFO Waiting for EC2 instances to launch. This may take a few minutes.
2020-08-20 05:05:46 INFO Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:111111111111:scalingPolicy:f2d0c1fc-e96d-41d6-a20c-9e791c2b7166:autoScalingGroupName/awseb-e-u6j7ubnf56-stack-AWSEBAutoScalingGroup-94SRCJPFN5F9:policyName/awseb-e-u6j7ubnf56-stack-AWSEBAutoScalingScaleUpPolicy-1WWHVFHUA9ATS
2020-08-20 05:05:46 INFO Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:111111111111:scalingPolicy:49c8098c-495d-455f-bf0a-63472593f645:autoScalingGroupName/awseb-e-u6j7ubnf56-stack-AWSEBAutoScalingGroup-94SRCJPFN5F9:policyName/awseb-e-u6j7ubnf56-stack-AWSEBAutoScalingScaleDownPolicy-4AUHRB0KFKGU
2020-08-20 05:06:02 INFO Created CloudWatch alarm named: awseb-e-u6j7ubnf56-stack-AWSEBCloudwatchAlarmHigh-149KK1O2VXJXG
2020-08-20 05:06:02 INFO Created CloudWatch alarm named: awseb-e-u6j7ubnf56-stack-AWSEBCloudwatchAlarmLow-GKTVA8SZ66O6
2020-08-20 05:06:37 INFO Created load balancer named: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:loadbalancer/app/awseb-AWSEB-9QSDBBY8XY1A/10604c0117039c7e
2020-08-20 05:06:52 INFO Created Load Balancer listener named: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:listener/app/awseb-AWSEB-9QSDBBY8XY1A/10604c0117039c7e/02dde44d0da6f440
2020-08-20 05:07:35 INFO Instance deployment completed successfully.
2020-08-20 05:07:41 INFO Application available at envgreen.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com.
2020-08-20 05:07:41 INFO Successfully launched environment: envgreen
環境作成後に、ステータスを確認します。
$ eb status envgreen
Environment details for: envgreen
Application name: app
Region: ap-northeast-1
Deployed Version: app-f56a-200820_050403
Environment ID: e-u6j7ubnf56
Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Docker running on 64bit Amazon Linux 2/3.1.0
Tier: WebServer-Standard-1.0
CNAME: envgreen.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
Updated: 2020-08-20 05:07:41.383000+00:00
Status: Ready
Health: Green
こちらもCNAMEの項目で表示されている http://envgreen.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
にブラウザからアクセスしてみると、
背景が緑になったサンプルアプリケーションが確認できます。
Route53にレコードを追加する
サービスURLとして分かりやすいように Route53
にレコードを追加してみます。
今回は、 ebapp.test.mmmcorp.co.jp
にしました。
ALIAS として、先程作成したBlue環境のCNAME envblue.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
を設定します。
http://ebapp.test.mmmcorp.co.jp
にアクセスしてみると
想定通りBlue環境へアクセスが行っていることがわかります。
CNAME を切り替える
この状態で、 eb swap
コマンドで2つの環境のCNAMEを入れ替えます。
まずは、ステータス確認から。
Blue環境のCNAMEは、下記のとおりになっています。
$ eb status envblue
Environment details for: envblue
(略)
CNAME: envblue.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
(略)
これを eb swap
で切り替えます。
$ eb swap --destination_name envgreen
2020-08-20 05:48:33 INFO swapEnvironmentCNAMEs is starting.
2020-08-20 05:48:34 INFO Swapping CNAMEs for environments 'envblue' and 'envgreen'.
2020-08-20 05:48:39 INFO 'envgreen.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com' now points to 'awseb-AWSEB-K7ARO4RZPPFS-554919051.ap-northeast-1.elb.amazonaws.com'.
2020-08-20 05:48:39 INFO Completed swapping CNAMEs for environments 'envblue' and 'envgreen'.
コマンド実行が完了した後に、ステータスを確認すると、
$ eb status envblue
Environment details for: envblue
(略)
CNAME: envgreen.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
(略)
Blue環境のCNAMEが Green環境のCNAMEになっていることが確認できます。
さらにその状態で、Green環境のステータスを確認すると、
$ eb status envgreen
Environment details for: envgreen
(略)
CNAME: envblue.eba-at7th2ac.ap-northeast-1.elasticbeanstalk.com
(略)
CNAMEがBlue環境のものに入れ替わっており、サービスURLの http://ebapp.test.mmmcorp.co.jp/
にアクセスすると、
Green環境のアプリケーションが表示されていることが確認できました。
リリース後に何か不具合が発覚して、アプリケーションを切り戻したい、という場合は同じように eb swap
コマンドでCNAMEを入れ替えるだけで実現できます。
まとめ
以上、今回はBlue-Green DeploymentをElastic Beanstalkでやってみました。
弊社では、マイクロサービスや複雑なカスタマイズが要件上発生する(見込まれる)システムの開発を請け負うことが多く、コードベースの管理コスト・複雑性の観点からElastic Beanstalkをあまり利用しません。
とはいえ、比較的シンプルなAWSインフラで問題ない場合や、AWSインフラをあまり考えたくない場合、AWSインフラの複雑な管理をしたくない場合には、Elastic Beanstalkを採用することで、簡単にBlue-Green Deploymentが行えるので一考の余地ありだとは思います。
参考
- AWS のブルー/グリーンデプロイ
- Upgrades Without Tears Part 1: An Introduction to Blue/Green Deployment on AWS | AWS Startups Blog
- EB CLI command reference - AWS Elastic Beanstalk
- 「Blue-Green Deployment」とは何か、マーチン・ファウラー氏の解説 - Publickey
- AWSでブルーグリーンデプロイを実践してみた | キャスレーコンサルティング株式会社
- AWS Elastic BeanstalkでBlue-Green Deployment | SIOS Tech. Lab