それ積んどく?

ひたすら何かを積んでいくブログ

AWS CloudFormation StackSets のまとめ

概要

複数リージョンまたアカウントに CloudFormation テンプレート(スタック)を
一斉展開できる StackSets 機能について記載。
スタンドアローンアカウントが対象(非 Organizations管理)。

  • 役割の異なる 2 つのアカウントが存在する。
    • 管理者アカウント ... スタックセットを実行するアカウント。
    • ターゲットアカウント ... スタックが展開されるアカウント。
  • 各アカウントに対する事前の権限設定が必要。
    • 規定の名前の 2 つのロールが必要。
      • 管理者アカウント(管理ロール): AWSCloudFormationStackSetAdministrationRole
      • ターゲットアカウント(実行ロール): AWSCloudFormationStackSetExecutionRole
    • 管理者アカウントが実行ロールを引き受ける内容となっている。
      • 作成可能なリソースは実行ロールに割り当てるポリシーに依存する。
    • いずれも AWS から環境設定用の CloudFormation テンプレートのサンプルが提供されている。
  • 複数の展開先を指定する以外は、通常の CloudFormation と使い方は同じ。
    • アカウントとリージョンを指定する。
    • 同一アカウントの場合は実行アカウントに自身のアカウント ID を指定する。

[参考サイト]

スタックセットとは

単一の CloudFormation テンプレートを複数のアカウント、リージョンに展開する機能。

スタックセットでは、1 つの CloudFormation テンプレートを使用して、複数のリージョンの AWS アカウントにスタックを作成できます。各スタックに含まれるリソースはすべて、スタックセットの CloudFormation テンプレートで定義されます。スタックセットを作成する際、使用するテンプレートに加え、そのテンプレートで必要なパラメータや機能を指定します。

see also

アカウントと権限

マルチアカウント展開できることから、スタックセット実行時は
管理者アカウント(実行元のアカウント)、ターゲットアカウント(展開先のアカウント)
の 2 つのアカウントの指定が必要。

  • 管理者アカウント
  • ターゲットアカウント

それぞれのアカウントに役割に応じたスタックセットの実行権限が必要。

  • 実行元先が同一のアカウントの場合でも、所定の権限設定が必要。
  • この際は、自身のアカウント ID を指定して実行する。

規定名称の IAM ロールを使用。

  • 管理者アカウント(管理ロール): AWSCloudFormationStackSetAdministrationRole
  • ターゲットアカウント(実行ロール): AWSCloudFormationStackSetExecutionRole

IAM ロールの作成

AWS 提供のサンプルベースで記載。

  • ターゲットアカウントに AdministratorAccess 権限でリソースが作成できるようになる。

see also

管理者アカウント

実行元のアカウントに必要な IAM ロール。

  • 実行元のアカウントによる AssumeRole を許可する。
    • AWSCloudFormationStackSetAdministrationRole

[AWSCloudFormationStackSetAdministrationRole]

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole"
            ],
            "Effect": "Allow"
        }
    ]
}

ターゲットアカウント

展開先のアカウントに必要な IAM ロール。

  • 実際のリソース作成に必要な権限付与を担う IAM ロール。
    • AWSCloudFormationStackSetAdministrationRole が昇格する先のロール。
  • ロールに割り当てられた権限の行使を可能にする。
    • サンプルでは AdministratorAccess を許可。
  • 信頼関係を設定している。

[AWSCloudFormationStackSetExecutionRole]

<admin_account_id> は管理者アカウントのアカウント ID。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<admin_account_id>:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

単一アカウント用のテンプレート

AWS 提供のサンプルを合体させただけです。
実行アカウントにスタックセット実行に必要な IAM ロールを作成します。

[使い方]

  • CloudFormation-Stack-Create-IAMRole-ForStackSets.yml でテンプレートを保存してスタックを実行。
    • 名前は任意(コピペ用に適当に名前をつけてます)。
  • 実行したリージョンにスタックが作成。
aws cloudformation deploy \
    --template-file CloudFormation-Stack-Create-IAMRole-ForStackSets.yml \
    --stack-name CloudFormation-Stack-CreateIAMRole-ForStackSets \
    --capabilities CAPABILITY_NAMED_IAM

see

[CloudFormation-Stack-Create-IAMRole-ForStackSets.yml]

AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetExecutionRole to enable use of your account as a target account in AWS CloudFormation StackSets.

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

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

see also

Stacksets の操作

マニュアルベースで概要を記載。
() 内は GUI 上の表記。★ は本記事内で扱うもの。

  • 既存スタック(リソース)の内容を変更する場合は「更新」。
  • アカウントやリージョンに追加展開する場合は、「追加」。
  • テンプレートに設定したパラメータ変更のみの場合は「パラメータの上書き」。
  • 「更新」と「上書き」は一部リージョンのみの選択も可能。

[概要]

  • ★スタックセットの作成
    • 新規作成。
  • スタックセットの更新(Stacksets の詳細を編集)
    • スタックセット中のスタックインスタンスを更新する場合の操作。
      • 変更したテンプレートをアップロード or 何らかのパラメータを変更。
    • アカウントやリージョンの追加はこの操作では出来ない。
  • スタックをスタックセットに追加する(Stacksets にスタックを追加)
    • スタックをさらに別のアカウントやリージョンに展開する場合。
      • 追加展開するアカウント ID とリージョンを指定して実行。
      • テンプレートは既存テンプレートのまま。
  • タックインスタンスのパラメータを上書きする(Stacksets のパラメータを上書き)
    • 文字通り、パラメータ(デプロイオプション)のみ変更可能。
      • テンプレートは既存テンプレートのまま。
      • テンプレート中のパラメータ操作が可能。上書き or テンプレート値に戻す等の操作が出来る。
    • 対象のアカウント ID とリージョンを指定して実行。
      • 展開済みのアカウントとリージョンのみ選択可能。
  • スタックセットからのスタックインスタンスの削除(Stacksets からスタックを削除)
    • 追加の逆。削除するアカウントとリージョンを指定。
  • ★スタックの削除(Stacksets の削除)
    • Stacksets 削除の前にすべてのスタックインスタンス(スタック)の削除が必要。

[検証メモ]

長くなったものを別だし。

  • スタックセットの更新(Stacksets の詳細を編集)
    • アカウント番号やリージョンを入力しなくてもエラーにはならない。
      • 新規作成時と同様のアカウントとリージョンに変更が反映される。
    • リージョンは展開済みのリージョンのみ選択可能。
      • リージョン指定時はアカウント ID とセットで指定が必要。
        • エラー) Must provide both Accounts and Regions if providing a filter
      • 一部リージョンのみの指定も可能。
        • 但し、選択されなかったリージョンの状態ステータスは PENDING になる(実害は不明)。
          • 未選択リージョンではテンプレートと差異が出たはずだが、ドリフトの検出ではエラーにならなかった。
          • 検証は EventBridge ルール名だけ変えて行ったので、対象にならなかったのかもしれない。

see also

StackSets の作成

  • StatkSets が実行元のリージョンに作成される。
  • Stack が展開先のリージョンに作成される。
    • StatkSets 上でスタックインスタンスとして管理される。
  • GUI 上では無効なリージョンも対象として追加可能なため、除外する必要がある。

[設定パラメータ]

  • テンプレートの選択
    • IAM 管理ロール ARN ... ロール名を選択するか、ARN を入力。
      • AWSCloudFormationStackSetAdministrationRole
    • IAM 実行ロール名 ... 実行ロールはデフォルトで下記が設定済。
      • AWSCloudFormationStackSetExecutionRole
    • テンプレートの準備。
      • Amazon S3 URL
      • テンプレートのアップロード
        • cf-templates-<ランダム>-<リージョン名>バケットが作成される。
      • スタック ID(ARN)
  • StackSet の詳細
    • StackSet名
    • 説明
    • パラメータ
      • スタックにパラメータが設定されている場合に入力。
  • StackSet オプション
    • タグ:
      • 作成リソースにタグを設定する場合。
    • 実行設定
      • 非アクティブ or アクティブ ... 並列実行の可否(アクティブのほうが断然早い)。
  • デプロイオプション
    • スタックセットにスタックを追加
      • ● 新しいスタックのデプロイ
      • ○ スタックをスタックセットにインポート
    • スタックをアカウントにデプロイ
      • 対象アカウント ID を入力。
    • デプロイするリージョン
      • リージョンを選択。
    • 同時アカウントの最大
      • 1
    • 耐障害性
      • 0
    • リージョンの同時実行
      • 1

see also

StackSets の削除

StackSets の削除時はまず展開したリソース(スタックインスタンス)を
先に削除する必要がある。
画面が削除っぽくないので、初めてやるとちょっと面食らう。

スタックインスタンスの削除 -> StackSets の削除

  • 展開時と同様に対象アカウントを指定して削除を実施する。

[作業の流れ]

  1. 対象の StackSets を選択。
  2. アクションより、「StackSets からスタックを削除」をクリック。
  3. デプロイオプションの設定
    1. ● スタックをアカウントにデプロイ
      1. <アカウント ID> を入力。
    2. リージョンの指定
      1. 対象リージョンを選択。
    3. デプロイオプション(デフォルト設定を記載)
      1. 同時アカウントの最大数: 1
      2. 障害耐性: 1
      3. スタックを保持: 無効
      4. リージョンの同時実行: 順次
  4. 内容を確認して削除を実施。
  5. 削除完了後、スタックインスタンスのタブを確認。
    1. 何もない状態になれば StackSets を削除できる。
  6. アクションより、「StackSets の削除」をクリック。

see also

StackSets の CLI 操作

(CLI) StackSets の作成

GUI ではそれほど意識することがないが、
コンテナとスタックインスタンスを順番に作成する。

  1. スタックセットコンテナの作成
  2. タックインスタンスの作成
    1. 任意のリージョンに展開する(例示は有効な全リージョン展開)。
STACKSET_NAME=<stack-set-name>

# 自アカウント ID の取得
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)

# 有効なリージョンの取得
REGIONS=$(aws ec2 describe-regions --all-regions \
--filters "Name=opt-in-status,Values=opt-in*" \
--query "sort_by(Regions[].{Name:RegionName},&Name)" --output text)

# スタックセットコンテナの作成
aws cloudformation create-stack-set \
    --stack-set-name $STACKSET_NAME \
    --template-url https://XXX \
    # --template-body file://XXX
    --parameters ParameterKey=Key1,ParameterValue=Value1 \

# 確認
aws cloudformation list-stack-sets --status ACTIVE
aws cloudformation describe-stack-set \
    --stack-set-name $STACKSET_NAME

# スタックセットインスタンスの作成
aws cloudformation create-stack-instances \
    --stack-set-name $STACKSET_NAME \
    --accounts $ACCOUNT \
    --regions $REGIONS \
    --operation-preferences \
      RegionConcurrencyType=PARALLEL,MaxConcurrentCount=1,FailureToleranceCount=0

# 確認(オペレーション ID を入力)
aws cloudformation describe-stack-set-operation \
    --stack-set-name $STACKSET_NAME --operation-id <operation_ID>

# スタックセットインスタンスの確認
aws cloudformation list-stack-instances \
  --stack-set-name $STACKSET_NAME \
  --query "Summaries[].[StackSetId,Region,StackInstanceStatus.DetailedStatus]"
  • --operation-preferences
    • RegionConcurrencyType= {"SEQUENTIAL"|"PARALLEL"}
      • リージョンごとの並行実行の可否
      • The concurrency type of deploying StackSets operations in Regions, could be in parallel or one Region at a time.

    • MaxConcurrentCount=1,FailureToleranceCount=0
      • FailureToleranceCount パラメータで 0 を MaxConcurrentCount に、1 を --operation-preferences に設定することで、障害耐性 および 同時アカウントの最大数 を設定します。代わりに割合を適用するには、FailureTolerancePercentage または MaxConcurrentPercentage を使用します。このウォークスルーでは、割合ではなくカウントを使用します。

      • MaxConcurrentCount の値は、FailureToleranceCount の値に依存します。MaxConcurrentCount は、最大で FailureToleranceCount より 1 だけ多くなります。

see also

(CLI) StackSets の削除

削除は作成の逆。
中身を消してからガワを削除する。

  1. タックインスタンスの削除
  2. スタックセットコンテナの削除
STACKSET_NAME=<stack-set-name>

# 自アカウント ID の取得
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)

# 展開先リージョンの取得
REGIONS=$(aws cloudformation describe-stack-set \
  --stack-set-name $STACKSET_NAME \
  --query "StackSet.Regions" --output text)

# スタックインスタンスの削除
aws cloudformation delete-stack-instances \
    --stack-set-name $STACKSET_NAME \
    --accounts $ACCOUNT \
    --regions $REGIONS \
    --operation-preferences \
      RegionConcurrencyType=PARALLEL,FailureToleranceCount=0,MaxConcurrentCount=1 \
    --no-retain-stacks

# 確認(オペレーション ID を入力)
aws cloudformation describe-stack-set-operation \
    --stack-set-name $STACKSET_NAME --operation-id <operation_ID>

# スタックセットコンテナの削除
aws cloudformation delete-stack-set \
    --stack-set-name $STACKSET_NAME

# 確認
aws cloudformation list-stack-sets --status ACTIVE
  • --retain-stacks | --no-retain-stacks (boolean)
    • スタックを残すかどうか。
    • Removes the stack instances from the specified stack set, but doesn't delete the stacks. You can't reassociate a retained stack or add an existing, saved stack to a new stack set.

see also

ドリフトの検出

CloudFormation テンプレートで設定したリソースの設定と
実際のリソースの設定差分を検出できる(つまり手動変更の検出)。

  • 対象のスタックまたはスタックセットに対して、ドリフトの検出を実行。
  • 差分がなければ「IN_SYNC」、差分があれば「DRIFTED」になる。
    • 差分の詳細は、該当リージョンのスタックから確認する。
  • 差分の修正はテンプレートの修正 or 再展開などで行う(1 クリック是正のようなものはなかった)。

see also