ちょっと話題の記事

CloudFormation超入門

2016.05.28

AWSでインスタンスやVPC環境を作成するとき、コンソール上で作ろうとすると、似たような環境を何度も作ったり、大量に作ったりする時、非常に手間になってしまいます。

しかし、AWSにはそんな手間を一気に解消してくれるCloudFormaionという便利サービスがあります。 今回は、初めての人向けの超入門ということで「CloudFormationってどないやねん」という方向けに、まずは使ってみようというコンセプトで書いてみようと思います。

CloudFormation って何?

誤解を恐れつつ一言で言えば、「自動的にAWS上で作りたいものを作ってくれる」サービスです。というか、そういう環境を用意してくれるサービスです。

少し補足すると、自分が作りたい環境を定義したファイルを作って、その定義書を読み込んで自動で環境を作ってくれます。 今回は超入門ということで詳細な説明は割愛したいと思います。

今回のお題

今回は下記のような環境をCloudFormationで作ってみます。 インスタンスとかなくて寂しい気がしますが、作るときはネットワーク環境用、パブリックサブネット用と分けて作っていくと、後からも運用しやすいと思います。

構成図

説明

図のままですが、以下のような内容の環境を作っていきます。 超入門ということでできるだけシンプルな構成を考えてみました。

  • VPC(10.0.0.0/16)を1つ作ります。
  • VPC名は「Nyumon-VPC」とします。
  • そのサブネット(10.0.1.0/24)を1つ作ります。
  • サブネット名は「Nyumon-Subnet」とします。
  • インスタンスがインターネットにアクセスできるようにインターネットゲートウェイを作ります。
  • ゲートウェイ名は「Nyumon-IGW」とします。
  • インターネットゲートウェイへのルーティングテーブルを作ります。
  • ルーティングテーブル名は「Nyumon-RT」とします。

作業の流れ

大まかな流れは次の通りです。

  1. 環境を定義した「テンプレート」というファイルを作成する。
  2. テンプレートファイルをCloudFormationに読み込ませる。

手順としては以上です。 CloudFormationは、テンプレートを作成することが全てです。 今回もテンプレートの内容の意味を理解し作り方が分かるようになることを目標にしたいと思います。

テンプレートの作成

それでは早速テンプレートを作成していきます。 まずは、下記の内容のファイルを準備します。

{
"AWSTemplateFormatVersion" : "2010-09-09",
"Resources" : {

(ここに定義を書いていきます)

}
}

AWSTemplateFormatVersionResourcesの部分は固定だと思ってください。 文字通り上記のResourcesの中(ここに〜)に作成したいAWS環境を定義していきます。

すでにお気づきかと思いますが、テンプレートはjson形式です。 コメントが書けなかったりしますが、AWSではよく使われるフォーマットです。

今回のテンプレート

先ほどの説明のところで書いた内容をそのまま書き起こすと以下のような感じになります。

{
"AWSTemplateFormatVersion" : "2010-09-09",
"Resources" : {
"MyVPC" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16",
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"InstanceTenancy" : "default",
"Tags" : [ {"Key" : "Name", "Value" : "Nyumon-VPC"} ]
}
},
"MyIGW" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [ {"Key" : "Name", "Value" : "Nyumon-IGW"}]
}
},
"AttachGateway" : {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"InternetGatewayId" : { "Ref" : "MyIGW" }
}
},
"MySubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"CidrBlock" : "10.0.0.0/20",
"AvailabilityZone" : "ap-northeast-1a",
"Tags" : [ { "Key" : "Name", "Value" : "Nyumon-Subnet" } ]
}
},
"MyRouteTable" : {
"Type" : "AWS::EC2::RouteTable",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"Tags" : [ { "Key" : "Name", "Value" : "Nyumon-RT" } ]
}
},
"SubnetAttache" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"RouteTableId" : { "Ref" : "MyRouteTable" },
"SubnetId" : { "Ref" : "MySubnet" }
}
},
"MyRoute" : {
"Type" : "AWS::EC2::Route",
"Properties" : {
"RouteTableId" : { "Ref" : "MyRouteTable" },
"DestinationCidrBlock" : "0.0.0.0/0",
"GatewayId" : { "Ref" : "MyIGW" }
}
}
}
}

いきなりいっぱい出てきたと思われるかもしれませんし、「MyVPC」とか「MyIGW」「AttachGateway」といった初出のキーワードが出ていますが、1つ1つの塊を単に並べているだけなので、各項目の意味さえ分かってしまえばどうってことありません。

ちなみに先ほどの「MyVPC」などのキーワードは、論理IDと呼ばれるもので、テンプレート内の他のリソースを参照するために利用します。 論理ID?、リソース?・・なんじゃそりゃ、となるかもしれませんが、一番上の「MyVPC」を例として説明をしていきたいと思います。

意味の説明

「MyVPC」の箇所を改めて抜粋します。

"MyVPC" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16",
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"InstanceTenancy" : "default",
"Tags" : [ {"Key" : "Name", "Value" : "Nyumon-VPC"} ]
}
},

リソースとリソースタイプ

上記のような定義の一塊をリソースと呼びます。

リソースはリソースタイプ毎に作ります。 リソースタイプとは「何を作るか」の種類の指定の事で「Type」で指定します。

指定できるリソースタイプの種類は公式ドキュメントのリファレンスに詳しく書かれています。 コツが分かれば、リファレンスの内容をコピペ、修正しながら自由に書けるようになると思います。

リソースプロパティ

具体的な設定値は次の「Properties」で指定します。 「Properties」の要素の種類や数は、リソースタイプによって異なります。 上記の場合だと、「10.0.0.0/16のCIDRでVPCを作り、作ったVPCのNameタグはNyumon-VPCにする」という内容がPropertiesで指定されています。

論理ID

最初の「MyVPC」がこのリソースのID(論理ID)になります。これはリソースの名前のことで、任意のもので構いません。 (ただし、利用できるのは英数字(A-Za-z0-9)のみで、テンプレート内で一意にする必要があります。)

書き方は自由ですが、AWSはキャメルケース(camelCase)で書かれることが多いので、そのように書くことが多いみたいです。 ちなみに単語の最初だけ大文字にすることがラクダのコブのように見えることからcamelCaseというらしいです。 アンダースコアで繋げる書き方は、蛇のように見えるのでスネークケースと言います。

マネジメントコンソールで操作する時は、ポチポチとクリックしながら色々指定したり値を入力して環境を作ると思いますが、この「ポチポチ」がリソースの各指定に相当します。

リソースの参照

テンプレートの中にチラホラ出てくる「Ref」の文字ですが、これが先ほど書いた「論理ID」を参照するという意味です。 例えば、下記の部分で説明すると「MyIGW」が参照されていますが、参照されるのはリソース名「MyIGW」で定義されているリソース内容になります。

"MyVPC" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16",
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"InstanceTenancy" : "default",
"Tags" : [ {"Key" : "Name", "Value" : "Nyumon-VPC"} ]
}
},
"MyIGW" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [ {"Key" : "Name", "Value" : "Nyumon-IGW"}]
}
},
"AttachGateway" : {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"InternetGatewayId" : { "Ref" : "MyIGW" }
}
},

もう少し上記の内容で説明しますと「AttachGateway」のリソースでは、インターネットゲートウェイ「MyIGW」にVPC「MyVPC」をアタッチしようとしています。 実際に作成される際は、「MyIGW」「MyVPC」で定義されたリソース内容を参照して作成されることになります。

書く順番

テンプレートを書く順番は特には決まっていません。 VPC作ってからサブネット作るという流れに沿って書かなくても、CloudFormation側で内容を解釈して実行してくれます。 しかし、人がメンテしやすいようにある程度順番を意識して書くと、後で見た時に楽かなと思います。

一旦まとめ

少々くどい説明になっているかもしれませんが、ここまでの内容でまとめると、要点としては以下になります。

  • 論理IDを適当に宣言する
  • 何を作るのかリソースタイプTypeを指定する
  • 各Type毎に必要な要素をPropertiesで指定する
  • 他のリソースの参照が必要な場合は、参照したい論理IDを指定する

いかがでしょうか。 感覚的にでも理解してもらえていれば幸いです。

CloudFormation実行

では作成したテンプレートで実際に環境を作っていきます。 ここからは簡単です。

CloudFormationの画面で「Create New Stack」をクリックします。 スタック作成

今回は先ほどのテンプレートをファイルに保存して、ローカルからアップロードします。 S3に保存しておいてそのURLを指定することもできます。

テンプレート指定

テンプレートに問題がなければ次の画面になるので、適当な名前をつけます。 なお、指定したjsonのテンプレートに誤りがあると、ここでエラーになります。

エラー内容も合わせて表示してくれるので、修正してやり直します。 エラーとしては、jsonフォーマットの間違い(カンマ,の抜け漏れ等)や、参照IDのスペル間違いなどです。

スタック名指定

タグの指定などは必要に応じて指定します。

タグ指定

最後に確認して「Create」をクリックすれば実際の作成が開始されます。

レビュー

Statusが「CREATE_COMPLETE」になれば作成完了です。

コンプリート

途中で失敗すれば、作成途中でも全てロールバックされます。 途中で失敗するのは、例えば、指定したリソースタイプで使えない「Properties」要素が入ってしまっている場合などです。

スタック作成失敗

削除

削除したい対象のStackを削除すると、作成した環境も全て削除されます。 これで、環境一式を作ったり消したりといったことが簡単にできて便利ですね。

最後に

今回はご紹介していませんが、Stack作成時にユーザが動的に値を指定できる「パラメータ」やリージョン毎にAMIなどを指定できる「マッピング」といった便利機能もあります。

本ブログでもCloudFormationはよく採り上げられているいるので、合わせて見ていただければと思います。

これをきっかけにCloudFormationを使ってもらえれば幸いです。

以上になります。