現在、AWSではELBとオートスケールでのBlueGreenDeploymentが非常に簡単にできるようになりました。
Auto Scaling環境でのBlue-Green Deploymentの切替がAWS ELBでできるようになりました
上記に記載されているようにオートスケールに紐づくELBを変えれるようになったことでCLIやAPIを使って簡単にBlueGreenDeploymentを行う事ができるようになっています。
話は変わって、最近ElasticBeanstalkを使ってみようという話があり、ElasticBeanstalkでBlueGreenDeploymentを行う方法を調べた所、CNAME Swapという機能があり、この機能を使う事でBlueGreenDeploymentができそうでした。(上記のELBの向き先を変えるのではなく、CNAMEを変える方式)
上記を実際に確認してみたのでその時のメモ。
やること
- ElasticBeanstalkを操作するebコマンドの設定をしたEC2を起動(ローカル環境でも良いと思います)
- Blue環境(本番環境)にデプロイ
- Green環境(テスト環境)にデプロイ
- CNAME Swapを使ってGreen環境をBlue環境のURLでも確認できるようにする
準備
新規に作成したAmazonLinuxのEC2上でebコマンドを使ってやってみます。
IAMの設定を実施後、EC2を起動します。
ElasticBeanstalkで利用するIAMの詳細については以下に記載があります。
IAMロールの作成(ebを操作するEC2用)
EC2からebコマンドを実行するのでその権限を持ったIAMロールを作成します。
- Roles->Create New Role
- 任意のロール名を設定
- Select Role TypedではAmazonEC2を選択
- Attach PolicyではAWSElasticBeanstalkFullAccessを設定
- Create role
上記にはIAMロールを作成する権限はないので次の項で利用するロールをあらかじめ作成しておきます。
ElasticBeanstalkで利用されるサービスロールとIAMロールの作成
ElasticBeanstalkで利用されるサービスロールとIAMロールを予め作成します。
IAMの画面から頑張ってやる方法もあると思うのですが、マネージメントコンソールからElasticBenastalkを作成する途中で作成できる機能を利用します。
マネージメントコンソールでElasticBeanstalkの画面を表示します。
まだ一つもElasticBeanstalkでアプリを作成していない場合、上記のような画面になっているので画面右上の「Create Appliction」を選択して任意のアプリケーションを作成します。
- Create New Application
- 任意のアプリケーション名を入力
- Create web serverを選択
- 以降、Permissionという下記画面までは適当に入力(どうせ作成をキャンセルするので)
上記でまだInstanceProfileとService roleが作成されていない場合には新規作成する旨が記載されているので作成します。
作成が終われれば、CancelでElasticBeanstalkの操作をキャンセルします。
上記操作ではアプリケーションが削除がされていないのでAction->Delete Applicationでアプリも削除しておきます。
EC2の起動
ebを操作できるEC2を起動します。
セットアップはUserDataでやってしまいます。
- OS->Amazon Linux AMI 2015.03.1
- IAM Role->「IAMロールの作成(ebを操作するEC2用)」で作成したIAMロールを設定
- UserData->以下の通り
#!/bin/bash
EC2_HOME="/home/ec2-user/"
# install packages
yum install lynx git -y
# set AWS SDK and CLI configuration
mkdir $EC2_HOME.aws
cat > $EC2_HOME.aws/config << EOS
[default]
output = json
region = ap-northeast-1
EOS
chown -R ec2-user:ec2-user $EC2_HOME.aws
# install eb command
pip install --upgrade pip
/usr/local/bin/pip install awsebcli
# completion eb command(for Bash)
echo "source /usr/local/bin/eb_completion.bash" >> $EC2_HOME.bashrc
Blue環境にデプロイする
ebコマンドを使ってElasticBeanstalkでデプロイしてみる
以前書いた以下の項を実施します。
- Webアプリの作成
- アプリケーションの設定
ざっくり記載。詳細は記事を参照。
$mkdir -p git/elastic-beanstalk
$cd git/elastic-beanstalk
$git init .
$vi index.php
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>Hello World!</p>'; ?>
</body>
</html>
$git add index.php
$git commit -m "initial check-in"
$eb init
上記でデプロイするアプリが作成できました。
ElasticBenstalkでは一つのアプリケーションに複数の環境を紐づけることができます。(検証、本番など)
今回は上記の環境という概念でBlueとGreenを作成して切り替えを行います。
eb create
コマンドを使ってBlue環境の作成とデプロイを行います。デプロイ時にELBやインスタンスの起動など複数のリソースを利用するため、利用できるまで少し時間がかかります。
$eb create
Enter Environment Name
(default is elastic-beanstalk-dev): elastic-beanstalk-blue
Enter DNS CNAME prefix
(default is elastic-beanstalk-blue):
...以降設定のログ
INFO: Successfully launched environment: elastic-beanstalk-blue
完了したらeb openコマンドでアクセスして確認してみます。
$eb open
上記でHelloWorld!という表示が確認できればOKです。
実際にアクセスする際のURLも確認できます。
$eb status
Environment details for: elastic-beanstalk-blue
Application name: elastic-beanstalk
Region: ap-northeast-1
Deployed Version: bc92
Environment ID: e-87itv3u3d3
Platform: 64bit Amazon Linux 2015.03 v2.0.1 running PHP 5.6
Tier: WebServer-Standard
CNAME: elastic-beanstalk-blue.elasticbeanstalk.com
Updated: 2015-09-19 06:04:31.352000+00:00
Status: Ready
Health: Green
上記のCNAMEとなっている部分でのアクセスも可能です。
Green環境にデプロイする
次にGreen環境を作成し、こちらに新しいアプリをデプロイします。
まず、Green環境の構築およびデプロイを行います。
$eb create elastic-beanstalk-green
これでBlue環境と同じ環境となっているGreen環境の構築とアプリのデプロイを行いました。
次にCLIで現在設定されている操作対象の環境を確認します。
$ eb list
* elastic-beanstalk-blue
elastic-beanstalk-green
現在はBlue環境を操作する形になっているのですが、今後はGreen環境で操作をメインにしたいので設定を変更します。
$eb use elastic-beanstalk-green
$eb list
elastic-beanstalk-blue
* elastic-beanstalk-green
設定が変わったのでGreen環境の状態を確認します。
$eb open
現在はBlue環境と同じ情報が表示されるかと思います。
なお、デフォルトの環境を変えなくても以下のよう引数に環境を指定することでも指定環境の操作が可能です。
$eb open elastic-beanstalk-blue
Green環境に最新のアプリをデプロイする
ソースコードを変更して最新状態にし、デプロイします。
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>Hello World!!!!!<</p>'; ?>
</body>
</html>
$git add .
$git commit -m "hoge fuga"
$eb deploy
eb deploy
Creating application version archive "2a32".
Uploading elastic-beanstalk/2a32.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.
INFO: Deploying new version to instance(s).
INFO: New application version was deployed to running EC2 instances.
INFO: Environment update completed successfully.
デプロイ後、eb open
でHello World!!!!!と表示されればOKです。
今回の例ではGreen環境はテスト環境なので、開発の都度deployし、開発者のみアクセスしてテストを行うような開発スタイルが可能です。その間もBlue環境では本番環境が問題なく動作しています。
CNAME SwapでBlue環境のURLでGreen環境にアクセスする
Green環境のアプリのテストも終わったので、本番環境(Blue環境)へ投入するぞ!というタイミングでCNAME Swapを使ってBlue環境へのアクセスURLでGreen環境へ向くようにします。
まず、Blue環境の状態を再度、ブラウザなどで確認します。(アクセスURLはeb statusコマンドのCNAME)問題なければ「Hello World!」と表示されるはずです。今回の例ではそれぞれのCNAMEは以下のようになっているとします。
- Blue->http://elastic-beanstalk-blue.elasticbeanstalk.com/
- Green->http://elastic-beanstalk-green-kqzyhtmmze.elasticbeanstalk.com/
ではeb swap
コマンドを使ってBlueとGreenのCNAMEを変更します。
$ eb list
elastic-beanstalk-blue
* elastic-beanstalk-green
$eb swap elastic-beanstalk-blue
ERROR: InvalidShapeReferenceError :: Invalid model, missing shape reference: OrderedDict([(u'type', u'structure'), (u'members', OrderedDict([(u'User', OrderedDict([(u'shape', u'Double')])), (u'Nice', OrderedDict([(u'shape', u'Double')])), (u'System', OrderedDict([(u'shape', u'Double')])), (u'Idle', OrderedDict([(u'shape', u'Double')])), (u'IOWait', OrderedDict([(u'shape', u'Double')])), (u'IRQ', OrderedDict([(u'shape', u'Double')])), (u'SoftIRQ', OrderedDict([(u'shape', u'Double')]))]))])
まさかの内部エラー。。。ぐぬぬぬ・・・他の方も同様の事象が発生しているようなのでebの問題なのかもしれません。。
AWS CLIでもできるようなのでそちらでやってみます。
$aws elasticbeanstalk swap-environment-cnames --source-environment-name elastic-beanstalk-green --destination-environment-name elastic-beanstalk-blue
これで切り替わったはずなので確認します。
$eb status
Environment details for: elastic-beanstalk-green
Application name: elastic-beanstalk
Region: ap-northeast-1
Deployed Version: 2a32
Environment ID: e-z5u9efeudu
Platform: 64bit Amazon Linux 2015.03 v2.0.1 running PHP 5.6
Tier: WebServer-Standard
CNAME: elastic-beanstalk-blue.elasticbeanstalk.com
Updated: 2015-09-19 08:39:53.378000+00:00
Status: Ready
Health: Green
$eb status elastic-beanstalk-blue
Environment details for: elastic-beanstalk-blue
Application name: elastic-beanstalk
Region: ap-northeast-1
Deployed Version: bc92
Environment ID: e-87itv3u3d3
Platform: 64bit Amazon Linux 2015.03 v2.0.1 running PHP 5.6
Tier: WebServer-Standard
CNAME: elastic-beanstalk-green-kqzyhtmmze.elasticbeanstalk.com
Updated: 2015-09-19 08:39:53.378000+00:00
Status: Ready
Health: Green
Green環境とBlue環境のCNAMEが変わっているのが確認できます。
また、Blue環境(本番)のURL
にアクセスすることで「Hello World!!!!!!」という表示がされます。なお、内部的にRoute53のCNAMEの付け替えとなっているようで、切り替え後すぐに表示が変わらない場合もありますが、少し時間が経てば表示ができるはずです。
最新環境で動作が問題ないよであればBlue環境は破棄し、新規に新環境を作ってテスト、リリース時にCNAME Swapにより切り替えとすれば最初に割り当てたURLでの運用が可能です。(実際はRoute53でドメインを割り当てると思いますが。。)
また、仮に最新版で動作に不具合がある場合もCNAME Swapを再度行うことで旧環境に戻すことも簡単にでき、安心に運用ができます。
掃除
以下で今回作成したそれぞれの環境とアプリケーションを削除します。
$eb terminate elastic-beanstalk-blue
$eb terminate elastic-beanstalk-green
# 上記が消えてからアプリケーションは削除
$aws elasticbeanstalk delete-application --application-name elastic-beanstalk
最後に
- CLIによる操作(ebコマンドとAWS CLI)のみでアプリのデプロイが簡単にできるのは面白い
- CNAME Swapで簡単にBlueGreenDeploymentができる
- DockerやECSもElasticBeanstalkはサポートしているのでDockerのBlueGreenDeploymentも簡単にできる?
- 今ならELBの付け替えができるのでElasticBeanstalkでも簡単にやれる仕組みが欲しい(やろうと思えばできるような気もしますが。。。)