先月19日に、AWS体験ハンズオンに初めて参加してきました。
AWS Summit Tokyo 2015 で、「AWS 認定ソリューションアーキテクト – アソシエイト」を受験予定だったこともあり、その予習として実際に手を動かしながらやってみようと思ったからです。受検結果はまた別途。
結論としては、このハンズオンは私にとって非常に有益でした。
ハンズオンのスピードがすごく速くて、着いていくのにギリギリでしたが。。
また、ハンズオンの前にこちらの本をちょうど読み終えていったのですが、この本がなければ、内容は半分くらいしか理解できなかったかもしれません。オススメの本です。

Amazon Web Services クラウドデザインパターン実装ガイド 改訂版
- 作者: 大澤文孝,アマゾンデータサービスジャパン玉川憲,アマゾンデータサービスジャパン片山暁雄,アイレット鈴木宏康,日経SYSTEMS
- 出版社/メーカー: 日経BP社
- 発売日: 2015/03/05
- メディア: 単行本
- この商品を含むブログ (2件) を見る

Amazon Web Services クラウドデザインパターン 実装ガイド 改訂版 日経BP Next ICT選書
- 作者: アマゾンデータサービスジャパン玉川憲,片山暁雄,アイレット鈴木宏康
- 出版社/メーカー: 日経BP社
- 発売日: 2015/04/01
- メディア: Kindle版
- この商品を含むブログを見る
説明資料(英語コンソール版)
https://aws-ref.s3.amazonaws.com/handson/building_3tier_on_vpc_ver9.2.pdf
説明資料(日本語コンソール版)
https://aws-ref.s3.amazonaws.com/handson/building_3tier_on_vpc_ver9.2_ja.pdf
最終的には、↓ のような構成のシステムを構築していきます。

やっていること
- VPC とサブネットを活用
- パブリックなサブネットとプライベートなサブネットを明確に分離
- 別アベイラビリティゾーンにも同様に、パブリックなサブネットとプライベートなサブネットを配置
- Elastic Load Balancer による Webサーバの冗長化
- Multi-Server, Multi-Datacenterパターン
- RDS をインターネットに直接接続しないプライベートサブネットに配置してセキュリティを向上
- RDS を別アベイラビリティゾーンに レプリケーションさせることで可用性を向上
- DB Replicationパターン
やっていないこと
- IAM によるセキュリティ管理
- Route53 による独自ドメイン管理
- AutoScaling によるクラスターの伸縮
- CloudWatch による監視
- SSL による通信暗号化
Phase 0:VPC の作成
AWSクラウド上に、VPC とサブネットを作成します。
【 完成形となる構成図 】

最終的なサブネットはこのようになります。
| # | AZ | インターネットに接続可能? | サブネット名 | CIDR |
| 1 | 1a | パブリック | T1-Public #1 | 10.0.0.0/24 |
| 2 | 1c | パブリック | T1-Public #2 | 10.0.1.0/24 |
| 3 | 1a | プライベート | T1-Private #1 | 10.0.2.0/24 |
| 4 | 1c | プライベート | T1-Private #2 | 10.0.3.0/24 |
まずはじめに、リージョンは「Tokyo」にします。

「Networking」から、「VPC」を選択します。

VPC作成ウィザードを開始します。

「VPC with a Single Public Subnet」を選択し、VPCを作成しつつ、パブリックなサブネットも作成していきます。

| IP CIDR block | 10.0.0.0/16 | |
| VPC name | 任意の名前。ここでは、「T1」 | |
| Public subnet | 10.0.0.0/24 | 251個のIPが確保できる |
| Availability Zone | ap-northeast-1a | 1a側を指定 |
| Subnet name | T1-Public #1 |
を入力し、「Create VPC」をクリックします。

VPCが作成されました。
(VPCが 2つ表示されていますが、もう1つは、アカウント作成時のデフォルトVPC です。)

ここで、「Filter by VPC」を使ってフィルタリングすれば、指定したVPC に関連したリソースしか表示されなくなるので、非常に便利です。

作成されたサブネットを確認します。
「Route Table」タブをクリックすることで、ルートテーブルを確認することができます。なお、「VPC with a Single Public Subnet」ウィザードを使って初めに作成されたこのサブネットだけ、IGW に接続できるようになっています。

あと3つのサブネットを追加していきます。


このようにして、全部で4つのサブネットを用意します。
| # | AZ | インターネットに接続可能? | サブネット名 | CIDR |
| 1 | 1a | パブリック | T1-Public #1 | 10.0.0.0/24 |
| 2 | 1c | パブリック | T1-Public #2 | 10.0.1.0/24 |
| 3 | 1a | プライベート | T1-Private #1 | 10.0.2.0/24 |
| 4 | 1c | プライベート | T1-Private #2 | 10.0.3.0/24 |

2番目のサブネットがインターネットに接続できない状態になっているので、ルートテーブルを現在選択されているものから変更します。



Phase 1:EC2 の作成
WordPress を最小構成(Web + DB 1台構成)で構築して、インスタンスに Elastic IP を付与します。
【 完成形となる構成図 】





| Network | T1 | 作成した VPC を選択 |
| Subnet | T1-Public #1 | |
| Auto-assign Public IP | Enable | Public IP を自動的に付与。今回は後で Elastic IP を付与するので、結局破棄される |
と入力して、「Next」をクリック。

ストレージはそのまま。

「Name」タグは、適当に「T1-Web #1」と入力。

セキュリティグループを新たに作成します。セキュリティグループ名は適当に「T1-Web」などとします。
また、セキュリティグループ作成時に、22番と80番ポートを許可します。
| Type | Protocol | Port Range | Source |
| SSH | TCP | 22 | MyIP |
| HTTP | TCP | 80 | MyIP |


キーペアを新たに作成して、ダウンロードしておきます。

「Launch Instance」をクリックして、インスタンスを起動します。

「running」になりました。

次に、作成したインスタンスに、Elastic IP を付与していきます。






続いて、作成したインスタンスに SSHで乗り込んで、WordPress をインストールしていきます。
$ chmod 600 ~/Downloads/T1-key.pem $ ssh -i ~/Downloads/T1-key.pem ec2-user@52.68.117.22
以降、root で操作します。
$ sudo -i
MySQL をインストールします。
# yum install -y mysql-server
# service mysqld start
# chkconfig --level 345 mysqld on
# mysqladmin -u root -h localhost password 'Password1'
# mysql -p
(Enter password: Password1)
mysql> CREATE DATABASE wordpress;
mysql> GRANT ALL ON wordpress.* to admin@localhost;
mysql> FLUSH PRIVILEGES;
mysql> SET PASSWORD FOR admin@localhost=password('Password1');
mysql> exit
次に、Nginx + PHP をインストールします。
# yum install -y nginx # yum install -y php php-fpm php-mbstring php-mysql # service nginx start # service php-fpm start # chkconfig --level 345 nginx on # chkconfig --level 345 php-fpm on
Nginx で PHP を実行するように設定します。
# cat << EOF > /etc/nginx/conf.d/wordpres.conf
server {
listen 80;
location / {
root /var/www/html;
index index.php index.html;
}
location ~ \.php$ {
root /var/www/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
include fastcgi_params;
}
}
EOF
WordPress をインストールします。
# service nginx restart # wget http://wordpress.org/latest.tar.gz # tar xzvf latest.tar.gz # mv wordpress/* /var/www/html/ # chown -R apache:apache /var/www/html/
ブラウザで、Elastic IP
http://52.68.117.22/
にアクセスします。


MySQL ユーザ「admin」のパスワードは「Password1」です。


WordPress管理者「admin」のパスワードは「Password2」としておきます。

WordPress のインストールが完了しました。

Phase 2:RDS の作成
WordPress を Web + DB の 2台構成で構築します。
【 完成形となる構成図 】

まず先に、DB用のセキュリティグループを作成しておきます。

| セキュリティグループ名 | T1-DB(任意) |
| VPC | T1 |
とし、3306番ポートをセキュリティグループ「T1-Web」に対して解放します。

RDS の管理ページを開きます。

まず、DBサブネットグループを作成します。

DBサブネットグループ名、および VPC は以下のように設定し、
| Name | t1-db(任意) | 英大文字は作成後に小文字に変換される? |
| VPC ID | T1 |
1a および 1c、それぞれのアベイラビリティゾーンから、プライベートなサブネットを追加します。


「Create」ボタンをクリック。

DBサブネットグループが作成されました。

続いて、RDS インスタンスを作成していきます。

MySQL を選択します。

非Multi-AZ 構成とします。

検証用なので、最小インスタンスタイプを選択します。
| DB Instance Class | db.t2.micro |
| Multi-AZ Deployment | No |
RDSインスタンスの管理者のユーザ名とパスワードを設定します。
| DB Instance Idetifier | t1-wp-db | ホスト名の一部になります |
| Master Username | admin | |
| Master Password | Password1 |

ネットワークの設定をします。
| VPC | T1 |
| Subnet Group | t1-db |
| Publicly Accessible | No |
| Availability Zone | ap-northeast-1a |
| VPC Security Group(s) | T1-DB |
データベース名(Database Name)は、「wordpress」とします。
なお、RDS 1インスタンスにつき、データベースは1つとなります。
検証用なので、バックアップは取らない設定にしておきます。「Backup Retention Period」を「0 days」にすれば OK です。

RDSインスタンスの起動には、5分くらいかかります。
起動したら、RDSインスタンスのエンドポイントを確認しておきます。

Webサーバの EC2インスタンスから、RDSインスタンスに接続できることを確認します。
# mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress (Enter password: Password1) mysql> show tables; Empty set (0.00 sec) mysql> exit
「wordpress」というデータベースは存在しますが、当然ながらテーブルはまだ一つもありません。
次に、RDSにデータ移行をするために、EC2上の MySQLレコードをエクスポートします。
# service nginx stop # mysqldump -u root -p wordpress > wordpress.sql (Enter password: Password1) # service nginx start
EC2上の mysqld はもう使わないので、stop しておきます。
# service mysqld stop # chkconfig --level 345 mysqld off
エクスポートしたデータを、RDS にインポートします。
# mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress < wordpress.sql (Enter password: Password1)
RDSに正常にインポートできたか、チェックします。
$ mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress (Enter password: Password1) mysql> show tables; +-----------------------+ | Tables_in_wordpress | +-----------------------+ | wp_commentmeta | | wp_comments | | wp_links | | wp_options | | wp_postmeta | | wp_posts | | wp_term_relationships | | wp_term_taxonomy | | wp_terms | | wp_usermeta | | wp_users | +-----------------------+ 11 rows in set (0.00 sec) mysql> exit
ここから少し WordPressのテクニカルな部分になりますが、WordPress の DB接続設定を初期化するために、WordPress の設定ファイルを一旦待避します。
# mv /var/www/html/wp-config.php /var/www/html/wp-config_bk.php
待避させてから、
http://52.68.117.22/
に再びアクセスして、WordPress を再インストールしていきます。
「データベースのホスト名」に、RDSインスタンスのエンドポイントを設定します。


WordPress の再インストールが完了しました。
Phase 3:ELB の作成
LB + Web × 2 + DB のサーバ 3台構成を構築します。
【 完成形となる構成図 】

はじめに、Webサーバの AMI を作成していきます。



Status が「available」になるのを待ちます。

作成した AMI から、2台目の Webサーバインスタンスを起動します。


1c 側のアベイラビリティゾーンで起動するように、ネットワーク、サブネットを指定します。



1台目の Webサーバと同じセキュリティグループを選択します。


キーペアも同じものを選択します。

2台のインスタンスが起動しました。

続いて、ELB を作成していきます。

| Load Balancer name | T1-LB |
| Create LB Inside | VPC を選択 |
を設定し、Selected Subnets で管理対象とするサブネットを選択します。

新たにセキュリティグループを作成します。


ヘルスチェックの設定を調整します。

管理する EC2インスタンスを選択します。

タグは何も設定せずそのまま。



ELB は作成されましたが、インスタンスのヘルスチェックは「OutOfService」のままです。これは、インスタンスのセキュリティグループが「MyIP」しか許可していない状態になっているからです。

そこで、インスタンスのセキュリティグループの「HTTP」を、ELB からアクセスできるように(ELB のみをアクセス許可するように)設定変更していきます。

HTTP の Source に「T1-LB」を設定します。


ELB のヘルスチェックが、どちらも「InService」になりました。

疎通が完了したら、ELB の DNS名をチェックしておきます。

WordPress の HTML内のリンク先ホスト名がインストール時の EIP になっているので、それを ELB のホスト名に書き換える必要があります。
そこで、以下のコマンドをどちらかの Webサーバ上で実行します。
# mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress (Enter password: Password1) mysql> update wp_options set option_value='T1-LB-53959373.ap-northeast-1.elb.amazonaws.com' where option_name='siteurl' or option_name='home';
変更処理が完了したら、ELB の DNS名でアクセスします。
http://T1-LB-53959373.ap-northeast-1.elb.amazonaws.com/

アクセスできました。
Phase 4:RDS のレプリケーション
最後に、LB + Web × 2 + DB × 2 のサーバ4台構成を構築していきます。
【 完成形となる構成図 】

RDS の管理ページから、RDS インスタンスの設定を変更します。

| Multi-AZ Deployment | Yes |
| Apply Immediately | チェックを付ける |
とするだけで、すぐに設定変更できます。


設定変更には少し時間(5分くらい)がかかります。容量に応じて必要な時間が変わってくるそうです。


Status が「modifying」から「available」になり、Multi-AZ が「Yes」に変われば、設定変更が完了です。
なお、マスターに障害が発生した場合の RDSのフェイルオーバーは 1〜3分で完了するそうです。また、ディスクのブロックレベルのレプリケーションができる設計になっているので、データのロスはほぼ無いとのこと。