SSMドキュメントでCloudFormation Stackを作成してみた

## 背景
AWS環境にて一時サーバー用のEC2インスタンスを定期的に起動/削除する作業があり、手順を自動化したいというニーズがありました。
CodePipelineによるEC2インスタンス用のCloudFormation（CFn） Stack作成も検討したのですが、一時サーバー上で実行する処理を既にSSMドキュメント化していたため、CFn Stack作成自体もSSMドキュメントによる実行という方針に決まりました。
筆者はSSMドキュメント作成自体が初めてだったため、試した際の手順や注意点をメモしておきます。

## 事前準備
S3バケットにCFn Templateのyamlファイルを配置します。
※SSMドキュメント作成時にyamlファイルの内容を直接記載することもできます。

## SSMドキュメント作成手順

1.AWS Systems Managerのコンソールのドキュメントから「Create automation」をクリックします。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_18_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/fd5dcdbe-e2dd-6639-d5d2-3f0cc0fd0d7d.png)

2.「Document Attributes」を設定します。
ドキュメントの名前の指定は必須です。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_49_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/fc26578b-810d-e0bc-9ea5-13322b394a9f.png)

3.ステップの詳細を設定します。
指定する項目は「ステップ名」、「アクションタイプ」、「Stack name」、「Template URL」、「Additional inputs」の「Input name」と「値」です。
事前にCFn TemplateをS3バケットに配置せずyamlファイルの内容を直接記載する場合は「Template URL」は未指定のまま「Template body」に記載します。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_58_34_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/dc295478-b4a1-4cdf-29c0-6f76d0e365b0.png)
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_45_08_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/9a968497-b774-cd7b-b59a-6f5a51f3fd2b.png)

**ハマったポイント①**
「Template URL」は `s3://bucket-name/folder/xxxxx.yaml`のような指定でもSSMドキュメント自体は作成できますが、ドキュメント実行時に以下のメッセージが出てエラーになりました。

>Exception Message from CreateStack API: [S3 error: Domain name specified in bucket-name is not a valid S3 domain (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: 48c6c446-06e5-4200-8008-e3e5d7dea160; Proxy: null)].

URL形式で指定するようご注意ください。

**ハマったポイント②**
「Additional inputs」は最初未指定でSSMドキュメントを作成したのですが、以下のエラーが出ました。

>Exception Message from CreateStack API: [Requires capabilities : [CAPABILITY_IAM] （Service: AmazonCloudFormation; Status Code: 400; Error Code: InsufficientCapabilitiesException; Request ID: 3914e8fa-bf73-4d74-b77b-020266bc8a2d; Proxy: null）].

アクセス許可に影響するリソース作成が含まれるためにアクション実行時にその機能を明示的に認識するために`CAPABILITY_IAM` の指定が必要とのことです。
参考：https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/automation-action-createstack.html

CFn Templateで作成予定のリソースは正確には一時サーバ用のEC2インスタンス自体でなく一時サーバ用のAutoScalingGroupおよび起動テンプレートですが、指定がないとだめでした。

この`CAPABILITY_IAM` の指定をするのが「Additional inputs」です。
ただし、「Input name」に`Capabilities`、「値」に`CAPABILITY_IAM` を指定してもだめで、以下のようなエラーが出ます。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_58_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/85b10f02-7a14-9771-16e7-7103cee88c90.png)

`CAPABILITY_IAM`は`StringList format`でないとだめだそうで、`[CAPABILITY_IAM]`と指定すれば通ります。

（2020/08/04 追記）
CFn Templateで作成予定のリソースは一時サーバ用のAutoScalingGroupおよび起動テンプレートだけでなくインスタンスプロファイルも含まれていました。
上記リンクにインスタンスプロファイル作成時には`CAPABILITY_IAM` または `CAPABILITY_NAMED_IAM` の指定が必要とはっきり書いてあるので　`CAPABILITY_IAM` の指定がないとエラーになるのは当たり前でした。。

4.「Create automation」をクリックします。
これでSSMドキュメント完成です。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_45_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/e8160aac-a769-bce7-97e0-923ebaa0cb59.png)

## SSMドキュメント実行手順
1. 「自己所有」タブから先ほど作成したドキュメントを見つけてクリックします。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_58_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/5fddca31-42cf-e75d-88fe-d9d974a13e7f.png)

2. 「オートメーションを実行する」をクリックします。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 18_59_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/7a506ab7-0a70-9615-0ebd-31faf3a5ca26.png)

3. 「実行」をクリックします。
![AWS Systems Manager - Automation - Google Chrome 2020_07_27 14_59_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/4c018005-1327-0e82-e822-76e3c23a8ec9.png)

4. 「全体的なステータス」が「成功」になるのを確認します。
CFn Stackが作成されたかやEC2インスタンスが起動しているかどうかも確認します。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 16_37_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/e3ea826d-90be-dd8b-39ae-5652d940f944.png)

## SSMドキュメント修正&再実行する場合の注意点
実行するバージョンが修正後のバージョンになるよう明示指定が必要になります。
未指定の場合、実行バージョンはバージョン1のままとなります。
筆者は最初のうちこれに気づかずドキュメントを更新しても挙動が変わらず戸惑いました。。
ドキュメント修正時に指定、ドキュメント修正後に指定、実行時に指定するのいずれかが必要です。

**ドキュメント修正時に実行バージョンを指定する場合**
新しいバージョンを作成する際に「Set new version as default」にチェックを入れます。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 21_41_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/1ccd4c5b-18e3-b2df-b381-e02e03680821.png)

**ドキュメント修正後に実行バージョンを指定する場合**
「アクション」で「デフォルトバージョン」を指定し、バージョンを更新します。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 21_49_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/0aec3706-d5d3-1350-7251-a3c550a0b9a3.png)

![AWS Systems Manager - Documents - Google Chrome 2020_07_27 21_40_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/e5497984-eb2f-8fd1-3844-a3a44963a1b2.png)

**ドキュメント実行時に実行バージョンを指定する場合**
ドキュメントのバージョンをデフォルトから更新して実行します。
![AWS Systems Manager - Documents - Google Chrome 2020_07_27 21_34_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271327/de026eab-3cc8-12eb-8634-53b049c9117a.png)