StackSetsをCloudFormationで構築する

# はじめに
今回は、StackSetsをCloudFormationから作成してみました。
前回の最後で課題とした「各スタックインスタンスへのパラメータの一覧化」は適ったかなと思っています。

https://qiita.com/a_b_/items/a2d131e30ef74d701367

# 概要
- スタックセットをCloudFormationで作成
    - スタックインスタンスへ渡すパラメータを明記する形
        - コードをみればすべてのスタックインスタンスへのパラメータがわかる


# 手順

## 親/子アカウント上にIAMロール作成

以前の記事で説明したように、親と子アカウントに必要なIAMロールを作成します。

https://qiita.com/a_b_/items/1858055ba447c4966b58#%E6%89%8B%E9%A0%86

## パラメータ無しの場合

パラメータなしの場合は以下のようになります。

```yaml
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  AdminiRoleArn:
    Type: String
    Default: 'arn:aws:iam::000000000000:role/AWSCloudFormationStackSetAdministrationRole'

Resources:
  TestStackSet1:
    Type: 'AWS::CloudFormation::StackSet'
    DeletionPolicy: Delete
    Properties:
      StackSetName: TestStackSet12345
      AdministrationRoleARN: !Ref AdminiRoleArn
      PermissionModel: SELF_MANAGED
      Capabilities: 
        - 'CAPABILITY_NAMED_IAM'
      StackInstancesGroup:
        - 
          DeploymentTargets: 
            Accounts: 
              - '111111111111'
          Regions: 
            - 'ap-northeast-1'
        - 
          DeploymentTargets: 
            Accounts: 
              - '222222222222'
          Regions: 
            - 'ap-northeast-1'
      TemplateBody: |
        AWSTemplateFormatVersion: 2010-09-09

        Resources:
          AWSUser:
            Type: AWS::IAM::User
            Properties:
              UserName: 'Kasumi-Nakasu'
```
- `DeletionPolicy`は、削除時にスタックインスタンスも消すか、残しておくかを指定します。
- `AdministrationRoleARN`は、親アカウント用のIAMロールのArnを指定します。
- `Capabilities`は、今回のCFnテンプレートがIAMユーザを作成するため、'CAPABILITY_NAMED_IAM'を指定しています。
- `StackInstancesGroup`で、複数のスタックインスタンスを指定します。
- `TemplateBody`に直接、作成したいCFnテンプレートを記載します。

## パラメータ有りの場合
```yaml
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  AdminiRoleArn:
    Type: String
    Default: 'arn:aws:iam::000000000000:role/AWSCloudFormationStackSetAdministrationRole'

Resources:
  TestStackSet1:
    Type: 'AWS::CloudFormation::StackSet'
    DeletionPolicy: Delete
    Properties:
      StackSetName: TestStackSet12345
      AdministrationRoleARN: !Ref AdminiRoleArn
      PermissionModel: SELF_MANAGED
      Capabilities: 
        - 'CAPABILITY_NAMED_IAM'
      StackInstancesGroup:
        - 
          DeploymentTargets: 
            Accounts: 
              - '111111111111'
          ParameterOverrides: 
            - 
              ParameterKey: 'NicknameString'
              ParameterValue: 'kasukasu'
          Regions: 
            - 'ap-northeast-1'
        - 
          DeploymentTargets: 
            Accounts: 
              - '222222222222'
          ParameterOverrides: 
            - 
              ParameterKey: 'NicknameString'
              ParameterValue: 'かすかす'
          Regions: 
            - 'ap-northeast-1'
      TemplateBody: |
        AWSTemplateFormatVersion: 2010-09-09

        Parameters:
          NicknameString:
            Type: String
            Default: 'kasumin'

        Resources:
          AWSUser:
            Type: AWS::IAM::User
            Properties:
              UserName: 'Kasumi-Nakasu'
              Tags:
                - Key: 'Nickname'
                  Value: !Ref NicknameString
                - Key: 'Unit'
                  Value: 'QU4RTZ'

```
- `StackInstancesGroup`の`ParameterOverrides`で、各スタックインスタンスに指定するパラメータを指定します。
    - 日本語などの全角文字でも正常に作成されますが、作成後テンプレートを見ると文字化けしていました、要注意。
- `TemplateBody`はYamlで記述する。
    - JSON形式で記述する、またはJSON形式のファイルへのS3URLを指定すると、`Parameters: [NicknameString] must have values`とエラーとなり、うまく作成できませんでした。

# 公式ユーザーガイド

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-stackset.html

# おわりに
スタックインスタンスに与えるパラメータを一か所で管理するため、StackSetsをCloudFormationから作成しました。
そのほかの恩恵として、コンソールで作成するよりだいぶシンプルに作れるように感じました。