CloudFormation入門 #1 「EC2インスタンスの作成」


CloudFormationは、JSONで記述された情報をもとに、AWS上にEC2やS3といったリソースを生成するための仕組みです。

* AWSのインフラ情報をテンプレート（テキストファイル）としてバージョン管理できる
* テンプレートを再読み込みすることで、インフラを更新できる

などといったメリットがあります。しかしこのテンプレートが非常に複雑で、サンプルや自動生成されたものを見て利用を断念してしまうほどです。そこで、本当に０からこのテンプレートを作成して、なんとかCloudFormationの理解を深めていければと思います。

# 新規テンプレート作成

**以下しばらくの手順では、AWSへの料金は発生しません**

まずは最もシンプルなテンプレートを作成してみましょう。テンプレートは、どのようなインフラを構築できるのかが記載されています。テンプレートの基本的な構造は、以下のドキュメントに記載されています。

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-anatomy.html

これによると、テンプレートは大きく次のセクションより構成されています。

* Format Version（任意）
* Description（任意）
* Metadata（任意）
* Parameters（任意）
* Mappings（任意）
* Condition（任意）
* Resources（必須）
* Outputs（任意）

この中で必須なのは、Resourcesだけのようです。そこでこのResourcesについてさらに詳しく調べてみます。

## Resources

Resourceは、EC2やS3などAWSのリソースを定義するセクションです。詳細は以下のドキュメントに記載されています。

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html

リソースの定義は以下のようになります。

```json:リソース定義
"Resources" : {
    "Logical ID" : {
        "Type" : "Resource type",
        "Properties" : {
            Set of properties
        }
    }
}
```

`Logical ID`にはリソースを識別する名前をつけます。
`Resource type`と`Properties`に定義できるリソースは、ドキュメントに記載されています。ここでは、AWSといえばEC2インスタンスということで、EC2インスタンスを定義しようと思います。EC2インスタンスのテンプレートは以下のドキュメントに記載されています。

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html

ドキュメントにはさまざな情報が書かれています。ただし、この中で必須なのは、`ImageId`のみです。これははEC2を生成する時に選択するマシンイメージに付けられたIDです。ここでは無料で使えるAmazon Linux AMIのIDを利用します。

![AMI.png](https://qiita-image-store.s3.amazonaws.com/0/75307/2525598a-60da-53ac-b2ab-fe682352e4f7.png "AMI.png")

このテンプレートで使われるEC2インスタンスのタイプは"m1.small"となりますが、今回はテストなのでもう少し安い"t2.micro"を使うようにしましょう。インスタンスのタイプは`InstanceType"で指定することができます。


## 最終的なテンプレートファイル

ここまでの内容を踏まえた最もシンプルなCloudFormation用のテンプレートファイルです。ローカルマシンの任意のディレクトリに保存してください。

```json:cloudformation-study.template
{
  "Resources" : {
    "MyEC2Instance": {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "ami-383c1956",
        "InstanceType" : "t2.micro"
      }
    }
  }
}
```

# スタック作成

スタックとは、実際にインフラを構築するための情報です。テンプレートとスタックの関係は、オブジェクト指向におけるクラスとインスタンスの関係に似ています。つまり、あるテンプレートを元にして、幾つものスタックが生成されます。特によく使われるようなテンプレートは、パブリックテンプレートとしてインターネット上に公開されているものもあります。

スタックは、AWSのコンソールを使ってWeb上から、あるいはAWS CLIでコマンドラインから、いずれかの方法で生成します。ここではコンソールを使ってWeb上から生成してみます。

コンソール上から"サービス - CloudFormation"を選択します。表示された画面から"Create Stack"をクリックしてスタックの生成を開始します。

![stack01.png](https://qiita-image-store.s3.amazonaws.com/0/75307/41917337-96fd-935f-f84c-72e83a9d7ec9.png "stack01.png")

"Upload a template to Amazon S3"を選択して、ローカルマシンに保存したテンプレートファイルをアップロードして、"Next"をクリックします。

![stack02.png](https://qiita-image-store.s3.amazonaws.com/0/75307/a6e97f9a-91eb-a565-7913-419a79519003.png "stack02.png")

このスタックに名前をつけます。ここでは"MyStack"としています。名前をつけたら"Next"をクリックします。

![stack03.png](https://qiita-image-store.s3.amazonaws.com/0/75307/fbdfccc5-5ffa-8268-f899-cf4fd469e25c.png "stack03.png")

生成されるリソースにTagをつけたり追加の情報を設定することができます。ここでは何も指定せずに"Next"をクリックします。

![stack04.png](https://qiita-image-store.s3.amazonaws.com/0/75307/cf613e8a-c6fd-f237-84e4-19944b572580.png "stack04.png")

これでスタックを元にリソースを実際に生成する準備が出来上がりました。上部にある"Cost"リンクをクリックすると、このスタックにより生成されるリソースの見積もりを確認することができます。この記事を書いた時には、１時間当たり2.41円ほどかかるという結果になりました。

## リソースの生成

**注意：ここから先の手順は、AWSへの料金が発生します！**

それでは実際にリソースを生成してみましょう。"Create"をクリックしてください。スタックに基づいたリソースの生成が行われます。

![stack05.png](https://qiita-image-store.s3.amazonaws.com/0/75307/b7302d99-54c7-b826-1796-c6398363c10d.png "stack05.png")

画面上部には、スタックの最新の作業状況が表示されます。Statusの欄には作業中の間は"CREATE_IN_PROGRESS"が、作業が終了すると"CREATE_COMPLETE"が表示されます。
画面下部のEvensタブには、スタックの作業が一つ一つログとして時系列に表示されます。下の方が古い作業となります。

## EC2インスタンスの確認

AWSのコンソールからEC2を開くと、インスタンスが生成されていることを確認できます。おめでとうございました。これでCloudFormationによるリソース生成が行えました。

なお、このEC2にはSSHでログインするためのセキュリティーグループやSSHの鍵情報などが存在していませんので、外部からSSHでログインすることはできません。料金がかかる以外にまったく役に立たないEC2インスタンスです :-P

# スタックの削除

**注意：この作業を行わないとずっと料金がかかり続けます**

最後にスタックを削除して、生成したインスタンスを破棄しましょう。コンソール画面から"サービス - CloudFormation"を選択します。すると今回作成した"MyStack"スタックが表示されています。チェックを入れて、"Actions - Delete Stack"をクリックします。

![stack06.png](https://qiita-image-store.s3.amazonaws.com/0/75307/c769fedc-b73f-f0b4-86b4-900958d5f6f4.png "stack06.png")

画面下部のEventsタブに、スタックの削除作業の進捗が表示されます。削除が終了すると、Stackが０個になったのでCloudFormationのスタート画面が表示されます。コンソールからEC2を開き、EC2インスタンスが破棄されている(＝インスタンスの状態がterminatedになっている）ことを確認してください。

## S3上のテンプレートの削除

ローカルからアップロードされたテンプレートは、自動的にS3上に保存されます。わずかですがS3の使用料がかかります。気になる方はS3上のファイルも消しましょう。

# まとめ

もっとも短いテンプレートファイルを使って、CloudFormationでEC2インスタンスを生成する方法について学びました。