AWS CloudFormationまとめ

AWS上にインフラを構築するときにCloudFormationというサービスを利用すると
再利用しやすくて便利です。

僕はいつもCloudFormationを使って構築しているので、自分がよく使う
ものはgithubで管理したりしてます。

1. そもそもどういう用途なのか

参考 : AWS CloudFormation 公式

例えばAWS上にWebサービス向けインフラを構築したいとしたとき

  1. EC2でWebサーバを立てる
    • ポートは80(443)を開ける
    • ストレージはSSDにして容量を例えば30GBにする
  2. RDSでデータベースサーバを立てる
    • Webサーバ経由のみアクセスを許可する
    • MySQL 5.6を使う
  3. S3にファイルサーバを立てる
    • デフォルトの公開権限を設定する
  4. ElasticsearchServiceで検索用サーバを立てる
    • Elasticsearchのバージョンは5.1
    • Webサーバ経由のみアクセスを立てる

こんな感じの手順が必要になると思います。
ロードバランサを入れたい、キャッシュサーバを立てたいとか
やりたくなってくると更に手順は増えてきます。

これをサービスを開発するごとに、サーバを増やすごとに
同じ手順を踏まないといけないのは、面倒だし、手順が共有されていないと
上手く全体が動かない、なんてことが起こります。

これを設定ファイルによって、定義し実行できるのがCloudformationに
なります。

CloudFormation自体を利用するのに料金はかかりません。
(もちろん、CloudFormationによって構築されたEC2のインスタンス等には
通常通りの料金が加算されます。)

2. 簡単な設定ファイルを書いてみる

設定ファイルはjsonもしくはyamlで記述することができます。
僕はいつもyamlで書いてますので、ここでもyamlで例を挙げていきます。

CloudFormation公式のチュートリアルと同じものです。
S3のバケットを作成するための最小の設定ファイルです。

Resourcesの下には複数のハッシュを含めることができます。
以下の例では2つのバケットを生成します。

※もちろん、S3バケットとEC2インスタンスを、みたいにも書けます。
それぞれのリソースタイプの書き方は、下記の参考リンクを参照してください。

最初はAWSマネジメントコンソールからポチポチやったほうが
早いですが、慣れてくる+設定ファイルを使いまわせるようになってくると
早くなります。

ものすごくざっくり書くと

  • Typeに作りたいリソースタイプ(S3のバケットとか、EC2のインスタンスとか)
  • Propertiesに、設定項目を書く(S3のアクセス権限とか、EC2のインスタンスタイプとか)

という感じです。

Typeには何が指定可能なのか、というと
以下が一覧になります

AWS リソースプロパティタイプのリファレンス 公式

上記では省略していますが、下記のようにDescriptionで、
設定ファイルが何をしているか記述しておくことができます。

Description以外にどのようなセクションが利用できるのか
は以下に一覧があります。

テンプレートの分析 公式

よく使うのはParametersOutputsで、
こちらに関しては後ほど。

3. 外部から設定を動的に指定できるように

上記だけでも、まぁ便利は便利ですが、1つのスタックを外部から変更
できないので、使いまわすのには不便です。

例えば最初に例に出した

  1. EC2でWebサーバを立てる
    • ポートは80(443)を開ける
    • ストレージはSSDにして容量を例えば30GBにする
  2. RDSでデータベースサーバを立てる
    • Webサーバ経由のみアクセスを許可する
    • MySQL 5.6を使う
  3. S3にファイルサーバを立てる
    • デフォルトの公開権限を設定する
  4. ElasticsearchServiceで検索用サーバを立てる
    • Elasticsearchのバージョンは5.1
    • Webサーバ経由のみアクセスを立てる

これをサービスAとして、新しくサービスBを立ち上げることになり、
インフラ構成はほとんどサービスAと同様、でもEC2のストレージのサイズを
100GBにしないといけない

ということがあったときに、全部コピーしてストレージサイズだけ
書き換えるのはしんどいです。

そんなときに使えるのが前述したParametersです。

これは20GBのEBSをもったm1.smallインスタンスタイプのEC2インスタンスを
定義した設定です。100GBにしたいときに、もともとあったこのファイル
をコピーしてVolumeSizeだけを書き換えるのはしんどいです。

そこでVolumeSizeParametersによって変更できるようにします。
それが以下になります。

こうすることで、この設定ファイルを利用すると、実行時に
CloudFormationの画面から当該の値を指定することができます。

これをたくさんパラメータにしていけば、設定ファイルを一回書けば
使いまわすことができるようになりますね。

4. 複数設定ファイルを組み合わせて利用したい

スタックを使いまわすことができるようになったのはいいですが、
ここでもう一つ問題が起こります。

また最初の例を出してみます。

  1. EC2でWebサーバを立てる
    • ポートは80(443)を開ける
    • ストレージはSSDにして容量を例えば30GBにする
  2. RDSでデータベースサーバを立てる
    • Webサーバ経由のみアクセスを許可する
    • MySQL 5.6を使う
  3. S3にファイルサーバを立てる
    • デフォルトの公開権限を設定する
  4. ElasticsearchServiceで検索用サーバを立てる
    • Elasticsearchのバージョンは5.1
    • Webサーバ経由のみアクセスを立てる

これをサービスAとして、今度はサービスCを作りたいとしてます。
サービスCの要件が

  • RDSは使いません
  • その代わりにDynamoDB使いたいです

だとします。こうなると、さっきパラメータで指定できるように
書き換えた設定ファイルも使えません。
(RDSをなくせないし、DynamoDBを追加もできない。)

これに対応するために、サービスAのスタックを複数ファイルに分割して
必要に応じて呼び出すように変更します。

イメージとしては今まで1つのファイルに全ての設定を書いていたものを

  1. EC2インスタンスの設定ファイル
  2. RDSの設定ファイル
  3. S3の設定ファイル
  4. Elasticsearchの設定ファイル
  5. 1-4を呼び出して組み合わせる設定ファイル

に変えていきます。
本来であれば、全て具体的に書きたいんですが、すっごく長くなると思うので
上記項目の中から3と5だけ取り上げます。

以下がS3の設定ファイル

そしてこれが呼び出す側の設定ファイル

CloudFormationのリソースタイプは結構な種類があるので覚える必要は
ありませんが、AWS::CloudFormation::Stackだけは覚えてほしい!

これは外部に置かれているCloudFormation用の設定ファイルを参照して
パラメータを渡し、自分のスタックとします。

これによって複数のミニマルな設定ファイルを組み合わせて
アプリケーション全体のスタックを定義することができます。

上記のサービスCの例なら、新しくDynamoDBのスタックの設定ファイルを
記述して、RDSと置き換えれば可能です。

最後に、よくあるのが

  • あるVPCネットワークを作成する
  • サブネットAを作成する
  • サブネットBを作成する

こういうケースでは、サブネットAとサブネットBはVPCネットワーク
の情報が必要になります。

サブネットが2つ程度であればいいですが、複数(または1つ)作りたいときが
あると思います。

そういうときには、Outputsセクションを用います。
(この例では最小限のものだけしか出してないので、ルートテーブルとかは別途記述する必要があります。)

まずはVPCを作成する設定ファイル

次にサブネットを作成する設定ファイル

実際にVPCとサブネットを作成する設定ファイル

VPC作成設定ファイルでVPCのIDをOutputsに出すことによって、利用側がその値を参照できるようになってます。

RefGetAtt

この辺を参照してみてください。

5. はまったので注意してほしいところ

ParameterをList<?>型にしているスタックに対してyamlのリストを
渡せません(2017-07-03現在)

この場合はカンマ区切りの文字列にする必要があります。

組み込み関数のJoinを使うことで対応することができます。

こんな感じ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です