アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Elastic Beanstalk 入門

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 つの「アプリケーション」の中には複数の「環境」を作成できます。
例えば、本番環境の他にステージング環境などを作ることができます。

各「環境」はデプロイ繰り返してアプリの変更を反映していくことができます。そして、デプロイする毎に「アプリケーションバージョン」として記録され、どのバージョンがどの「環境」に現在デプロイされているのかが管理されます。もしデプロイしたバージョンに不具合があって戻したい場合、過去の「アプリケーションバージョン」を指定してサクッとデプロイし直したりできます。

この様なアプリケーションをいくつも作成できます。
図にするとこんな感じです。

f:id:HeRo:20220125001359p:plain
アプリケーションの構造

1つの「環境」を作って Web アプリを公開するまでの手順は大きく分けて次の3ステップです。

  1. 公開する Web アプリの Docker イメージと docker-compose.yml を用意する
  2. 「アプリケーション」を作成する
  3. 「環境」を作成する

では順に説明していきます。

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 コンソールを確認すると次の様にアプリケーションが作成されています。

f:id:HeRo:20220125001438p:plain
「アプリケーション」のリスト

また、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 コンソールでも処理の様子を見ることができます。

f:id:HeRo:20220125001518p:plain
「環境」作成中

5分程度で処理は完了して「環境」が構築されます。

f:id:HeRo:20220125001554p:plain
作成された「環境」

デプロイされたアプリの URL が表示されているので、ブラウザからそれにアクセスすると 2048 が表示されます。

シンプルですが結構ハマるパズルアプリです2

f:id:HeRo:20220125001716p:plain
2048

なお、作成した「環境」は「アプリケーション」のリストにも表示されます。

f:id:HeRo:20220125001626p:plain
「環境」作成後の「アプリケーション」のリスト

どんなふうにデプロイされているのか?

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.

次回、これらの設定について紹介したいと思います。

最後に

アクトインディではエンジニアを募集しています。

actindi.net

参考


  1. aws configure を使用したクイック設定

  2. とりあえず 2048 をやってみたいという方はこちらをどうぞ。2048