【AWS】CloudFormation

# はじめに
タダです。

AWS認定資格の試験勉強のためにCloudFormationの情報をまとめた自分用メモになります。
あくまで個人用のメモになるので、その点はご了承ください。
※違う内容書いているなどありましたらご指摘いただけると幸いです。
※随時アップデートがあれば更新していきます。

# CloudFormationとは
AWSリソースを作成したり、管理するのが役立つツールです。JSONやYAML形式でリソース定義できる

CloudFormationを使う主なメリットは以下の通り

* AWSリソース管理が簡略化
* インフラリソースを素早く展開/複製
* インフラリソースの制御や変更も簡単

## Elatic Beanstalkとの違い
* Elatic Beanstalkはアプリを簡単にデプロイ及び実行できる環境を提供する
	* アプリのライフサイクルを管理するためのサービス
* CloudFormationはAWSリソースの作成をサポートする
	* Elatic Beanstalkもサポートしている


# CloudFormationの概念
* テンプレート
	* YAMLまたはJSON形式のテキストファイルでAWSリソース作成のための設計図
		* ５種類の要素で構成される
			* テンプレートパラメータのオプションリスト
			* 出力値のオプションリスト
			* 静的な設定値を見るのに使用するデータテーブルのオプションリスト
			* AWS リソースとそれらの設定値のリスト
			* テンプレートファイルフォーマットのバージョン番号
	* 具体的には以下のようなものがテンプレート例

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "A sample template",
  "Resources" : {
    "MyEC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "ami-2f726546",
        "InstanceType" : "t1.micro",
        "KeyName" : "testkey",
        "BlockDeviceMappings" : [
          {
            "DeviceName" : "/dev/sdm",
            "Ebs" : {
              "VolumeType" : "io1",
              "Iops" : "200",
              "DeleteOnTermination" : "false",
              "VolumeSize" : "20"
            }
          }
        ]
      }
    }
  }
}
```
* スタック
	* CloudFormationの関連リソースは、スタックと呼ばれます。これを作成、変更、更新することでリソース制御を行う
	* スタックの更新には2つの方式がある
		* 直接更新(in place)と変更セットの作成(blue-green)と実行
* 変更セット
	* スタックの更新をおこなう時の概要が変更セットと呼び、影響度を確認するためのスタック

## 変更セットについて
### 変更セットの作成
更新元のスタックをもとに変更セットを作成します
Cloudformation -> [Actions],[Create Change Set For Current Stack]を選択
その他のパラメーターは、スタックを作成するのと同じ操作で行う
CLIだと、以下のように実行する

```
aws cloudformation create-change-set --stack-name arn:aws:cloudformation:us-east-1:123456789012:stack/SampleStack/1a2345b6-0000-00a0-a123-00abc0abc000
--change-set-name SampleChangeSet --use-previous-template --parameters ParameterKey="InstanceType",UsePreviousValue=true ParameterKey="KeyPairName",UsePreviousValue=true ParameterKey="Purpose",ParameterValue="production"
```

### 変更セットの実行
変更セットに記述された変更をスタックに加えるには、変更セットを実行する
※変更セットを実行するとスタックに関連付けられた変更セットは削除される点は注意。
CLIだと、以下のように実行する

```
aws cloudformation execute-change-set --change-set-name arn:aws:cloudformation:us-east-1:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000
```


# CloudFormationのベストプラクティス
* スタックは共通リソースの所有者でグルーピング
	* リソース利用の制限は行わないようにする
* クロススタック参照で共有リソースをエクスポート
	* ネットワークリソース系
* アクセス制限はIAMで
* スタックの制限は200なので、注意
* テンプレートの再利用
* 他のスタックにネストされたテンプレートの参照
	* [AWS::CloudFormation::Stack](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html)
* テンプレートに認証情報を埋め込まない
	* 埋め込んでもNoEchoプロパティを使う
* cfn-init ヘルパースクリプトと AWS::CloudFormation::Init を使ってEC2にソフトウェアをインストールする
* ヘルパースクリプトは常に最新のものを使う
* テンプレートを使用する前に検証する
	* `aws cloudformation validate-template`
* CloudFormationで全てのリソースを管理する
* スタックを更新する前に変更セットを作成する
* CloudTrailとロギング
* コードの確認とリビジョン管理
* Elastic Compute Cloudのパッケージは最新化する

# CloudFormationのテンプレート
JSONかYAMLのどちらかでテンプレートを作成します。

## テンプレートのセクション
* Format Version(任意)
	* テンプレートバージョンを指定する
* Desription(任意)
	* 説明文
* Metadata(任意)
	* テンプレートに関する追加情報を提供するオブジェクト
* Parameters(任意)
	* テンプレートに渡すことができる値を指定する
		* データ型、デフォルト値、最大最小値など型が設定可能
	* テンプレートのResources、Outputsセクションのパラメーターを参照できる
* Mappings(任意)
	* 条件パラメーター値の指定に使用できる、キーと関連する値のマッピング(検索テーブルに類似したもの)
* Conditions(任意)
	* 特定のリソースが作成されるかどうかや、スタックの作成または更新中に特定のリソースプロパティが値を割り当てられるかどうかを制御する条件を定義する
* Transform(任意)
	* サーバレスアプリケーションの場合、使用するAWS SAMのバージョンを指定する
* Resources(必須)
	* スタックで作成するリソースとそのプロパティを指定する
		* EC2やELBやRDSなど起動するサービスを指定し、リソース毎に決められたプロパティを指定する
* Outputs(任意)
	* スタックのプロパティを確認すると返される値について説明する
* Function
	* パラメータの参照やMapの参照などの際はFunctionを使う(Parameterの取得に利用するRef関数もFunctionの一つ)
		* Ref: パラメータの参照
		* Fn::Base64 : 文字列をBase64でエンコードする
		* Fn::FindInMap : Mapから値を取り出す
		* Fn::GetAtt :リソースに付随する値を取得する
		* Fn::GetAZs : 指定したリージョンのAZを取得する
* 疑似パラメータ参照
	* 予め定義されたパラメータ群をRef関数で参照できる
		* AWS::Region,AWS::StackId,AWS::StackNameなど

## スタックの出力値のエクスポート
* スタック間で情報を共有するにはスタックの出力値をエクスポートする
	* 同じAWSアカウントとリージョンの他のスタックは、エクスポートされた値をインポートできる
	* WebサーバのサブネットやSecurityGroup IDをエクスポートする単一ネットワーキングスタックがあったとして、Webサーバのあるスタックは、それらのネットワーキングしリソースをインポートできる

## テンプレート作成ツール
* CloudFormer
	* 構築済みの環境からテンプレートを作成するWebツール
* CloudFormation Designer
	* テンプレート内のリソースを可視化
* Hava
* Cloudcraft


## CloudFormationの運用
* 個別テンプレート、1スタック
* 個別テンプレート、個別スタック
* スタック間の連携

# CloudFormationのリソースについて
## リソース属性
### CreationPolicy
* CloudFormationが指定数の成功シグナルを受信するかまたはタイムアウト期間が超過するまでは、ステータスが作成完了にならないようにする
	* AutoScalingCreationPolicy
	* ResourceSignal

### DeletionPolicy
* スタックが削除された際にリソースを保持または (場合によっては) バックアップできる
	* Retain
		* スタック削除したくない場合は指定する

### DependsOn
* 特定のリソースが他のリソースに続けて作成されるように指定できる

### UpdatePolicy属性
* CloudFormationがAWS::AutoScaling::AutoScalingGroup リソースに対する更新を処理する方法を指定できる
	* AutoScalingReplacingUpdate
		* AutoScaling グループの置き換え更新を処理する方法を指定する時に使う
	* AutoScalingRollingUpdate
		* ローリング更新を使う場合指定する
	* AutoScalingScheduledAction
		* スケジュールされたアクションが関連付けられているAutoScalingグループを含むスタックを更新する時に使う

## CloudFormationヘルパースクリプト
スタック作成の時にEC2インスタンスでソフトウェアをインストールしたりサービスを開始したりするために使用できるPythonヘルパースクリプトのセットがある

* cfn-init
	* リソースメタデータの取得と解釈、パッケージのインストール、ファイルの作成およびサービスの開始で使用される
* cfn-signal
	* スタック内の他のリソースと準備できたアプリケーションを同期できる
* cfn-getmetadata
	* リソースに定義されたすべてのメタデータ、またはリソースメタデータの特定のキーやサブツリーへのパスを簡単に取得できる
* cfn-hup
	* メタデータへの更新を確認し、変更が検出された時にカスタムフックを実行するデーモン


# 参考情報
[サービス概要](https://aws.amazon.com/jp/cloudformation/)
[よくある質問](https://aws.amazon.com/jp/cloudformation/faqs/)
[ドキュメント](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html)
[SlideShare](https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2016-aws-cloudformation)

# 更新日時
* 2017/04/30 初回投稿