CloudFormationStackSetで異なるアカウントにスタックをデプロイする

AWS

目次

はじめに

業務上でマルチアカウント環境でCloudFormationを利用した環境構築を実施することになりました。
CloudFormationは基本的にアカウント単位でスタックを作成します。ただし、アカウント単位でスタック実行するのは運用的に非効率であり、スタックやテンプレートの管理も複雑になります。
上記の理由で、スタック実行するアカウントを一元管理したいという思いがあったため、
CloudFormationの機能であるStackSetを使って1つの管理アカウントから別のアカウントへスタック構築してみました。

前提

  • AWSCloudShellが使えること
  • 同じ組織内のAWSアカウントが2つあること

手順

大まかな流れ

下記の流れで実施します。

  1. 管理アカウントIAMロールの作成
  2. スタック作成されるアカウントのIAMロール作成
  3. 管理アカウントでCloudFormationテンプレートを作成
  4. 管理アカウントでStackSetsを実行
  5. スタック作成されるアカウントで確認

管理アカウントIAMロールの作成

管理アカウント上のCloudShellで下記のJSONファイルを作成します。
スタックが作成されるアカウントのIAMロールを引き受けるためのロールです。

cat << EOF > AWSCloudFormationStackSetAdministrationRole.yaml
AWSTemplateFormatVersion: 2010-09-09

Resources:
  AdministrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetAdministratorRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: AWSCloudFormationManagementStackSetAdministratorRolePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sts:AssumeRole
                Resource:
                  - "arn:*:iam::*:role/AWSCloudFormationManagementStackSetExecutionRole"
EOF

管理アカウントIAMロールを作成します。

aws cloudformation deploy \
--template-file AWSCloudFormationStackSetAdministrationRole.yml \
--stack-name CloudFormation-StackSets-Admin-Role-Stack \
--capabilities CAPABILITY_NAMED_IAM

スタック作成されるアカウントのIAMロール作成

スタック作成されるアカウント上のCloudShellで下記のJSONファイルを作成します。

cat << EOF > AWSCloudFormationStackSetExecutionRole.yaml
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  AdministratorAccountId:
    Type: String
    Description: AWS Account Id of the administrator account (the account in which StackSets will be created).
    MaxLength: 12
    MinLength: 12

Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetExecutionRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref AdministratorAccountId
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - !Sub arn:\${AWS::Partition}:iam::aws:policy/AdministratorAccess
EOF

IAMロールを作成します。
「AdministratorAccountId」は管理アカウントのIDを入力します。

aws cloudformation deploy \
    --template-file AWSCloudFormationStackSetExecutionRole.yaml \
    --stack-name CloudFormation-StackSets-Execution-Role-Stack \
    --capabilities CAPABILITY_NAMED_IAM \
    --parameter-overrides AdministratorAccountId=xxxxxxxxxx

管理アカウントでCloudFormationテンプレートを作成

管理アカウントでCloudFormationテンプレートを作成します。
今回はVPCのみを作成する簡単なテンプレートを作成します。

cat << EOF > vpc.yaml
AWSTemplateFormatVersion: '2010-09-09'
#-------------------------
#VPC
#-------------------------


Resources:
  FirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
EOF

StackSets実行

管理アカウントでスタックセットを実行します。
CLIの場合は、スタックセットとスタックインスタンスは別々でリソース作成します。

aws cloudformation create-stack-set \
--stack-set-name pullpull3-stack-set \
--template-body file://vpc.yaml \
--permission-model SELF_MANAGED

スタックインスタンスを作成します。

aws cloudformation create-stack-instances \
--stack-set-name pullpull3-stack-set \
--accounts xxxxxxxxxxxx \
--regions ap-northeast-1

スタック作成されるアカウントで確認

スタック作成されるアカウントでCloudFormationのコンソールを確認すると、
下記の通りスタックが作成されている。

おわりに

元々スタックセットは同じスタックを複数アカウントもしくは複数リージョンにデプロイするものという認識でしたが、異なる単一の特定アカウントのみにスタックを作成する使い方もできることがわかりました。
考えられるケースとしては、企業の組織ポリシーでそれぞれ別々の用途のためにアカウントを複数使って運用する場合に一元管理のために使えそうだと思いました。

参考

セルフマネージド型のアクセス許可を付与する – AWS CloudFormation (amazon.com)

[小ネタ] CLIからCloudFormation StackSetsを作成する方法 | DevelopersIO (classmethod.jp)

CloudFormation StackSetsで複数アカウント・複数リージョンへ簡単にデプロイする | DevelopersIO (classmethod.jp)

タイトルとURLをコピーしました