[CloudFormationハンズオン] VPC環境を丸ごとコピー

社内勉強会のネタです。

EC2+RDSをVPC上にCloudFormationで作成するハンズオンです。
いきなりCloudformationのテンプレートは作成するのは難しいと思うので、一度手動で環境を作成してからCloudFormerというツールを使ってテンプレートをエクスポートし、環境を複製するという流れで進めます。

## 複製元環境の作成

マネジメントコンソールから作成します。

アプリは同僚の作成した以下を利用させてもらいます。
https://github.com/khwada/springboot_web_batch_sample

1. VPCを作成
    * DNS解決：はい
    * DNSホスト名：はい
2. サブネットを2つ作成。AZは分けて作成してください
3. 紐づくルートテーブルにProjectタグを設定
4. 紐づくネットワークACLにProjectタグを設定
5. EC2用のセキュリティグループを作成
    * 22,8080ポートを自分のIPに対して公開
6. RDS用のセキュリティグループを作成
    * MySQL想定のため、3306ポートを5で作成したEC2用セキュリティグループに対して公開
    * 自分のIPに対しても3306ポートを公開しておく（何かあった時の直接接続用）
7. インターネットゲートウェイを作成して、VPCにアタッチ
8. ルートテーブルの設定で0.0.0.0/0への送信は7で作成したインターネットゲートウェイに向くように設定を追加
9. ルートテーブルの設定で2で作成したサブネット2つを関連付け
10. RDS mysql5.6用のパラメータグループを作成。
    * character_set_client: utf8
    * character_set_connection: utf8
    * character_set_database: utf8
    * character_set_results: utf8
    * character_set_server: utf-8
    * skip-character-set-client-handshake: 1
11. RDS(mysql)を作成する。
    * DB名はtestdb
    * パラメータグループは9で作成したもの
    * VPCは1で作成したもの
    * セキュリティグループは6で作成したもの
    * パブリックアクセス可能「はい」
    * DBサブネットグループも作成する
12. EC2を立ち上げる
    * AmazonLinuxを選択
    * VPCは1で作成したもの
    * 自動割り当てパブリックIPは有効化
    * セキュリティグループは5で作成したもの
    * ロールはなしでOK

これでインフラ部分は用意できました。

この環境でアプリが動くかどうか
https://github.com/khwada/springboot_web_batch_sample#アプリ側の接続先設定
や
https://github.com/khwada/springboot_web_batch_sample#ec2へのミドルウェアインストール
以降の手順を実施して、検証してみましょう。

簡単に補足しておくと
```web/src/main/resources/application-aws.yml```の設定ファイルに今回作成したRDSの接続情報を追記して以下の手順でビルド

```
gradlew.bat :web:build
```

できたファイルをEC2にアップロードして実行

```
java -jar -Dspring.profiles.active=aws web.jar &
```

## CloudFormerの立ち上げ

ここからやっとCloudFormationのテンプレート作成に入るのですが、そのためのツール「CloudFormer」もCloudFormationを使って立ち上げます。

1. CloudFormationのメニューを開き、新しいスタックの作成を選択
2. サンプルテンプレートの選択から「CloudFormer」を選択
3. 名前、ID,PWを設定して作成

あとは全て終わるのを待つだけです。

## CloudFormerでテンプレートを作成する

CloudFormationの出力タブにURLが出てくるため、ブラウザでアクセスして利用します。
Basic認証がかかっているので先ほど設定したID/PWを入力します。

1. リージョンを選択してCreateTemplate
2. Intro：Descriptionを記入するくらい
3. DNS：なし
4. VPC：デフォルトじゃない先ほど作ったVPCを選びましょう（IDしか出ないのは不親切ですが間違えないように）
5. VPC Network：4で選んだVPCに属するサブネットやインターネットゲートウェイはチェックされているかと思いますが、確認を。
6. VPC Security：こちらも4で選んだVPCに属するネットワークACLやルートテーブルの確認を。
7. Network：なし
8. Managed Service：なし
9. Managed Config：なし
10. Compute：作成したEC2インスタンスを選択
11. Storage：作成したRDSインスタンスを選択
12. Storage Config：11で選んだRDSに紐づくDBサブネットグループやパラメータグループの確認をするだけ。
13. AppService：なし
14. Security：作成したセキュリティグループを選択
15. Operational：なし
16. Summaryで確認して、S3に保存する

これで既存の環境からテンプレートが作成できました。
ですが、これをそのまま使えるわけではないので編集していくことになります。

### RDSの部分

以下が変更されていましたので先ほどと同じ設定に変更します。

* MasterUserPassword
* DBName

RDSのタグはどういう理由で作られたタグなのかよくわからないですが、エラーになったので削除しておきます。

### 最終的なテンプレート

参考まで。
https://gist.github.com/nyasba/6f4bc23d1735facf5a2b12cf3c55ddfd

## 作ったリソースをすべて削除

CloudFormerのスタックから、RDS,EC2,VPC,セキュリティグループまで。
EC2のキーペアだけは残しておいてください。

## Cloudformationでリソースを再作成！

templateをアップロードしてスタックを作成するだけです。
＃インスタンスしかできてませんので、アプリは自分で立ち上げてください m(_ _)m


## こんなこともできる

今回の例では同じ環境を再作成をしただけです。開発環境をもう1環境作りたいという用途では使えますが、templateの中でResourceしか使っていないため、まだまだできることは多いです。
http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-anatomy.html

今回はEC2を立ち上げるだけでアプリのデプロイはできていませんが、EC2へのデプロイもUserDataやMetaDataを使うと自動化もできます。
http://dev.classmethod.jp/cloud/aws/cfn-init/