CloudFormation StackSetsの自動デプロイターゲットOUを変更してみた
こんにちは。たかやまです。
CloudFormation StackSetsではサービスマネージド型のデプロイを利用することで、OrganizationsのOUをターゲットに自動デプロイを設定することができます。
サービスマネージド型のアクセス許可を持つスタックセットの自動デプロイの管理 - AWS CloudFormation
今回はStackSetsの自動デプロイのターゲットOUをすでに設定/運用している環境で、ターゲットOUを変更する場合の方法と気をつけるべき点について紹介したいと思います。
さきにまとめ
- StackSetsの既存の自動デプロイターゲットOUを変更するには
delete-stack-instances
を実行する必要があり、一度スタックインスタンスの管理から外す必要がある - 新たな自動デプロイターゲットOUを設定は
create-stack-instances
を実行する- 新しいターゲットOUにすでにスタックが存在するアカウントがある場合には
AccountFilterType
を指定してスタックが存在するアカウントを除外する
- 新しいターゲットOUにすでにスタックが存在するアカウントがある場合には
- 既存のスタックをStackSetsのスタックインスタンスとして管理する場合にはインポートを実施する
NoEcho
プロパティを含むスタックはStackSetsへのインポートができないので注意
やってみる
更新のイメージ
今回は ParentOU
-> Child1OU
ターゲットOUに変更する流れになります。
イメージは以下のとおり
おおまかな流れは以下のとおりです。
- 変更前のスタックインスタンスを一覧取得
- 不要なターゲットOUを削除
- 新たなターゲットOUを追加
- 変更後のスタックインスタンスを一覧化取得
- ターゲット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
をつけているためスタックは削除されていません。
ちなみに、イメージでいう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オペレーションが確認できます。この時、除外アカウントとして指定したアカウントが表示されていないことを確認してください。
CREATEオペレーションが完了するとStackSetの情報
から指定したOUが新しいターゲットOUとして登録されていることを確認できます。
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オペレーションが確認できます。
無事、IMPORTが完了するとスタックインスタンスとして表示されます。
インポートまでできればターゲットOUの変更は完了です。
最後に
今回はStackSetsの自動デプロイのターゲットOUを変更する方法について紹介しました。
ちなみにAPIにはupdate-stack-setといういかにもStackSets更新用のAPIもあるのですが、こちらではターゲットOUだけの変更はできません。
(テンプレートの差し替えやパラメータの置き換えで使用する)
目的としてはターゲットOUを変更するだけなのですが、StackSetsの仕様上スタックインスタンスの削除が発生するので作業には注意が必要です。
StackSetsの適用範囲は下位OUに適用することで万が一の修正も影響範囲を狭めることができるので、そういった設計部分からも注意していきたいなと思いました。
こちらの内容がどなたかのお役に立てれば幸いです。
以上、たかやま(@nyan_kotaroo)でした。