Edited at

HTTP/2対応のElastic Beanstalk環境を構築する

More than 1 year has passed since last update.


はじめに


サービスの紹介

2017/10/16 にリリースした Snapmap(スナップマップ) は、

「いつ」「なにを」「どこで」「どうやって」撮影したのかが分かるというコンセプトのサービスです。

そんな Snapmap ですが、画像共有サービスなのでサイト全体は HTTP/2 で表示するようになっています。

その効果1もあり、サイトのパフォーマンスを計測するとこんな感じで結構速いです。


Elastic Beanstalkとは

Snapmap は Elastic Beanstalk を使ってアプリケーションサーバーの環境を構築しています。

Elastic Beanstalk は AWS のサービスの一つで、デプロイ・サーバー監視・スケーリングの全てをまるっとやってくれます。

新規サービスで考慮しておくべきことの多くをショートカットできるのはとても魅力的で、インフラにコストを掛けたくなかった今回の案件にぴったりでした。


HTTP/2にする、その前に

Elastic Beanstalk で構築したアプリケーションサーバーを HTTP/2 に対応させるには、ロードバランサーを Application Load Balancer にする必要があります2

ただ、普通に Web の画面からポチポチ作成すると Classic Load Balancerで環境を構築されてしまいます(2017/12/1 現在)。

さらに、悲しいことに環境構築後にロードバランサーの種類は変更できません

なので、一番初めから EB CLI を使って作成する必要があります。

すでに構築してしまっている場合は諦めて別環境を再作成しましょう。

というわけで、自分の備忘録として今回は一から手順を書いていきたいと思います。


手順


AWS CLI / EB CLIのインストール

EB CLI のインストールがまだであれば以下のコマンドでインストールできます。(AWS CLI も後で必要なのでついでにインストールします)

$ pip install --upgrade pip

$ pip install awscli --user
$ pip install blessed --user
$ pip install awsebcli --user


AWSの設定

aws configure を利用して、AWSへのアクセス情報を設定します。

$ aws configure

AWS Access Key ID [None]: AKIA*********EXAMPLE # アクセスキーを指定
AWS Secret Access Key [None]: wJa***************************EXAMPLEKEY # シークレットアクセスキーを指定
Default region name [None]: ap-northeast-1
Default output format [None]: json

アクセスキーをまだ発行していなければこちらを参考に。


Elastic Beanstalkの環境作成

準備ができたので Elastic Beanstalk の環境を作っていきます。

まず初期設定を行います。

デプロイ用ディレクトリを作成して eb init を実行し、リージョンとアプリケーションを選択します。

$ mkdir hogehoge

$ cd hogehoge
$ 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): 9 # 東京リージョンを選ぶ

Select an application to use
1) [ Create new Application ]
(default is 1): 1 # 新規アプリを選ぶ

Enter Application Name
(default is "hogehoge"): hogehoge # ディレクトリ名がデフォルトになっているのでアプリ名を入力する
Application hogehoge has been created.

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
(default is 1): 4 # プラットフォームを選ぶ

Select a platform version.
1) Ruby 2.4 (Puma)
2) Ruby 2.3 (Puma)
3) Ruby 2.2 (Puma)
4) Ruby 2.1 (Puma)
5) Ruby 2.0 (Puma)
6) Ruby 2.4 (Passenger Standalone)
7) Ruby 2.3 (Passenger Standalone)
8) Ruby 2.2 (Passenger Standalone)
9) Ruby 2.1 (Passenger Standalone)
10) Ruby 2.0 (Passenger Standalone)
11) Ruby 1.9.3
(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): Y # 対象サーバーにSSHアクセスしたいならYes

Select a keypair.
1) hogehoge_bastion
2) [ Create new KeyPair ]
(default is 1): 2 # キーペアは新規作成がオススメ

次に環境の作成ですが、ここで注意したいのが、1 つの VPC とアベイラビリティーゾーンが異なる 2 つのサブネットが必要という点です。

可用性確保のためにそういう仕様になっているっぽいです。

つまり先に VPC とサブネットは作成しておく必要があります。

作成ができたら eb create を実行し、環境を作成します。

eb create xxxxxxxx \

--elb-type application \
--vpc.id vpc-xxxxxxxx \ # 作成したVPC
--vpc.elbsubnets subnet-xxxxxxxx,subnet-xxxxxxxx \ # 作成したサブネット
--vpc.ec2subnets subnet-xxxxxxxx,subnet-xxxxxxxx \ # 作成したサブネット
--vpc.elbpublic \
--vpc.publicip

これでサンプルアプリのサイトが構築されます。こんな感じ。

うまく起動したら、環境作成はいったん完了です。

ちなみに、試行錯誤をしていく上で Still waiting for the following 1 instances to become healthy: [i-xxxxxxxxxxxxxxxxx]. みたいなヘルスチェック待ちがうっとおしかったりするので、AWS の管理画面にて一時的にヘルスチェックを無視するようにしておくと良いです。


ebextensionsを設置

次にソースコードを HTTP/2 対応させます。

こちらを参考に、ソースコードのプロジェクト直下にHTTPをHTTPSにリダイレクトさせるための .ebextensions ファイルを作ります。


.ebextensions/01_aws.config

option_settings:

aws:elbv2:listener:443:
DefaultProcess: default
ListenerEnabled: true
Protocol: HTTPS
SSLCertificateArns: rn:aws:acm:ap-northeast-1:*************************** # 先ほど発行した証明書のARN
aws:elbv2:listener:80:
DefaultProcess: http
ListenerEnabled: true
Protocol: HTTP
aws:elasticbeanstalk:environment:process:default:
Port: 80
Protocol: HTTP
StickinessEnabled: true
StickinessLBCookieDuration: 43200
HealthCheckPath: /
HealthCheckTimeout: 30
HealthCheckInterval: 60
MatcherHTTPCode: 200
aws:elasticbeanstalk:environment:process:http:
Port: 81
Protocol: HTTP
HealthCheckPath: /
HealthCheckTimeout: 30
HealthCheckInterval: 60
MatcherHTTPCode: 301


.ebextensions/02_nginx.config

files:

/etc/nginx/conf.d/redirect.conf:
mode: "000644"
owner: root
group: root
content: |
server {
listen 81;
rewrite ^ https://$host$request_uri permanent;
}

Elastic Beanstalk の関連ファイルを無視するよう .gitignore に以下を追加します。


.gitignore

# Elastic Beanstalk Files

.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml

ソースコードの変更は以上です。


ソースコードの取得

作成したデプロイ用ディレクトリにソースコードを配置します。

$ cd hogehoge # デプロイ用ディレクトリに移動する

$ git init
$ git remote add origin git@github.com:CoachUnited/hogehoge.git
$ rm .gitignore # 自動で作成されてしまうので消す
$ git pull origin master

次に環境変数を設定し、再度デプロイします。

$ eb setenv RAILS_ENV=production HOGE=fuga 〜 # 必要な環境変数をつらつらと

$ eb deploy # ソースコードをデプロイ

これでサイトが正しく表示されれば OK です。

次は SSL 対応をしていきます。


証明書の取得

こちらを参考に AWS Certificate Manager を利用して、サイトドメインで利用する証明書を取得します。

ちなみに、テスト環境もSSL化したい場合はワイルドカード証明書(*.snapmap.jp)を作成すればOKですが、ワイルドカード証明書はルートドメイン(snapmap.jp)には使えないので注意してください。

(なんと、11月の時点でSESでメールを受け取る必要がなくなったそうです :tada:


Route53を設定

あとは Route53 でサイトドメインの Hosted Zone から A レコードを作成して、ElasitcBeanstalk で作成された環境のドメインを割り当ててください。

これですべて完了です。

ブラウザでアクセスして HTTP/2 になっていれば成功です。お疲れ様でした。


まとめ

手順自体はそこそこ長いですが、実際に作業してみるととても簡単に、そして一度作成してしまえば後は AWS におまかせできます。

スモールスタートのプロジェクトには ElasticBeanstalk 超超オススメです!





  1. Vue.js や materializecss の利用も速度向上に大きく寄与しています。 



  2. 画像は CloudFront で配信されているため、Supported HTTP Versions を「HTTP/2, HTTP/1.1, HTTP/1.0」にするだけで HTTP/2 化できます。