はじめてのAWS CloudFormationテンプレートを理解する

# はじめに
AWS CloudFormationを利用する場合、どういう構成になっているかを簡潔にまとめてみました。

# テンプレートのファイル拡張子
テンプレートはJSONもしくはYAMLとなります。
JSONの場合は、jqコマンドが利用できるメリットがあります。
YAMLの場合は、コメントが書けるメリットがあります。
YAMLを利用する場合は、SAMの事を考慮に入れると、拡張子はyamlではなく、ymlとした方が無難です。

# セクションの構成
テンプレートの要素の事をセクションと言います。
※コメントになっているのは、オプションです。

```テンプレート.yml
AWSTemplateFormatVersion: 2010-09-09
# Description: Template for Akane

# Metadata:

# Parameters:

# Mappings:

# Conditions

# Transform

Resources:

# Outputs:
```
# セクションの詳細
各セクションを詳しく見ていきましょう。

##1. [Format version 形式バージョン](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/format-version-structure.html) (必須)

AWS CloudFormationテンプレートバージョンを記述する
形式バージョン: 2010-09-09
※現状唯一有効な値

```テンプレート.yml
AWSTemplateFormatVersion: 2010-09-09
```

##2. [Description 説明](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-description-structure.html) (オプション)
テンプレートの説明を記述する

```テンプレート.yml
Description: Template for Akane
```

##3. [Metadata メタデータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html) (オプション)
テンプレートに関する追加情報を記述する

##4. [Parameters パラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) (オプション)
テンプレートで利用するパラメータを宣言する

```テンプレート.yml
# パラメータを設定する
Parameters:
  パラメータ名:
    Description: 説明
    Type: String

# !Refで値を参照する
!Ref パラメータ名
```

```パラメータ.json
{
  "Parameters":[
    {
      "ParameterKey": "パラメータ名",
      "ParameterValue": "値"
    }
  ]
}
```

##5. [Mappings](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html) (オプション)
キーと値のマッピングを記述する

```テンプレート.yml
Mappings: 
  論理名: 
    キー1: 
      Name: 値1
    キー2: 
      Name: 値2
```

##6. [Conditions 条件](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html) (オプション)
条件を宣言する
※ResourcesセクションまたはOutputsセクションでリソースの作成に利用

```テンプレート.yml
Conditions:
  論理ID:
    組み込み関数
```
- 組み込み関数
  - Fn::And
  - Fn::Equals
  - Fn::If
  - Fn::Not
  - Fn::Or

##7. [Transform トランスフォーム](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-section-structure.html) (オプション)
マクロを指定する
※サーバレスアプリケーションや定型コンテンツ挿入などで利用する

```テンプレート.yml
Transform: AWS::Serverless-2016-10-31
```

##8. [Resources リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html) (必須)
スタックを構成するAWSリソースを記述する

リソースタイプとリソースプロパティは、[AWS リソースおよびプロパティタイプのリファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)を利用すると良いです。

```テンプレート.yml
Resources:
  論理ID:
    Type: リソースタイプ
    Properties: リソースプロパティ
```

##9. [Outputs 出力](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) (オプション)
スタック構築後に表示・取得した値や他スタックとの連携のための値を記述する

```テンプレート.yml
Outputs:
  論理ID:
    Description: Information about the value
    Value: !Ref Resourcesセクションの論理ID
    Export:
      Name: Export名
```
別のテンプレートからOutputsの値を参照する場合は、下記のようになります。

```別のテンプレート.yml
!ImportValue Export名
```

# AWS CLI
マネジメントコンソールからファイルをアップロードしたり、S3のURLを指定する事で実行できますが、パラメータ.jsonを利用する場合は、AWS CLIで行うことになります。

[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

- [スタックの作成(create-stack)](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html)
- [スタックの削除(delete-stack)](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/delete-stack.html)

```aws-cli.sh
# AWSリージョンを環境変数に指定(東京リージョン)
export AWS_DEFAULT_REGION=ap-northeast-1

# スタックの作成
aws cloudformation create-stack \
  --stack-name スタック名 \
  --template-body file://テンプレート.yaml \
  --cli-inpu-json file://パラメータ.json

# スタックの削除
aws cloudformation delete-stack \
  --stack-name スタック名 
```
# サンプルテンプレート集
- [AWS CloudFormationでVPCを構築しよう](https://qiita.com/miyabiz/items/e26702b6e20bfd2ecfd4)
- [AWS CloudFormationで2層ネットワークを構築しよう](https://qiita.com/miyabiz/items/f51b2a45e9a41df51603)
- [AWS CloudFormationでS3エンドポイントを使用したS3バケットを構築しよう](https://qiita.com/miyabiz/items/db97d1b719d99594e203)
- [AWS CloudFormationでCloudFormationエンドポイントを使用したEC2インスタンスを構築しよう](https://qiita.com/miyabiz/items/e71acb1e0fa34dd42ee3)