🕌

AWS CloudFormation StackSet を AWS Organizations 配下に AWS CLI でデプロイ

2023/11/07に公開

概要

CloudFormation の StackSets を使用すると、複数のアカウント・リージョンに同一テンプレート定義からスタックをデプロイすることができます。
参考) AWS CloudFormation StackSets の操作

使用例

実際にデプロイするテンプレートは例として以下にサンプルが用意されているように、Organizations 内のアカウントにセキュリティ上のガードレールを設定したり監査用に証跡を取得するなどの管理用が主なユースケースのようです。

参考) AWS CloudFormation StackSets のサンプルテンプレート

  • AWS Config の設定して、リソースの変更履歴を記録、セキュリティ上のチェックをおこなう
  • AWS CloudTrail を設定して API 呼び出しを記録する

手順

環境変数の設定

以降のコマンドで使用する環境変数を以下のように設定しておきます。

STACK_NAME=StackSetTest
TEMPLATE_URL=https://s3.amazonaws.com/xxxxxxxxxxxx/template.yml
TARGET_OU=ou-xxxx-xxxxxxxx
TARGET_REGIONS="us-east-1 ap-northeast-1"
  • STACK_NAME : 作成する StackSet の名前
  • TEMPLATE_URL : CloudFormation テンプレートの S3 URL (https:// から始まる)
  • TARGET_OU : デプロイ先 Organization Unit の ID
  • TARGET_REGIONS : デプロイ先リージョン

Trusted Access を有効化

AWS Organizations 内のアカウントに一括デプロイできるようにするには、Organization の管理アカウントで Trusted Acess を有効化しておきます。これにより Organizations の各アカウントに必要な権限を持った Service-linked role が作成されます。

aws cloudformation activate-organizations-access

StackSet を作成

Organization の管理アカウントにて、StackSet を作成します。

aws cloudformation create-stack-set \
    --stack-set-name "${STACK_NAME}" \
    --capabilities CAPABILITY_IAM \
    --template-url "${TEMPLATE_URL}" \
    --permission-model SERVICE_MANAGED \
    --auto-deployment "Enabled=true,RetainStacksOnAccountRemoval=false" \
    --managed-execution "Active=true"
  • --permission-model SERVICE_MANAGED を指定すると、IAM ロールまわりの設定なしに管理アカウントからメンバーアカウントへのデプロイをおこなうことができます。
  • --auto-deploymentEnabled=true を指定すると OU にアカウントが追加されたときに自動的にスタックをデプロイ、RetainStacksOnAccountRemoval=false を指定すると OU からアカウントが削除されたときに自動的にスタックを削除します。
  • --managed-execution "Active=true" を指定すると、可能な範囲で並列実行されます。デフォルトではひとつずつ実行されます。

作成した StackSet から Organization Unit 内の全アカウントにスタックをデプロイします。

aws cloudformation create-stack-instances \
    --stack-set-name "${STACK_NAME}" \
    --deployment-targets "OrganizationalUnitIds=${TARGET_OU}" \
    --regions ${TARGET_REGIONS}

テンプレートを編集して StackSet を更新するには以下のようにします。

aws cloudformation update-stack-set \
    --stack-set-name "${STACK_NAME}" \
    --template-url "${TEMPLATE_URL}"

StackSet を削除

削除する前に、デプロイ済みのスタックを削除します。

aws cloudformation delete-stack-instances \
    --stack-set-name "${STACK_NAME}" \
    --deployment-targets "OrganizationalUnitIds=${TARGET_OU}" \
    --regions ${TARGET_REGIONS} \
    --no-retain-stacks

すべてのスタックが削除されたら、StackSet を削除します。

aws cloudformation delete-stack-set \
    --stack-set-name "${STACK_NAME}"

参考) サンプル StackSet の構成

AWS Config の有効化 (EnableAWSConfig)

EnableAWSConfig StackSet

  • 単一のアカウント・リージョンに保存先 S3 バケット、通知先 SNS トピックを作成します。
  • SNS トピックは外部に用意してパラメーターで指定することもできます。(後述と同様)

中央ログで AWS Config を有効にする (EnableAWSConfigForOrganizations)

EnableAWSConfigForOrganizations StackSet

  • S3 バケット、SNS トピックを別のアカウントに作成しておき、CloudFormation パラメーターに指定します。
  • S3 バケット、SNS トピックにはクロスアカウントで書き込むために適切なリソースポリシーを設定する必要があります。このサンプルでは Service-linked role を使用しているため、書き込みを許可するメンバーアカウント ID をすべて指定する必要があります。Organizations ID を指定してまとめて制限するには管理アカウントに IAM ロールを作り、それを AWS Config が使用するよう修正する必要があります。
  • SNS トピックはスタックのデプロイ先と同じリージョンである必要があるため、必然的に複数リージョンにはデプロイできません。リージョンごとに送信先トピックを変更するよう修正する必要があります。

Discussion