Elastic Beanstalkを試してみる
DVA試験(AWS Certified Developper - Associate)対策のため、Beanstalkをハンズオンしてみたので記録しておきました。
- Elastic Beanstalkを使って"Congratulations"してみる。
- Blue/Greenデプロイにより、サンプルプログラムの"Congratulations"を"Hello World"に変えてみる。
※相変わらず分かりにくい図で申し訳ないです。
Elastic Beanstalkは初めて使うため(AWS研修では使った経験あり)、AWS Management Console
から作成しました。
- アプリケーション名
- beanstalk_trial
- プラットフォーム
- Java
- プラットフォームのブランチ
- Corretto 17 running on 64bit Amazon Linux 2
- プラットフォームのバージョン
- 3.4.3
- アプリケーションコード
- サンプルアプリケーション
Amazon Correttoとは、Amazonによる無料の長期サポートが提供されている、Java SE標準と互換性があると認定されているOpen JDKディストリビューションのことです。
作成を開始すると、CloudFormationテンプレートによりスタックが作成されていきます。
次に、CloudFormation > スタック > awseb-e-e7d8kvxdpq-stack
を開き、イベントタブ
を開いたところ、以下のようなエラーが発生し、スタックのステータスはCREATE_FAILED
になっていました。この時、ElasticBeanstalk > 環境 > Beanstalktrial-env-2
の環境のヘルスは保留中
になっていました。
The following resource(s) failed to create: [AWSEBV2LoadBalancer, AWSEBAutoScalingGroup].
You must use a valid fully-formed launch template. No default subnet for availability zone: ‘ap-northeast-1c’. (Service: AmazonAutoScaling; Status Code: 400; Error Code: ValidationError; Request ID: 7d99081a-1554-487c-b265-38b01661aa2e; Proxy: null)
このエラーの原因は、デフォルトサブネットが存在しないことです。過去にデフォルトVPCを削除した時に、一緒に削除されたのだと思います。そして、現在はデフォルトVPCのみ作成されている状況です。本来、デフォルトVPCは以下のような構成になっているのが正しいようです。
そこで、以下の手順でデフォルトVPC、デフォルトサブネットを構成し直します。
- Elastic Beanstalkの環境を削除し、アプリケーションを終了する
- デフォルトVPCの記載を参考に、
AWS CloudShell
から以下のコマンドでデフォルトVPCとデフォルトサブネットを作成する1
Elastic Beanstalk > 環境
から、環境を選択し、右にあるアクションから環境の終了
を選択し、環境を終了します。これにより、アプリケーションの公開も停止されます。
AWS Cloud Shell
から以下のコマンドを実行します。実行しているコマンドの詳細は、AWS CLI Command Referenceを参照してください。
aws ec2 create-default-vpc
出力例は以下です。
An error occurred (DefaultVpcAlreadyExists) when calling the CreateDefaultVpc operation: A Default VPC already exists for this account in this region.
既にデフォルトVPCが存在すると言われます。そこで、デフォルトVPCのVpcId
を調べます。
aws ec2 describe-vpcs --filter Name=is-default,Values=true --query 'Vpcs[].[VpcId]' --output text
出力例は以下です。
vpc-0f48a5ddd72f1781f
今回は、既にデフォルトVPCが存在していました。その配下にあるサブネットがデフォルトサブネットか判断がつかなかった上、他で使っていなかったことから、デフォルトVPCにあるサブネットを削除しておきます。
for target_subnet in `aws ec2 describe-subnets --filters Name=vpc-id,Values=vpc-0f48a5ddd72f1781f --query 'Subnets[].[SubnetId]' --output text`
do
aws ec2 delete-subnet --subnet-id $target_subnet
done
以下のコマンドを実行し、出力結果が無いことを以てサブネットが削除されたことを確認します。
aws ec2 describe-subnets \
--filters Name=vpc-id,Values=vpc-0f48a5ddd72f1781f \
--query 'Subnets[].[SubnetId]' \
--output text
以下のコマンドで、各AZにデフォルトサブネットを作成します。
availabilityzones=(ap-northeast-1a ap-northeast-1c ap-northeast-1d)
for az in ${availabilityzones[@]}
do
aws ec2 create-default-subnet --availability-zone $az
done
unset availabilityzones
作成されたことを確認します。
aws ec2 describe-subnets \
--filters Name=vpc-id,Values=vpc-0f48a5ddd72f1781f \
--filters Name=state,Values=available \
--query 'Subnets[].[SubnetId,AvailabilityZone,CidrBlock]'
出力例は以下です。
|
|
ドキュメントによると、デフォルトサブネットのCIDRは172.31.0.0/20, 172.31.16.0/20, 172.31.32.0/20
の3つであるということなので、きちんと作成されたようです。
まず、デフォルトVPCにアタッチされているインターネットゲートウェイのInternetGatewayId
を調べます。
aws ec2 describe-internet-gateways \
--filter Name=attachment.vpc-id,Values=vpc-0f48a5ddd72f1781f \
--filter Name=attachment.state,Values=available \
--query 'InternetGateways[].[InternetGatewayId]' \
--output text
出力例は以下です。
igw-0adc27eae43d8714d
0.0.0.0/0
宛の通信が上記のInternetGatewayを通るように設定されているか、ルートテーブルを確認します。
aws ec2 describe-route-tables \
--filter Name=vpc-id,Values=vpc-0f48a5ddd72f1781f \
--filter Name=route.destination-cidr-block,Values=0.0.0.0/0 \
--filter Name=route.gateway-id,Values=igw-0adc27eae43d8714d \
--output text
出力例は以下です。
|
|
0.0.0.0/0
宛の通信がigw-0adc27eae43d8714d
を通るように設定されていることが確認できました。2
ここまでで、以下の構成が作成されたことが確認できました(以下図は再掲)。
再度、ElasticBeanstalkのアプリケーションを作成します。アプリケーションの作成に成功すると、Elastic Beanstalk > 環境
にURLが表示されるので、それにアクセスします。すると、以下のように"Congratulations"と表示されるはずです。
私の場合、以前にデフォルトVPCを作成した時に、プライベートサブネット用のルートテーブル、およびパブリックサブネット用のルートテーブルの2つを作っており、デフォルトのルートテーブルは「プライベートサブネット用のルートテーブル」でした。その結果、Beanstalkのアプリケーションを作成した際に、EC2インスタンスは「プライベートサブネット」に配置されており、それが原因でヘルスチェックに失敗する、必要な情報がELB側で取得できない等の問題が発生しました。解決するため、Beanstalkが作ったEC2インスタンスが配置されているサブネットのルートテーブルを「パブリックサブネット用のルートテーブル」に関連付けし直し、環境を再構築しました。
サクッと作っておきます。今回は、ap-northeast-1d
に配置しました。
Elastic Beanstalk resourcesにcorretto.zip
があるので、Cloud9のターミナルを使ってダウンロードし、展開しておきます。
wget https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/samples/corretto.zip
unzip corretto.zip -d sample/
続いて、sample/src/main/resources/index.html
を開き、以下のように編集します。
|
|
アップロードできるよう、cd sample; zip corretto-2.0.zip -r .
で圧縮しておきます。
現在動作している環境をクローンします。Elastic Beanstalk > 環境
を開き、ラジオボタンにチェックを入れ、アクションから環境のクローンを作成
を選択します。ひとまずはデフォルト設定のままクローンします。新しい環境の名前は「beanstalktrial-env-1」になりました。現時点で環境は2つあり、それぞれURLは以下の通りになっています。
- 1つ目(最初)のURL(環境名「Beanstalktrial-env」で、これをBlue環境とします)
- http://beanstalktrial-env.eba-js4ipinm.ap-northeast-1.elasticbeanstalk.com/
- 2つ目のURL(環境名「Beanstalktrial-env-1」で、これをGreen環境とします)
- http://beanstalktrial-env-1.ap-northeast-1.elasticbeanstalk.com/
1つ目、2つ目のURLにアクセスし、「Congratulations」が表示されていることを確認します。
先ほど作成したcorretto-2.0.zip
を、Green環境(Beanstalktrial-env-1)にアップロードし、デプロイします。Elastic Beanstalk > 環境 > beanstalktrial-env-1
を開き、アップロードとデプロイ
を選択します。ZIPファイルをアップロードし、デプロイが完了するのを待ちます。
デプロイが完了した後、先ほどの2つ目のURLにアクセスし、「Hello World」が表示されていることを確認します。1つ目のURLは引き続き「Congratulations」になっていることを確認しておきます。
Elastic Beanstalk > 環境
を開き、Green環境(Beanstalktrial-env-1)を選択し、アクションから環境URLのスワップ
を選択します。次の画面で、スワップする環境の選択で、環境名に「Beanstalktrial-env」を選択し、スワップ
を押下します。最近のイベント
を確認すると、Swapping CNAMEs for environments 'Beanstalktrial-env-1' and 'Beanstalktrial-env'.
と記載がある通り、スワップはRoute 53のCNAMEレコードの変更によって実現されています。
ここで、Elastic Beanstalk > 環境
を開き、2つの環境のURLがスワップされていることを確認します。
- 1つ目(最初)のURL(環境名「Beanstalktrial-env」で、これをBlue環境とします)
- http://beanstalktrial-env-1.ap-northeast-1.elasticbeanstalk.com/
- 2つ目のURL(環境名「Beanstalktrial-env-1」で、これをGreen環境とします)
- http://beanstalktrial-env.eba-js4ipinm.ap-northeast-1.elasticbeanstalk.com/
これでBlue/Greenデプロイが完了しました。
非常に単純な操作によって、Blue/Greenデプロイが出来ることが分かりました(小並感)。
Elastic Beanstalk自体は、AWS研修でもハンズオンを実施したことがありましたが、やはりそこは研修環境、トラブルなんて起こりません。今回は、自分のAWS環境を使って実行したので、デフォルトVPCやデフォルトサブネットが壊れていたこと、デフォルトルートテーブルがプライベート用になっていたことなど、ここに書いていないことも含めてハマりポイントがありました。過去xx年の経験によって、こういうハマりポイントを経て人は強くなっていくということを身を持って理解していますので、今後も用意された環境ではなく、自分の環境で色々と操作を試していきたいと思います。