読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

Elastic Beanstalkを使ったロードバランシングとHTTPSサイトの構築

AWS

概要

Elastic Beanstalk, ELBを使ったHTTPSサイトをCUIで構築する

詳細

ebコマンドのインストール

Elastic Beanstalkをコマンドラインから操作するにはebコマンドが必要
pipを使ってインストールする
pipは以下の記事でインストールしておく
AWS CLIを使ってコマンドラインからAWSを操作する - うさがにっき

# install
$ sudo pip install awsebcli
…

$ eb --version
EB CLI 3.4.5 (Python 2.7.6)

ebコマンドによるアプリケーションの作成

ダウンロードしたwordpressを解凍し、そのディレクトリに移動
そのディレクトリをebコマンドで制御できるように、セットアップする

$ eb init -p php
Application wordpress has been created.

次にRDB付きアプリケーションを作成する
"wordpress-env-cl"がアプリケーション環境名

    • databaseオプションをつけることで、RDSが作成される

RDSを作成するとルートユーザとパスワードを聞かれるので入力

$ eb create wordpress-env-cl --database --timeout 30

Enter an RDS DB username (default is "ebroot"): ebroot
Enter an RDS DB master password: 
Retype password to confirm: 
Creating application version archive "app-150613_224844".
Uploading wordpress/app-150613_224844.zip to S3. This may take a while.
Upload Complete.
Environment details for: wordpress-env-cl
  Application name: wordpress
  Region: ap-northeast-1
  Deployed Version: app-150613_224844
  Environment ID: e-ucpcppacza
  Platform: 64bit Amazon Linux 2015.03 v1.4.2 running PHP 5.6
  Tier: WebServer-Standard
  CNAME: UNKNOWN
  Updated: 2015-06-13 13:48:57.911000+00:00
Printing Status:
INFO: createEnvironment is starting.
INFO: Using elasticbeanstalk-ap-northeast-1-123823001885 as Amazon S3 storage bucket for environment data.
INFO: Created security group named: sg-95acc8f0
INFO: Created load balancer named: awseb-e-u-AWSEBLoa-13ZQDLP2267JU
INFO: Created security group named: awseb-e-ucpcppacza-stack-AWSEBSecurityGroup-LSHHVBVDVGU2
INFO: Created Auto Scaling launch configuration named: awseb-e-ucpcppacza-stack-AWSEBAutoScalingLaunchConfiguration-M0WWSHQ220Y4
INFO: Created RDS database security group named: awseb-e-ucpcppacza-stack-awsebrdsdbsecuritygroup-1ri2j1eygx6zd
INFO: Creating RDS database named: aat9naxt96ay05. This may take a few minutes.
INFO: Created RDS database named: aat9naxt96ay05
INFO: Created Auto Scaling group named: awseb-e-ucpcppacza-stack-AWSEBAutoScalingGroup-131JKA31BZT97
INFO: Waiting for EC2 instances to launch. This may take a few minutes.
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123823001885:scalingPolicy:b771fe19-56a1-4472-8ae0-8c62dff66a9e:autoScalingGroupName/awseb-e-ucpcppacza-stack-AWSEBAutoScalingGroup-131JKA31BZT97:policyName/awseb-e-ucpcppacza-stack-AWSEBAutoScalingScaleUpPolicy-J0GRWH5362CQ
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-1:123823001885:scalingPolicy:c5ca7db3-51eb-43de-9e1f-895df9d598ea:autoScalingGroupName/awseb-e-ucpcppacza-stack-AWSEBAutoScalingGroup-131JKA31BZT97:policyName/awseb-e-ucpcppacza-stack-AWSEBAutoScalingScaleDownPolicy-IPUOM764MQLT
INFO: Created CloudWatch alarm named: awseb-e-ucpcppacza-stack-AWSEBCloudwatchAlarmLow-1AXXIX81TGTER
INFO: Created CloudWatch alarm named: awseb-e-ucpcppacza-stack-AWSEBCloudwatchAlarmHigh-1VGOBEVVSCAT0
INFO: Added EC2 instance 'i-2bac26de' to Auto Scaling Group 'awseb-e-ucpcppacza-stack-AWSEBAutoScalingGroup-131JKA31BZT97'.
INFO: Application available at wordpress-env-cl-3eu3fpms2c.elasticbeanstalk.com.
INFO: Successfully launched environment: wordpress-env-cl

DBも含めインスタンス作ってるので、結構時間かかる(10分くらい?)
ログから色々作成している進捗がわかる

Wordpressの修正

WordpressをELBによるHTTPSに対応させるために、修正する
Elastic Beanstalkにより作成されたEC2インスタンスは同じアプリケーション環境に存在するRDSの情報を環境変数に持っている
これを利用して接続先のデータベースの設定をする

Wordpressを展開したディレクトリ内にある、wp-config-sample.phpをコピーしてwp-config.phpを作成する
作成したwp-config.phpを以下のように修正

define('DB_NAME', $_SERVER['RDS_DB_NAME']);

/** MySQL データベースのユーザー名 */
define('DB_USER', $_SERVER['RDS_USERNAME']);

/** MySQL データベースのパスワード */
define('DB_PASSWORD', $_SERVER['RDS_PASSWORD']);

/** MySQL のホスト名 */
define('DB_HOST', $_SERVER['RDS_HOSTNAME']);

/** SSL有効化 */
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);

ELBを使ったSSL通信を使うとwordpressではアクセスが無限ループしてしまう。
そのため、wp-includes/functions.phpを修正する。

function is_ssl() {
    if ( isset($_SERVER['HTTPS']) ) {
        if ( 'on' == strtolower($_SERVER['HTTPS']) )
            return true;
        if ( '1' == $_SERVER['HTTPS'] )
            return true;
    } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
        return true;
    } elseif ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
        return true;
    }
    return false;
}

ELBを使っている場合簡単にHTTPSで接続させることができる
まずは、opensslを利用してオレオレ自己証明書を作成する

オレオレ自己証明書に関しては以下を参考に
オレオレ証明書をopensslで作る(詳細版) - ろば電子が詰まっている

$ openssl genrsa -out ./server.key 2048
Generating RSA private key, 2048 bit long modulus
..........................................................+++
...........................................+++
e is 65537 (0x10001)

CSRを作成する、Common NameにはELBの名前を入れる

$ openssl req -new -key ./server.key -out ./server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo-to
Locality Name (eg, city) []:Toshima-ku
Organization Name (eg, company) [Internet Widgits Pty Ltd]:None
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:awseb-e-u-AWSEBLoa-13ZQDLP2267JU-1676648366.ap-northeast-1.elb.amazonaws.com
string is too long, it needs to be less than  64 bytes long
Common Name (e.g. server FQDN or YOUR name) []:awseb-e-u-AWSEBLoa-13ZQDLP2267JU
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

自己証明書に著名してCRTを作成

$ openssl x509 -in server.csr -days 365 -req -signkey server.key -out server.crt
Signature ok
subject=/C=JP/ST=Tokyo-to/L=Toshima-ku/O=None/CN=awseb-e-u-AWSEBLoa-13ZQDLP2267JU
Getting Private key

コマンドを実行すると、以下の3ファイルができる

  • server.crt
  • server.csr
  • server.key

これを以下の手順でELBに登録
f:id:tiro105:20150614164009p:plain
f:id:tiro105:20150614164021p:plain
プライベートキーに、server.keyの内容を入力
パブリックキー証明書に、server.crtの内容を入力
f:id:tiro105:20150614164318p:plain

ELB, RDS, Auto Scalingの設定

ELBはHTTPS, Sticky Sessionの設定、RDSはMulti-AZの設定、Auto Scalingは常時2台以上のインスタンスが稼働しているように設定する
ここまでebコマンドでやってきたので、ここもebコマンドでやってみる

eb initを実行したディレクトリの中には「.elasticbeanstalk」というディレクトリが作成されている
この中にアプリケーション環境の内容が記述されたファイル、config.ymlがある
このアプリケーション環境を追加、変更するには同じディレクトリに「.ebextensions」という名前のディレクトリを作り、拡張子が「.config」のファイルを追加する
このconfigファイルは複数存在でき、名前の順に実行される
そのため、ファイル名の先頭には数字を使うのが一般的、今回は「01_option-setting.config」というファイルを作成する

configファイルに設定を記述していく前に、確認しておくことがある
SSL証明書は先ほどアップロードした証明書をコマンドラインを使って再度指定する
ELBに証明書はアップロードされたが、AWSではIAMの中に保存されているので、以下のコマンドでIAMに保存された証明書のARNを取得する
ARNはAmazon Resource Nameの略で、AWS内にあるリソースの識別子になる

$ aws iam list-server-certificates
SERVERCERTIFICATEMETADATALIST    arn:aws:iam::123823001885:server-certificate/WP-Self-Certificate    2016-06-12T14:54:27Z    /    ASCAJX2ZLIV4HXK6AKL6C    WP-Self-Certificate    2015-06-13T15:04:09Z

arnは「arn:aws:iam::123823001885:server-certificate/WP-Self-Certificate」なのでこれを使って、設定していく
文字コードUTF-8にする

$ mkdir .ebextensions
$ cd .ebextensions/
$ vi 01_option-setting.config 
option_settings:
  # ELB HTTPS Settings
  - namespace: aws:elb:loadbalancer
    option_name: LoadBalancerHTTPSPort
    value: 443
  - namespace: aws:elb:loadbalancer
    option_name: LoadBalancerSSLPortProtocol
    value: HTTPS
  - namespace: aws:elb:loadbalancer
    option_name: SSLCertificateId
    value: arn:aws:iam::123823001885:server-certificate/WP-Self-Certificate

  # ELB Policies(Sticky Session Settings)
  - namespace: aws:elb:policies
    option_name: Stickiness Cookie Expiration
    value: 1800
  - namespace: aws:elb:policies
    option_name: Stickiness Policy
    value: true

  # Auto Scaling Settings
  ## EC2 Instance AZ
  - namespace: aws:autoscaling:asg
    option_name: Availability Zones
    value: Any 2
  ## EC2 Instance MaxSize
  - namespace: aws:autoscaling:asg
    option_name: MaxSize
    value: 4
  ## EC2 Instance MinSize
  - namespace: aws:autoscaling:asg
    option_name: MinSize
    value: 2

  # RDS Multi-AZ available
  - namespace: aws:rds:dbinstance
    option_name: MultiAZDatabase
    value: true

なお、option settingsに設定できる値はElastic Beanstalkドキュメントから確認できる
オプションの値 - Elastic Beanstalk


configの設定が終わったらデプロイする
タイムアウトは30分

$ eb deploy --timeout 30
Creating application version archive "app-150614_155353".
Uploading wordpress/app-150614_155353.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.                               
ERROR: The configuration file .ebextensions/01_option-setting.config in application version app-150614_155353 contains invalid YAML or JSON. YAML exception: while scanning for the next token
found character 	'\t' that cannot start any token
 in "<reader>", line 2, column 1:
    	# ELB
    ^
, JSON exception: Unexpected character (o) at position 0.. Update the configuration file.
ERROR: Failed to deploy application.                                
                                                                      
ERROR: Failed to deploy application.

tab使うなと言われたのでインデントをスペースに置き換えて再デプロイ

$ eb deploy --timeout 30
Creating application version archive "app-150614_160727".
Uploading wordpress/app-150614_160727.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.                               
INFO: Added EC2 instance 'i-37b858c5' to Auto Scaling Group 'awseb-e-ucpcppacza-stack-AWSEBAutoScalingGroup-131JKA31BZT97'.
INFO: Deploying new version to instance(s).                         
INFO: Adding instance 'i-37b858c5' to your environment.             
INFO: New application version was deployed to running EC2 instances.
INFO: Environment update completed successfully.   

うまくいった感じ

アクセス確認
$ eb open

でデフォルトブラウザで開く

ステータスを見たいときは以下で

$ eb status
Environment details for: wordpress-env-cl
  Application name: wordpress
  Region: ap-northeast-1
  Deployed Version: app-150614_162657
  Environment ID: e-ucpcppacza
  Platform: 64bit Amazon Linux 2015.03 v1.4.2 running PHP 5.6
  Tier: WebServer-Standard
  CNAME: wordpress-env-cl-3eu3fpms2c.elasticbeanstalk.com
  Updated: 2015-06-14 07:28:29.829000+00:00
  Status: Ready
  Health: Green

違うAZに最小2つのEC2インスタンスを設定したので作成されている
f:id:tiro105:20150614164443p:plain

ロードバランサーもいる
f:id:tiro105:20150614164505p:plain

マルチAZのRDSもいる
f:id:tiro105:20150614164517p:plain

S3にバックアップがいる様子
f:id:tiro105:20150614164531p:plain

感想

一回設定ファイルとか作っちゃえばデプロイとかは一発でできるから、環境さえできれば楽
だけど、覚えるまでは面倒くさい、コンソール画面がAWSは優秀だからそれほど使う機会ないかも

参考

Amazon Web Services パターン別構築・運用ガイド

Amazon Web Services パターン別構築・運用ガイド