AWSでWordPress構築 (EC2+RDS+ELB)

仕事が忙しく、AWSのリハビリのためWordPress構築してみました。

#VPCとSubnet
■VPC

|Name|VPC CIDR|DNS ホスト名|
|:----------|:----------|:----------|
|VPC-wp|10.0.0.0/16|はい|

■Subnet

|Name|アベイラビリティーゾーン|CIDR|自動割り当てパブリック IP|
|:----------|:----------|:----------|:----------|
|Subnet-Public-wp-A|ap-northeast-1a|10.0.0.0/24|はい|
|Subnet-Public-wp-C|ap-northeast-1c|10.0.1.0/24|はい|
|Subnet-Private-wp-A|ap-northeast-1a|10.0.10.0/24|いいえ|
|Subnet-Private-wp-C|ap-northeast-1c|10.0.11.0/24|いいえ|

■InternetGateway

|Name|アタッチ先VPC|
|:----------|:----------|
|InternetGateway-wp|VPC-wp|

■RouteTable

|Name|送信先(ターゲット)|サブネット関連付け|
|:----------|:----------|:----------|
|RouteTable-wp-0|10.0.0.0/16(local)|Subnet-Private-wp-A、Subnet-Private-wp-C|
|RouteTable-wp-1|10.0.0.0/16(local)、0.0.0.0/0(InternetGateway-wpのID)|Subnet-Public-wp-A、Subnet-Public-wp-C|

■SecurityGroup-elb-wp

|タイプ(ポート)|送信元|
|:----------|:----------|
|HTTP(80)|自身のIP|

■SecurityGroup-Server-wp
今回は外部への公開用ではないので、自身のIP(+ロードバランサー)のみにしておく。

|タイプ(ポート)|送信元|
|:----------|:----------|
|HTTP(80)|自身のIP|
|HTTP(80)|SecurityGroup-elb-wpのID|
|SSH(22)|自身のIP|

■SecurityGroup-DB-wp

|タイプ(ポート)|送信元|
|:----------|:----------|
|MYSQL/Aurora(3306)|SecurityGroup-Server-wpのID|

#RDSとEC2
■DBサブネットグループ

|Name|追加|
|:----------|:----------|
|dbsubnetgroup-wp|Subnet-Private-wp-A、Subnet-Private-wp-C|

■RDSインスタンス

|項目|設定|
|:----------|:----------|
|エンジン|MySQL 5.6.27|
|ラインセンスモデル|General Public License|
|インスタンスクラス|db.t2.micro|
|マルチ AZ|いいえ|
|ストレージタイプ|汎用（SSD）|
|ストレージ|5GB|
|識別子|wp-db|
|マスターユーザ|root|
|VPC|VPC-wp|
|サブネットグループ|dbsubnetgroup-wp|
|パブリックアクセス|いいえ|
|アベイラビリティーゾーン|ap-northeast-1a|
|セキュリティグループ|SecurityGroup-DB-wp|
|データベースの名前|空白(後で作成します)|
|バックアップの保存期間|0日|
|自動バックアップ|無効|
|拡張モニタリング|いいえ|
|マイナーバージョン自動アップグレード|はい|
|メンテナンスウィンドウ|指定なし|

■EC2インスタンス

|項目|設定|
|:----------|:----------|
|AMI|Amazon Linux AMI|
|インスタンスタイプ|t2.micro|
|VPC|VPC-wp|
|サブネット|Subnet-Public-wp-A|
|自動割り当てパブリック IP|サブネット設定を使用（有効）|
|テナンシー|共有|
|ストレージサイズ|8GB|
|ストレージタイプ|汎用SSD|
|Name|Server-wp-A|
|セキュリティグループ|SecurityGroup-Server-wp|

#ミドルウェアのセットアップ

ログインしてrootでコマンド
history結果とMySQLのコマンド

```
    1  yum update
    2  yum install php56 php56-mysqlnd php56-gd php56-mbstring mysql56
    3  wget -O /tmp/wordpress-4.6-ja.tar.gz https://ja.wordpress.org/wordpress-4.6-ja.tar.gz
    4  tar zxf /tmp/wordpress-4.6-ja.tar.gz -C /opt
    5  ln -s /opt/wordpress /var/www/html/
    6  chown -R apache:apache /opt/wordpress
    7  chkconfig httpd on
    8  service httpd start
    9  mysql -u root -p -h XXXX.XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com

mysql> create user 'wordpress-user'@'%' identified by 'wordpress';
Query OK, 0 rows affected (0.00 sec)

mysql> create database `wordpress`;
Query OK, 1 row affected (0.00 sec)

mysql> grant all privileges on `wordpress`.* to "wordpress-user"@"%";
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
```

ブラウザから下記へアクセスし、WordPressのセットアップ。

```
http://EC2インスタンスのパブリックDNS/wordpress/wp-admin
```

#ELB

##ロードバランサーを利用した冗長化

|項目|設定|
|:----------|:----------|
|種類|標準|
|ロードバランサー名|elb-wp|
|VPC|VPC-wp|
|内部向けロードバランサーの作成|オフ|
|ロードバランサーのプロトコル/ポート|HTTP/80|
|インスタンスののプロトコル/ポート|HTTP/80|
|サブネット選択|Subnet-Public-wp-A、Subnet-Public-wp-C|
|セキュリティグループ|セキュリティグループ|
|ping プロトコル/ポート|TCP/80|
|インスタンスの追加|Server-wp-A|
|Name|elb-wp|

・/var/log/httpd/access_logに408がめっちゃ出ていたのでググッたら解決策ありました。
ELBの「説明タブ-属性-アイドルタイムアウト」を30秒に設定

1.WordPressの設定から、「WordPress アドレス (URL)」と「サイトアドレス (URL)」の
　EC2のDNSをELBのDNSへ書き換え。
 (URLを間違えた場合の参考になった記事[[WordPress + MySQL] DBからサイトURLを変更](http://qiita.com/hishigataBOZE/items/bdd6009d3bfc1c7d313b))
2.Server-wp-AのAMI作成して、Subnet-Public-wp-CにServer-wp-Cを作成。
　ELBにServer-wp-Cをぶら下げ。
3.今後はELB経由でのアクセスになるため、EC2インスタンスへの直接接続は拒否しておきます。
SecurityGroup-Server-wp

|タイプ(ポート)|送信元|
|:----------|:----------|
|HTTP(80)|SecurityGroup-elb-wpのID|
|SSH(22)|自身のIP|

ちょっと時間を置いてアクセスアクセス。
それぞれの/var/log/httpd/access_logを眺めていると、アクセスが振り分けられているのがわかる。

##HTTPS
ここからは独り言が多くなってきます。

###自己証明書作成とELBへアップロード

■作成

```
   14  openssl genrsa -out ./server.key 2048
   15  openssl req -new -key ./server.key -out ./server.csr

Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Okinawa
Locality Name (eg, city) [Default City]:Okinawa
Organization Name (eg, company) [Default Company Ltd]:YukiWhite
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:elb-wp-XXXXXXXX.ap-northeast-1.elb.amazonaws.com
Email Address []:

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

   16  openssl x509 -in server.csr -days 365 -req -signkey server.key -out server.crt
```

■アップロード
ロードバランサーの「リスナータブ-編集」から
「AWS Identity and Access Management (IAM) に、新規のSSL 証明書をアップロードする」をチェック

|ロードバランサーのプロトコル|ロードバランサーのポート|インスタンスのプロトコル|インスタンスのポート|
|:-----------------|:-----------------|:-----------------|:-----------------|
|HTTPS|443|HTTP|80|

さらに「SSL 証明書-変更」から下記を設定し保存

|証明書の名前|プライベートキー|パブリックキー証明書|証明書チェーン|
|:-----------------|:-----------------|:-----------------|:-----------------|
|MyServerCert|server.keyの内容をペースト|server.crtの内容をペースト|なし|

すると『リスナーの更新が失敗しました。』
ググッてみると、AWS CLIから実施したら上手くいくみたいなこと書いてあったけど・・・めんどくさい。
いけないことないでしょ～と、いろいろ試してたら。
EC2→ELBでHTTPSの通信ができるようになると上手くいくようです。
SecurityGroup-elb-wpを編集。

|タイプ(ポート)|送信元|
|:----------|:----------|
|HTTPS(443)|SecurityGroup-Server-wpのID|
|HTTP(443)|自身のIP|
|HTTP(80)|自身のIP|

###WordPress側の設定
Server-wp-AとServer-wp-C共に
/opt/wordpress/wp-config.phpに下記を追記

```
define('FORCE_SSL_ADMIN', true);

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';
```

HTTPSでアクセスすると自己証明書のため、警告はでますがアクセスできるようになります。

#おまけ
・ステッキーセッションの利用
セッション情報の維持のため、「説明タブ-ポート構成 -維持設定の編集」
ロードバランサーによって生成された Cookie の維持を有効化にチェックし、
1800秒ぐらいにしときます。

***

間違い、改善点等ありましたらご指摘お願いします。