morishitaです。
アクトインディではいこレポやいこーよとりっぷなどいくつかのサービスで稼働環境として AWS Elastic Beanstalkを利用しています。
本エントリでは Elastic Beanstalk を使ってみる例として Docker コンテナで極々簡単な Web アプリを公開する流れを紹介しようと思います。
AWS Elastic Beanstalk とは
AWS Elastic Beanstalkは Web アプリケーションを稼働させるインフラをまるっと用意してくれるサービスです。
公式サイト「AWS Elastic Beanstalk(ウェブアプリの実行と管理)| AWS」では次の様に紹介されています。
AWS Elastic Beanstalk は、Java、.NET、PHP、Node.js、Python、Ruby、Go および Docker を使用して開発されたウェブアプリケーションやサービスを、Apache、Nginx、Passenger、IIS など使い慣れたサーバーでデプロイおよびスケーリングするための、使いやすいサービスです。
お客様はコードをアップロードするだけで、Elastic Beanstalk が、キャパシティのプロビジョニング、ロードバランシング、Auto Scaling からアプリケーションのヘルスモニタリングまで、デプロイを自動的に処理します。同時に、お客様のアプリケーションが稼動している AWS リソースの完全な制御を維持でき、いつでも基盤となるリソースにアクセスすることができます。
Elastic Beanstalk には追加料金はかかりません。アプリケーションを格納および実行するために必要な AWS のリソースに対してのみお支払いいただきます。
具体的にはアプリケーションの稼働環境としての EC2 インスタンス、ロードバランサーを用意し、オートスケールの設定もしてくれます。デプロイしたい Web アプリがあればすぐにデプロイして公開できる環境を一揃い用意してくれます。
各種プログラミング言語環境も便利ではあると思いますが、おすすめは Dcoker 環境です。これは Docker コンテナの上でアプリケーションを動作させる実行環境です。
Elastic Beanstalk でのアプリケーションの構造
Elastic Beanstalk では「アプリケーション」というリソースをまず作成します。
その「アプリケーション」の中に「環境」を作成して Web アプリケーションをデプロイします。
1 つの「アプリケーション」の中には複数の「環境」を作成できます。
例えば、本番環境の他にステージング環境などを作ることができます。
各「環境」はデプロイ繰り返してアプリの変更を反映していくことができます。そして、デプロイする毎に「アプリケーションバージョン」として記録され、どのバージョンがどの「環境」に現在デプロイされているのかが管理されます。もしデプロイしたバージョンに不具合があって戻したい場合、過去の「アプリケーションバージョン」を指定してサクッとデプロイし直したりできます。
この様なアプリケーションをいくつも作成できます。
図にするとこんな感じです。
1つの「環境」を作って Web アプリを公開するまでの手順は大きく分けて次の3ステップです。
- 公開する Web アプリの Docker イメージと docker-compose.yml を用意する
- 「アプリケーション」を作成する
- 「環境」を作成する
では順に説明していきます。
EB CLI のインストール
上記のステップの説明に入る前に道具を用意します。
AWS の Web コンソールからも各種設定が可能ですが、 Elastic Beanstalk 専用の CLI が用意されているのでそれを使うのがおすすめです。
Web アプリをデプロイしていくのに先立ち EB CLI をインストールします。
macOS なら homebrew でサクッとインストールできます。
$ brew install awsebcli
なお EB CLI を実行する時の認証情報は AWS CLI のものを利用するのでそちらも設定しておきます1。
公開する Web アプリの Docker イメージと docker-compose.yml を用意する
では、いよいよ Web アプリをデプロイしていきます。
そのためにはデプロイしたいWebアプリを含む Docker イメージを用意する必要があります。
イメージをビルドするところから説明すると少々長くなるので、今回そこは省略してAmazon ECR Public Galleryでイメージが公開されているパズルアプリ 2048 をデプロイしてみます。
実行するコンテナは docker-compose.yml で定義します。
アプリのルートとなるディレクトリを作って、その中に docker-compose.yml を作成します。
名前は何でもいいのですが、この例では sample-app という名前でディレクトリを作成してその中に作ります。
sample-app/ └── docker-compose.yml
docker-compose.yml 中身はこんな感じです。
version: '2.4' services: app: image: public.ecr.aws/l6m2t8p7/docker-2048:latest ports: - "80:80" mem_limit: 128m
Elastic Beanstalk にデプロイするための特殊な仕様追加などはなく、普通の docker-compose.yml です。 この例ではコンテナを1つだけ定義していますが、もちろん複数のコンテナを動かすことも可能です。
「アプリケーション」を作成する
docker-compose.yml を作成したら、sample-app ディレクトリでターミナルを開いて、eb init
コマンドでアプリケーションを初期化(= 作成)します。
途中次を質問されます。この例ではそれぞれ次の様に選択します。
- リージョン
- => 適当に。例では東京リージョンを選択します。
- アプリケーションの名前
- => デフォルトではディレクトリ名になります。
- プラットフォームの種類
- => 3) Docker を選択
- Docker プラットフォーム内の種類を選択
- => Docker running on 64bit Amazon Linux 2 を選択。他の 2 つは Deprecated なので一択。
- SSh での接続可否と keypair
- => 必要に応じて設定する。この例では既存のキーを指定します。
実行例は次の通りです。
❯ 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 Enter Application Name (default is "sample-app"): Application sample-app has been created. Select a platform. 1) .NET Core on Linux 2) .NET on Windows Server 3) Docker 4) GlassFish 5) Go 6) Java 7) Node.js 8) PHP 9) Packer 10) Python 11) Ruby 12) Tomcat (make a selection): 3 Select a platform branch. 1) Docker running on 64bit Amazon Linux 2 2) Multi-container Docker running on 64bit Amazon Linux (Deprecated) 3) Docker running on 64bit Amazon Linux (Deprecated) (default is 1): 1 Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization Do you want to set up SSH for your instances? (Y/n): Select a keypair. 1) my-aws-key 2) [ Create new KeyPair ] (default is 1): 1
実行後、AWS コンソールを確認すると次の様にアプリケーションが作成されています。
また、sample-app ディレクトリには選択結果を保存した設定ファイルが作成されます。
sample-app/ ├── .elasticbeanstalk/ │ └── config.yml ├── .gitignore └── docker-compose.yml
config.yml の中身はこんな感じです。
branch-defaults: default: environment: sample-app-dev group_suffix: null global: application_name: sample-app branch: null default_ec2_keyname: my-aws-key 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
CLIによる環境作成
「アプリケーション」が作成できたので、いよいよ eb create
コマンドで「環境」を作ってコンテナをデプロイします。
コマンド実行時に次の項目を尋ねられます。
- 「環境」の名称
- ロードバランサーの種類を聞かれます。
- => ALB を利用したいので 2) application を選択
- スポットインスタンスを利用するか
- => 必要に応じて適当に。
- インスタンスタイプ
- => この例では無料枠に収まる
t3.micro,t2.micro
を指定
- => この例では無料枠に収まる
eb create
コマンド実行例は次の通りです。
❯ eb create Enter Environment Name (default is sample-app-dev): Enter DNS CNAME prefix (default is sample-app-dev): Select a load balancer type 1) classic 2) application 3) network (default is 2): 2 Would you like to enable Spot Fleet requests for this environment? (y/N): y Enter a list of one or more valid EC2 instance types separated by commas (at least two instance types are recommended). (Defaults provided on Enter): t3.micro,t2.micro Creating application version archive "app-220122_161704". Uploading sample-app/app-220122_161704.zip to S3. This may take a while. Upload Complete. Environment details for: sample-app-dev Application name: sample-app Region: ap-northeast-1 Deployed Version: app-220122_161704 Environment ID: e-fnmkcyenrk Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Docker running on 64bit Amazon Linux 2/3.4.10 Tier: WebServer-Standard-1.0 CNAME: sample-app-dev.ap-northeast-1.elasticbeanstalk.com Updated: 2022-01-24 07:17:07.666000+00:00 Printing Status: 2022-01-24 07:17:06 INFO createEnvironment is starting. 2022-01-24 07:17:07 INFO Using elasticbeanstalk-ap-northeast-1-999999999999 as Amazon S3 storage bucket for environment data. 2022-01-24 07:17:29 INFO Created target group named: arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:targetgroup/awseb-AWSEB-DXXOTGRP890F/458e3c267aba54d9 2022-01-24 07:17:29 INFO Created security group named: sg-0f2dd09c2badc9a0f 2022-01-24 07:17:45 INFO Created security group named: awseb-e-fnmkcyenrk-stack-AWSEBSecurityGroup-197VD45J3TQRM 2022-01-24 07:18:31 INFO Created Auto Scaling group named: awseb-e-fnmkcyenrk-stack-AWSEBAutoScalingGroup-R5X9LVVJYA2H 2022-01-24 07:18:31 INFO Waiting for EC2 instances to launch. This may take a few minutes. 2022-01-24 07:18:31 INFO Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:999999999999:scalingPolicy:220d602e-1461-4d09-9467-ba14e12ecbbc:autoScalingGroupName/awseb-e-fnmkcyenrk-stack-AWSEBAutoScalingGroup-R5X9LVVJYA2H:policyName/awseb-e-fnmkcyenrk-stack-AWSEBAutoScalingScaleDownPolicy-9H2VG3T76QRV 2022-01-24 07:18:31 INFO Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:999999999999:scalingPolicy:fa2522b4-9460-4191-87c2-35df36d2bdff:autoScalingGroupName/awseb-e-fnmkcyenrk-stack-AWSEBAutoScalingGroup-R5X9LVVJYA2H:policyName/awseb-e-fnmkcyenrk-stack-AWSEBAutoScalingScaleUpPolicy-1BTC6KF1WN63W 2022-01-24 07:18:31 INFO Created CloudWatch alarm named: awseb-e-fnmkcyenrk-stack-AWSEBCloudwatchAlarmHigh-1N9OM9QI0W0EF 2022-01-24 07:18:31 INFO Created CloudWatch alarm named: awseb-e-fnmkcyenrk-stack-AWSEBCloudwatchAlarmLow-1I78W8RVKBR0U 2022-01-24 07:19:33 INFO Created load balancer named: arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:loadbalancer/app/awseb-AWSEB-C5P8NMUJTEM9/86fd65519f5f3b2b 2022-01-24 07:19:53 INFO Created Load Balancer listener named: arn:aws:elasticloadbalancing:ap-northeast-1:999999999999:listener/app/awseb-AWSEB-C5P8NMUJTEM9/86fd65519f5f3b2b/ecb57231ccb8f7e8 2022-01-24 07:20:13 INFO Instance deployment completed successfully. 2022-01-24 07:20:30 INFO Application available at sample-app-dev.ap-northeast-1.elasticbeanstalk.com. 2022-01-24 07:20:31 INFO Successfully launched environment: sample-app-dev
実行すると裏側で CloudFormation スタックが作成され次のリソース群を作成します。
VPC やサブネットはアカウントのデフォルトが利用されます。
- オートスケーリンググループ
- EC2 インスタンスとセキュリティグループ
- ALB とターゲットグループとセキュリティグループ
作成中は AWS コンソールでも処理の様子を見ることができます。
5分程度で処理は完了して「環境」が構築されます。
デプロイされたアプリの URL が表示されているので、ブラウザからそれにアクセスすると 2048 が表示されます。
シンプルですが結構ハマるパズルアプリです2。
なお、作成した「環境」は「アプリケーション」のリストにも表示されます。
どんなふうにデプロイされているのか?
SSH で構築された EC2 インスタンスに入ってどの様に動いているのか見てみます。
❯ ssh ec2-user@xx.xx.xx.xx -i ~/.ssh/my-aws-key.cer The authenticity of host 'xx.xx.xx.xx (xx.xx.xx.xx)' can't be established. ED25519 key fingerprint is SHA256:ht6XZNY0C0bbxLM1x/O14I+w9u6iET4VS0+NZ6Ft024. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added 'xx.xx.xx.xx' (ED25519) to the list of known hosts. _____ _ _ _ ____ _ _ _ | ____| | __ ___| |_(_) ___| __ ) ___ __ _ _ __ ___| |_ __ _| | | __ | _| | |/ _ \/ __| __| |/ __| _ \ / _ \/ _\ | '_ \/ __| __/ _\ | | |/ / | |___| | (_| \__ \ |_| | (__| |_) | __/ (_| | | | \__ \ || (_| | | < |_____|_|\__,_|___/\__|_|\___|____/ \___|\__,_|_| |_|___/\__\__,_|_|_|\_\ Amazon Linux 2 AMI This EC2 instance is managed by AWS Elastic Beanstalk. Changes made via SSH WILL BE LOST if the instance is replaced by auto-scaling. For more information on customizing your Elastic Beanstalk environment, see our documentation here: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html [ec2-user@ip-172-31-19-97 ~]$ sudo -i [root@ip-172-31-19-97 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3114193194cb public.ecr.aws/l6m2t8p7/docker-2048:latest "nginx -g 'daemon of…" 2 hours ago Up 2 hours 0.0.0.0:80->80/tcp, :::80->80/tcp current_app_1
ちゃんと指定したイメージでコンテナが稼働していますね。
また、docker-compose.yml は /var/app/current/ ディレクトリに配置されています。
[root@ip-172-31-19-97 ~]# cat /var/app/current/docker-compose.yml version: '2.4' services: app: image: public.ecr.aws/l6m2t8p7/docker-2048:latest ports: - "80:80" mem_limit: 128m
まとめ
今回は 2048 のデプロイを通して、Elastic Beanstalk で Web アプリを公開するまでの流れを紹介しました。
結構、少ない手順でサーバを立てて、ブラウザでアクセスできるようにできるのがわかってもらえたかと思います。
しかし、商用のサービスシステムの稼働環境として利用する場合には次の様なことはどうするのか?と気になるかもしれません。
- デフォルト VPC でなく、サービス専用の VPC にデプロイしたい
- オートスケールの条件を設定したい
- ログはどう出力するのか?
- DB は?
- etc.
次回、これらの設定について紹介したいと思います。
最後に
アクトインディではエンジニアを募集しています。
参考
- AWS Elastic Beanstalk(ウェブアプリの実行と管理)| AWS
- Elastic Beanstalk コマンドラインインターフェイス (EB CLI) の使用 - AWS Elastic Beanstalk
- EB CLI コマンドリファレンス - AWS Elastic Beanstalk