CloudFormation StackSetsの自動デプロイターゲットOUを変更してみた

CloudFormation StackSetsの自動デプロイターゲットOUを変更してみた

Clock Icon2024.07.06

こんにちは。たかやまです。

CloudFormation StackSetsではサービスマネージド型のデプロイを利用することで、OrganizationsのOUをターゲットに自動デプロイを設定することができます。

サービスマネージド型のアクセス許可を持つスタックセットの自動デプロイの管理 - AWS CloudFormation

今回はStackSetsの自動デプロイのターゲットOUをすでに設定/運用している環境で、ターゲットOUを変更する場合の方法と気をつけるべき点について紹介したいと思います。

さきにまとめ

  • StackSetsの既存の自動デプロイターゲットOUを変更するには delete-stack-instances を実行する必要があり、一度スタックインスタンスの管理から外す必要がある
  • 新たな自動デプロイターゲットOUを設定はcreate-stack-instancesを実行する
    • 新しいターゲットOUにすでにスタックが存在するアカウントがある場合にはAccountFilterTypeを指定してスタックが存在するアカウントを除外する
  • 既存のスタックをStackSetsのスタックインスタンスとして管理する場合にはインポートを実施する
    • NoEchoプロパティを含むスタックはStackSetsへのインポートができないので注意

やってみる

更新のイメージ

今回は ParentOU -> Child1OU ターゲットOUに変更する流れになります。

イメージは以下のとおり

01-stacksets-auto-deploy-target-change

おおまかな流れは以下のとおりです。

  1. 変更前のスタックインスタンスを一覧取得
  2. 不要なターゲットOUを削除
  3. 新たなターゲットOUを追加
  4. 変更後のスタックインスタンスを一覧化取得
  5. ターゲットOU配下アカウントのスタックをインポート

1. 変更前のスタックインスタンスを一覧取得

後工程のスタックインスタンスインポートのために、変更前のスタックインスタンスの一覧を取得します。

以下のコマンドでスタックインスタンスを取得します。

aws cloudformation list-stack-instances \
  --stack-set-name <YOUR_STACK_SETS_NAME> \
  --query 'Summaries[].[Account,StackId]' \
  --output table
実行結果
aws cloudformation list-stack-instances \
>   --stack-set-name example-stacksets \
>   --query 'Summaries[].[Account,StackId]' \
>   --output table

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|                                                                             ListStackInstances                                                                            |
+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  73XXXXXXXX81|  arn:aws:cloudformation:ap-northeast-1:73XXXXXXXX81:stack/StackSet-s3-stacksets-ca36efb6-248b-4f82-b85c-78419d32afa5/43fd7c10-3aa7-11ef-861d-0a5abfa1ddd   |
|  80XXXXXXXX71|  arn:aws:cloudformation:ap-northeast-1:80XXXXXXXX71:stack/StackSet-s3-stacksets-7a6b2867-fdb6-4487-a9bd-63d3313cbf9e/4f564ce0-3aa7-11ef-98aa-0a0ff7db0b5   |
+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+

2. 不要なターゲットOUを削除

次に不要なターゲットOUを削除します。

ここでは更新のイメージでいう ParentOU をターゲットOUから削除します。

では以下のコマンドで不要なターゲットOUを削除します。

aws cloudformation delete-stack-instances \
  --stack-set-name <YOUR_STACK_SETS_NAME> \
  --deployment-targets OrganizationalUnitIds=["<UNNECESSARY_UNIT_ID>"] \
  --operation-preferences RegionConcurrencyType=PARALLEL,MaxConcurrentPercentage=100 \
  --regions <YOUR_REGION> \
  --retain-stacks
実行結果
aws cloudformation delete-stack-instances \
>   --stack-set-name example-stacksets \
>   --deployment-targets OrganizationalUnitIds=ou-0orw-bvsrcrpk \
>   --regions ap-northeast-1 \
>   --operation-preferences RegionConcurrencyType=PARALLEL,MaxConcurrentPercentage=100 \
>   --retain-stacks
{
    "OperationId": "05bcd906-f826-4c57-9746-2f1d751ba47d"
}

実行が成功するとStackSetsコンソール オペレーション タブでDELETEオペレーションを確認できます。

オペレーションとしてはスタックが削除されたことになっていますが、--retain-stacksをつけているためスタックは削除されていません。

02-stacksets-auto-deploy-target-change-2

ちなみに、イメージでいうChild2OU配下のアカウントのスタックは今後StackSetsの管理下から外すことになります。

対象アカウントのスタックが不要な場合には個別にアカウントへログインしスタックを削除してください。
(削除対象のアカウントが多い場合には、delete-stack-instancesとアカウントフィルターを組み合わせて削除しても問題ないですが、オペレーションミスに注意してください。)

3. 新たなターゲットOUを追加

次に新たなターゲットOUを追加します。

この時、スタックが存在するアカウントにStackSetsがデプロイされないようにするためにAccountFilterTypeを指定してスタックが存在するアカウントを除外します。

aws cloudformation create-stack-instances \
  --stack-set-name <YOUR_STACK_SETS_NAME> \
  --deployment-targets 'OrganizationalUnitIds=["<NECESSARY_UNIT_ID>"],Accounts=["<EXCLUDED_ACCOUNT_ID>"],AccountFilterType=DIFFERENCE' \
  --regions <YOUR_REGION>
実行結果

ここでは Child1OU(ou-0orw-kitll1ta) をターゲットOUに追加し、配下に所属するアカウント(80XXXXXXXX71)を除外します。

aws cloudformation create-stack-instances \
> --stack-set-name example-stacksets \
> --deployment-targets 'OrganizationalUnitIds=["ou-0orw-kitll1ta"],Accounts=["80XXXXXXXX71"],AccountFilterType=DIFFERENCE' \
> --regions "ap-northeast-1"

{
    "OperationId": "485b0d0b-29f3-4fa0-92f4-e556678b2585"
}

こちらも同様にStackSetsコンソールでCREATEオペレーションが確認できます。この時、除外アカウントとして指定したアカウントが表示されていないことを確認してください。

03-1-stacksets-auto-deploy-target-change

CREATEオペレーションが完了するとStackSetの情報から指定したOUが新しいターゲットOUとして登録されていることを確認できます。

03-2-stacksets-auto-deploy-target-change

4. 変更後のスタックインスタンスを一覧化取得

ここで1. 変更前のスタックインスタンスを一覧取得で取得したスタックインスタンスと比較用に変更後のスタックインスタンスの一覧を取得します。

aws cloudformation list-stack-instances \
  --stack-set-name <YOUR_STACK_SETS_NAME> \
  --query 'Summaries[].[Account,StackId]' \
  --output table
実行結果

今回の環境ではスタックインスタンスが何も存在しないため返り値なしになります。

aws cloudformation list-stack-instances \
>   --stack-set-name example-stacksets \
>   --query 'Summaries[].[Account,StackId]' \
>   --output table

5. ターゲットOU配下アカウントのスタックをインポート

最後にターゲットOU配下に存在するアカウントのスタックをStackSetsのスタックインスタンスとしてインポートします。

インポートの際には仕様としてNoEchoプロパティを含むスタックはインポートできない点についてはご注意ください。

NoEcho プロパティは StackSet インポートにサポートされていません。NoEcho を含むスタックは、StackSet のインポートを介して新しいスタックセットにインポートされません。
AWS CloudFormation StackSets へのスタックのインポート - AWS CloudFormation

1. 変更前のスタックインスタンスを一覧取得4. 変更後のスタックインスタンスを一覧化取得で取得したスタックインスタンス一覧を比較して、新しいターゲットOUに存在するアカウントのスタックをインポートします。

ここでは、Child1OU配下のアカウント(80XXXXXXXX71)のスタックをインポートします。

aws cloudformation import-stacks-to-stack-set \
  --stack-set <YOUR_STACK_SETS_NAME> \
  --stack-ids "<EXISTING_ACCOUNT_STACK_ID_1>" "<EXISTING_ACCOUNT_STACK_ID_2>"... \
  --organizational-unit-ids "<NECESSARY_UNIT_ID>"

実行結果は以下の通りです。

aws cloudformation import-stacks-to-stack-set \
>   --stack-set example-stacksets \
>   --stack-ids "arn:aws:cloudformation:ap-northeast-1:80XXXXXXXX71:stack/StackSet-s3-stacksets-7a6b2867-fdb6-4487-a9bd-63d3313cbf9e/4f564ce0-3aa7-11ef-98aa-0a0ff7db0b5" \
>   --organizational-unit-ids "ou-0orw-kitll1ta"
{
    "OperationId": "bd0077a8-36b7-4d04-917c-25fa1a096cba"
}

StackSetsコンソールでIMPORTオペレーションが確認できます。

04-stacksets-auto-deploy-target-change

無事、IMPORTが完了するとスタックインスタンスとして表示されます。

05-stacksets-auto-deploy-target-change

インポートまでできればターゲットOUの変更は完了です。

最後に

今回はStackSetsの自動デプロイのターゲットOUを変更する方法について紹介しました。

ちなみにAPIにはupdate-stack-setといういかにもStackSets更新用のAPIもあるのですが、こちらではターゲットOUだけの変更はできません。
(テンプレートの差し替えやパラメータの置き換えで使用する)

目的としてはターゲットOUを変更するだけなのですが、StackSetsの仕様上スタックインスタンスの削除が発生するので作業には注意が必要です。

StackSetsの適用範囲は下位OUに適用することで万が一の修正も影響範囲を狭めることができるので、そういった設計部分からも注意していきたいなと思いました。

こちらの内容がどなたかのお役に立てれば幸いです。

以上、たかやま(@nyan_kotaroo)でした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.