Elastic Beanstalk のカスタムプラットフォームを試してみた

Elastic Beanstalk

こんにちは、藤本です。

現地時間 2/22 に Elastic Beanstalk のカスタムプラットフォームがリリースされました。

概要

Elastic Beanstalk はWebアプリケーションやワーカーアプリケーションを簡単にセットアップ、継続的デプロイできるサービスです。今まではある程度決まった構成の AMI を利用することができました。カスタマイズするとすれば、Docker Image を利用することはできましたが全てのアプリケーションが Docker に向いているわけではありません。また独自 AMI を利用することも可能でしたが、Elastic Beanstalk の癖があり、簡単に扱うことができませんでした。

それが今回リリースされたカスタムプラットフォームにより、Elastic Beanstalk に最適な独自 AMI を容易に作成することが可能となりました。簡単に言うと、ベースとなる AMI から Packer を使って、Elastic Beanstalk に最適な AMI(カスタムプラットフォーム)を作成してくれます。Elastic Beanstalk の利用シーンが広がりそうですね!

カスタムプラットフォームの動作を図で表すと、こんな感じになるかと思います。

CustomPlatform

試してみた

今回はドキュメントにあるサンプルを利用して、カスタムプラットフォームの動作を把握したいと思います。

  1. カスタムプラットフォームの作成
  2. カスタムプラットフォームを利用した EB アプリケーションの作成

事前準備

ebcli のインストール

今回はebcliを利用して試してみました。ebcliをインストールしていない方はインストールを、既にebcliをインストール済みの方はアップデートしてください。

インストールする場合
$ pip install awsebcli
アップデートする場合
$ pip install -U awsebcli

サンプルカスタムプラットフォームのダウンロード

公式ドキュメントに Node.js on Ubuntu のカスタムプラットフォームのサンプルが zip ファイルで配布されていますのでこちらをダウンロードします。

サンプルアプリケーションのダウンロード

同じく公式ドキュメントに Node.js アプリケーションのサンプルが zip ファイルで配布されていますのでこちらもダウンロードします。

カスタムプラットフォームの作成

まずはカスタムプラットフォームを作成します。ダウンロードした zip ファイルを展開します。

$ mkdir custom-platform
$ cd custom-platform
$ unzip ~/NodePlatform_Ubuntu.zip
$ cd NodePlatform_Ubuntu

こちらのサンプルは既にカスタムプラットフォームを作成するのに必要なファイルが揃っています。ちょっと中身に触れてみます。

ディレクトリ構成です。省略している platform-uploads はインスタンスにアップロードするファイル群を配置しています。nginx のコンフィグファイルや、eb の hook スクリプトなどがあります。

$ tree .
.
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── builder
│   ├── CONFIG
│   ├── builder.sh
│   ├── platform-uploads
<<snip>>
│   └── setup-scripts
│       ├── 00-sync-apt.sh
│       ├── 01-install-nginx.sh
│       └── 02-setup-platform.sh
├── custom_platform.json
└── platform.yaml

28 directories, 46 files
platform.yaml

このファイルがカスタムプラットフォーム作成の大元の設定ファイルとなります。

$ cat platform.yaml
#   Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
#   Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
#
#   http://aws.amazon.com/apache2.0/
#
#   or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

version: "1.0"

provisioner:
  type: packer
  template: custom_platform.json
  flavor: ubuntu1604

metadata:
  maintainer: <please enter your name here>
  description: Sample NodeJs Container.
  operating_system_name: Ubuntu
  operating_system_version: 16.04
  programming_language_name: ECMAScript
  programming_language_version: ECMA-262
  framework_name: NodeJs
  framework_version: 4.4.4
  app_server_name: "none"
  app_server_version: "none"

option_definitions:
  - namespace: "aws:elasticbeanstalk:container:custom:application"
    option_name: "NPM_START"
    description: "Default application startup command"
    default_value: "node application.js"
provisioner

カスタムプラットフォームのカスタマイズの定義となります。現在はpackerのみをサポートしています。template は packer の設定テンプレートファイルを指します。この設定ファイルに従って packer が動作します。flavor はベースとなる AMI の OS タイプを指定します。現在指定可能な flavor(OSの種類)は amazon, ubuntu1604, rhel7, rhel6 の 4種類です。

metadata

カスタムプラットフォームの環境情報を記載します。

option_definitions

カスタムプラットフォームで利用できるオプションのデフォルト値を設定できます。(環境変数的なもの)

custom_platform.json

platform.yamlの template で指定した Packer の設定テンプレートファイルです。利用するベースのAMIを指定したり、AMIから作成するインスタンスのインスタンスタイプを指定したり、今回の例ではプロビジョンの方法として、builder/builder.shのシェルスクリプトを実行して、設定を行います。

{
  "variables": {
    "platform_name": "{{env `AWS_EB_PLATFORM_NAME`}}",
    "platform_version": "{{env `AWS_EB_PLATFORM_VERSION`}}",
    "platform_arn": "{{env `AWS_EB_PLATFORM_ARN`}}"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "name": "HVM AMI builder",
      "region": "us-west-2",
      "source_ami": "ami-7c803d1c",
      "instance_type": "m3.medium",
      "ssh_username": "ubuntu",
      "ssh_pty": "true",
      "ami_name": "NodeJs running on Ubuntu Server 16.04 LTS (built on {{isotime \"20060102150405\"}})",
      "tags": {
        "eb_platform_name": "{{user `platform_name`}}",
        "eb_platform_version": "{{user `platform_version`}}",
        "eb_platform_arn": "{{user `platform_arn`}}"
      }
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "builder",
      "destination": "/tmp/"
    },
    {
      "type": "shell",
      "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo {{ .Path }}",
      "scripts": [
        "builder/builder.sh"
      ]
    }
  ]
}

Packer の設定テンプレートファイルの書き方は Packer のドキュメントをご参照ください。

platform.yaml のフォーマットは下記ドキュメントをご参照ください。

カスタムプラットフォーム作成

カスタムプラットフォームを作成します。まずはebp initで初期設定します。カスタムプラットフォームを作成するリージョンと、カスタムプラットフォームを指定します。既に一回カスタムプラットフォームを作成ずみだったため、NodePlatform_Ubuntu が表示されていますが、新規作成であれば、Create new Platform からカスタムプラットフォーム名を入力します。

$ ebp 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) us-east-2 : US East (Ohio)
14) ca-central-1 : Canada (Central)
15) eu-west-2 : EU (London)
(default is 3):

Select a platform to use
1) NodePlatform_Ubuntu
2) [ Create new Platform ]
(default is 1):

.elasticbeanstalk が作成されます。

$ cat .elasticbeanstalk/config.yml
global:
  application_name: Custom Platform Builder
  branch: null
  default_ec2_keyname: null
  default_platform: null
  default_region: us-west-2
  instance_profile: null
  platform_name: NodePlatform_Ubuntu
  platform_version: 1.0.0
  profile: null
  repository: null
  sc: null
  workspace_type: Platform

ebp createコマンドでカスタムプラットフォームを作成します。

$ ebp create
Creating application version archive "app-170312_124140".
Uploading NodePlatform_Ubuntu/app-170312_124140.zip to S3. This may take a while.
Upload Complete.
Note: An environment called 'eb-custom-platform-builder-packer' has been created in order to build your application. This environment will not automatically be terminated and it does have a cost associated with it. Once your platform creation has completed you can terminate this builder environment using the command 'eb terminate'.
INFO: createPlatform is starting.
INFO: Initiated platform version creation for 'NodePlatform_Ubuntu/1.0.1'.
INFO: Creating Packer builder environment 'eb-custom-platform-builder-packer'.
 -- Events -- (safe to Ctrl+C)

<<snip>>

INFO: Creating CloudWatch log group '/aws/elasticbeanstalk/platform/NodePlatform_Ubuntu'.
INFO: Successfully built AMI(s): 'ami-9dfe70fd' for 'arn:aws:elasticbeanstalk:us-west-2:xxxxxxxxxxxx:platform/NodePlatform_Ubuntu/1.0.1'
INFO: Packer built AMIs: ami-9dfe70fd.
INFO: Successfully created platform version 'NodePlatform_Ubuntu/1.0.1'.

AMIからインスタンス作ったり、インスタンスをセットアップしたり、セットアップしたインスタンスをAMI化したりで結構時間かかります。

カスタムプラットフォームが作成されています。

Elastic_Beanstalk_Applications 3

カスタムプラットフォーム作成によって作成されたものを見てみましょう。まずは通常の EB 同様、CloudFormation Stack が生成されています。

CloudFormation_Management_Console

そして、カスタムプラットフォームの AMI も作成されています。

EC2_Management_Console

今は最初に記載した図の状態です。

CustomPlatform

カスタムプラットフォームが作成し終わったあとも Packer インスタンスが残るんだけど、落としていいのかな。。

EB アプリケーション作成

作成したカスタムプラットフォームを利用して、EB アプリケーションを作成します。eb initで EB アプリケーションの初期設定を行います。利用するプラットフォームにCustom Platformを選択し、先に作成したカスタムプラットフォームの名前を指定します。カスタムプラットフォームは作成する度に新規バージョンが払い出されますので、バージョンを指定することができます。

$ mkdir custom-platform-app
$ cd custom-platform-app
$ 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) us-east-2 : US East (Ohio)
14) ca-central-1 : Canada (Central)
15) eu-west-2 : EU (London)
(default is 3):

Select an application to use
1) Custom Platform Builder
2) [ Create new Application ]
(default is 2):

Enter Application Name
(default is "custom-platform-app"):

Select a platform.
1) Node.js
2) PHP
3) Python
4) Ruby
5) Tomcat
6) IIS
7) Docker
8) Multi-container Docker
9) GlassFish
10) Go
11) Java
12) Packer
13) Custom Platform
(default is 1): 13

Select a platform.
1) NodePlatform_Ubuntu (Owned by: xxxxxxxxxxx)
(default is 1):

Select a platform version.
1) 1.0.1
2) 1.0.0
(default is 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): Y

Select a keypair.
1) cm-fujimoto
2) [ Create new KeyPair ]
(default is 1): 

ダウンロードしていたサンプルの Node.js アプリケーションを展開します。

$ unzip ~/NodeSampleApp.zip

EB アプリケーションを作成します。

$ eb create
Enter Environment Name
(default is custom-platform-app-dev):
Enter DNS CNAME prefix
(default is custom-platform-app-dev):

Select a load balancer type
1) classic
2) application
(default is 1):
Creating application version archive "app-170312_132834".
Uploading custom-platform-app/app-170312_132834.zip to S3. This may take a while.
Upload Complete.
Application custom-platform-app has been created.
Environment details for: custom-platform-app-dev
  Application name: custom-platform-app
  Region: us-west-2
  Deployed Version: app-170312_132834
  Environment ID: e-xgjaanhffx
  Platform: arn:aws:elasticbeanstalk:us-west-2:xxxxxxxxxxx:platform/NodePlatform_Ubuntu/1.0.1
  Tier: WebServer-Standard
  CNAME: custom-platform-app-dev.us-west-2.elasticbeanstalk.com
  Updated: 2017-03-12 04:28:52.192000+00:00
Printing Status:
INFO: createEnvironment is starting.
INFO: Using elasticbeanstalk-us-west-2-xxxxxxxxxxx as Amazon S3 storage bucket for environment data.
INFO: Environment health has transitioned to Pending. Initialization in progress (running for 37 seconds). There are no instances.
INFO: Created security group named: sg-fe97aa86
INFO: Created load balancer named: awseb-e-x-AWSEBLoa-1QI9H8DN2A78V
INFO: Created security group named: awseb-e-xgjaanhffx-stack-AWSEBSecurityGroup-1H1BRTODB1JTM
INFO: Created Auto Scaling launch configuration named: awseb-e-xgjaanhffx-stack-AWSEBAutoScalingLaunchConfiguration-138J78C075UZM
INFO: Created Auto Scaling group named: awseb-e-xgjaanhffx-stack-AWSEBAutoScalingGroup-1CJOKSMPCJ5QD
INFO: Waiting for EC2 instances to launch. This may take a few minutes.
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:us-west-2:xxxxxxxxxxxx:scalingPolicy:ee28efb7-b568-47f5-b0af-b71b1a5f82de:autoScalingGroupName/awseb-e-xgjaanhffx-stack-AWSEBAutoScalingGroup-1CJOKSMPCJ5QD:policyName/awseb-e-xgjaanhffx-stack-AWSEBAutoScalingScaleUpPolicy-1MU9WLQUJBMQA
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:us-west-2:xxxxxxxxxxxxx:scalingPolicy:48594629-0430-4a2e-9431-2c3f6a2a9010:autoScalingGroupName/awseb-e-xgjaanhffx-stack-AWSEBAutoScalingGroup-1CJOKSMPCJ5QD:policyName/awseb-e-xgjaanhffx-stack-AWSEBAutoScalingScaleDownPolicy-ETRK3Y1P00C0
INFO: Created CloudWatch alarm named: awseb-e-xgjaanhffx-stack-AWSEBCloudwatchAlarmHigh-1O6DQYIZFTL6R
INFO: Created CloudWatch alarm named: awseb-e-xgjaanhffx-stack-AWSEBCloudwatchAlarmLow-1M34TJLG0E4I7
INFO: Added instance [i-04d52cab831f3a84c] to your environment.
INFO: Environment health has transitioned from Pending to Ok. Initialization completed 31 seconds ago and took 3 minutes.
INFO: Successfully launched environment: custom-platform-app-dev

EB アプリケーションができました。

Elastic_Beanstalk_Applications 4

ヘルスチェックも問題ないです。

custom-platform-app-dev_-_Dashboard

図で表すとこんな感じだと思います。

EBApp

動作確認

それでは中身を覗いてみましょう。

Webアクセス

まず Webアクセスが成功することを確認してみます。

Custom_Platform_Node_Sample_App

うん、ページが表示されます。

OS から確認

SSH ログインして、Packer による設定を確認してみます。

$ ps -ef |grep nginx
root      1789     1  0 04:32 ?        00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data  1790  1789  0 04:32 ?        00:00:00 nginx: worker process
ubuntu   16863 16813  0 13:33 pts/0    00:00:00 grep --color=auto nginx

$ ps -ef |grep node
root      1729  1724  0 04:32 ?        00:00:11 node /var/app/current/app.js
root      1730  1724  0 04:32 ?        00:00:10 node /var/app/current/app2.js
ubuntu   16897 16813  0 13:34 pts/0    00:00:00 grep --color=auto node

Packer で設定していた Nginx が動いていたり、Node.js が動いていたりしています。

まとめ

いかがでしたでしょうか? 今まで EB の独自環境・独自ルールに馴染めず移行はできないが、EB 独自のメトリクスや、豊富なリリース方式が羨ましい方もいらっしゃったのではないでしょうか。今回のカスタムプラットフォームのリリースにより利用の敷居は下がったように感じました。是非試されてみてはいかがでしょうか。

参考リンク