組織のスケールにインフラが崩壊する前に:CloudFormation StackSetsでマルチアカウント・マルチリージョンを完全自動統御する実践アーキテクチャ
こんにちは。テックリードの私だ。
君たちの組織では、AWSアカウントが増えるたびに手動でマネージャーコンソールをポチポチしたり、各アカウントにバラバラのTerraform/CloudFormationコードをコピペして回ったりしていないだろうか?
「本番環境が3つ、検証環境が10個、サンドボックスが数え切れない……。セキュリティベースラインを全アカウントに強制適用するだけで今週が終わった」——もし心当たりがあるなら、今すぐその非効率な手作業を止めろ。
マルチアカウント戦略(AWS Organizations)を採用した瞬間から、インフラの構成管理は「単一アカウントの美しさ」ではなく「組織全体への一括統御(Governance at Scale)」のゲームに変わる。
今回は、AWS CloudFormation StackSetsの真の実力を引き出し、マルチアカウント・マルチリージョン環境へインフラを原子性(Atomicity)を持って自動展開する、現場の生血が通った実践アーキテクチャを伝授する。
—
1. StackSetsの全体像と「なぜマネジメントアカウント直叩きは悪手なのか」
StackSetsは、1つのCloudFormationテンプレートを、複数のAWSアカウント・複数のリージョンに対して一括でデプロイ・更新・削除するための仕組みだ。
しかし、ここで多くのジュニア〜ミドルクラスのエンジニアが最初の地雷を踏む。
「AWS Organizationsのマネジメントアカウント(Root)から直接StackSetsを実行する」という設計だ。
これはセキュリティー上の大罪であり、SREの観点からは悪夢でしかない。マネジメントアカウントが万が一侵害された場合、組織全体の全リソースが敵の手に落ちる。
【極限のベストプラクティス】デプロイメント専用の「Shared Services (Tooling) アカウント」の分離
StackSetsのオーケストレーションは、必ず管理用のアカウント(通常は `Shared Services` や `Tooling` と呼ばれるデプロイ専用アカウント)から実行させるべきだ。
[Tooling Account (Delegated Administrator)]
│
├──(信頼関係: IAM / Organizations API)
│
├──> [Target Account A] (US-EAST-1 / AP-NORTHEAST-1)
├──> [Target Account B] (US-EAST-1 / AP-NORTHEAST-1)
└──> [Target Account C] (US-EAST-1 / AP-NORTHEAST-1)
AWS OrganizationsのDelegated Administrator(委任管理者)機能を使用し、ToolingアカウントにStackSetsの権限を移譲するのが現代のデファクトスタンダードだ。
—
2. ハマりどころの連続:IAM権限(ExecutionRole & AdministrationRole)の完全理解
StackSetsが裏側で何をやっているかを理解していないと、必ず「Reason: The IAM role is not valid or does not exist」というエラーに夜間叩き起こされることになる。
StackSetsのデプロイには、主に2つのロールが関与する。
1. AWSCloudFormationStackSetAdministrationRole: 管理アカウント(または委任管理者アカウント)に作成され、ターゲットアカウントへのAssumeRoleを行うロール。
2. AWSCloudFormationStackSetExecutionRole: ターゲットアカウントの「全て」に作成され、CloudFormationが実際にリソースを作成・変更・削除するための権限を持つロール。
自動展開(Service-managed permissions)の罠
手動でロールを作り込む `Self-managed permissions` は今や遺物だ。AWS Organizationsと完全に統合された Service-managed permissions を使え。これによって、新しいアカウントが Organizations に追加された瞬間、自動的にターゲットアカウントへ `AWSCloudFormationStackSetExecutionRole` がプロビジョニングされる。
ただし、Organizations側での信頼関係の設定と、適切なSCP(Service Control Policies)のバイパスを忘れると、自動展開は静かに失敗する。
—
3. 実践:組織全体へベースラインを配布するCloudFormationテンプレート
ここでは、すべてのターゲットアカウントに「全リージョン共通で必ず配置すべきセキュリティベースライン(例: Configの有効化、GuardDutyの強制)」をデプロイする実用的なYAMLの構成例を示す。
テンプレート例: `baseline-security.yaml`
AWSTemplateFormatVersion: ‘2010-09-09’
Description: >
[SRE-PROD] Enterprise Security Baseline StackSet
This template is automatically deployed to all target accounts and regions.
Parameters:
EnvironmentType:
Type: String
Default: Production
AllowedValues: [Production, Staging, Development]
Description: Specifies the target environment type for tagging.
Resources:
# 1. 意図せぬS3バケットのパブリック公開を防ぐアカウントレベルのブロック
AccountBlockPublicAccess:
Type: AWS::S3::AccountPublicAccessBlock
Properties:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
# 2. ログ保管用の暗号化KMSキー(組織共通ポリシー)
CentralLogEncryptionKey:
Type: AWS::KMS::Key
Properties:
Description: “SRE Standard Encryption Key for regional logs”
EnableKeyRotation: true
KeyPolicy:
Version: ‘2012-10-17’
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub “arn:aws:iam::${AWS::AccountId}:root”
Action: “kms:”
Resource: “”
- Sid: Allow CloudWatch Logs to use the key
Effect: Allow
Principal:
Service: !Sub “logs.${AWS::Region}.amazonaws.com”
Action:
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt
- kms:GenerateDataKey
- kms:Describe
Resource: “”
Outputs:
EncryptionKeyArn:
Description: “ARN of the centralized KMS key for regional logs”
Value: !GetAtt CentralLogEncryptionKey.Arn
Export:
Name: !Sub “${AWS::StackName}-EncryptionKeyArn”
—
4. チーム開発を加速するプロの実践テクニック
ここからは、日常的にIaCを書き殴るプロのエンジニアたちが使っている、開発スピードを極限まで高めるためのエコシステム設定を共有する。
① VS Codeの神プラグイン選抜
- AWS Toolkit for Visual Studio Code: テンプレートのシンタックスチェックや、デプロイ状況をGUIを汚さずにエディタ内で完結させるために必須。
- CloudFormation Linter (cfn-lint): デプロイする前にローカルで静的解析を行う。文法ミスや存在しないプロパティの指定をCI/CDに乗せる前に叩き潰す。
- YAML/Jinja Support: インデントの崩壊を防ぐ。CloudFormationにおけるタブ・スペースの混入は死を意味する。
② チームで共有すべき `cfnlintrc` 設定ファイル
プロジェクトのルートに以下の `.cfnlintrc` を配置し、チーム全員のLintルールを強制せよ。
.cfnlintrc
—
無視するエラーコード(例: 組織のポリシー上あえて許可している項目など)
ignore_checks:
- W3002 # Basic styling checks if necessary
対象とするリージョン
regions:
- ap-northeast-1
- us-east-1
テンプレートのパースを厳密に行う
include_checks:
- I # インデントやフォーマット関連
③ デプロイを自動化する AWS CLI / Makefile のスニペット
手動でAWSコンソールからStackSetsを操作するなど言語道断だ。すべてコード(Git)で管理し、Makefile経由で冪等にデプロイする。
Makefile
STACKSET_NAME=EnterpriseSecurityBaseline
ADMIN_ACCOUNT=111122223333
REGION=ap-northeast-1
.PHONY: deploy update
create-stackset:
aws cloudformation create-stack-set \
–stack-set-name $(STACKSET_NAME) \
–template-body file://baseline-security.yaml \
–permission-model SERVICE_MANAGED \
–auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
–capabilities CAPABILITY_NAMED_IAM \
–region $(REGION)
update-stackset:
aws cloudformation update-stack-set \
–stack-set-name $(STACKSET_NAME) \
–template-body file://baseline-security.yaml \
–capabilities CAPABILITY_NAMED_IAM \
–region $(REGION)
deploy-instances:
aws cloudformation create-stack-instances \
–stack-set-name $(STACKSET_NAME) \
–deployment-targets OrganizationalUnitIds='[“ou-xxxx-yyyyyyyy”]’ \
–regions ‘[“ap-northeast-1”, “us-east-1”]’ \
–operation-preferences FailureToleranceCount=0,MaxConcurrentPercentage=100 \
–region $(REGION)
—
5. 現場の修羅場から導き出した「運用上の教訓」
最後に、StackSets運用において数々の障害を踏み抜いてきた者からのアドバイスだ。
1. ConcurrenceとFailureToleranceのチューニングを怠るな
アカウント数が50を超えたあたりから、デフォルトの並行度(Concurrence)やエラー許容数(FailureTolerance)のままだとデプロイに数時間かかるか、一部のアカウントでデッドロックが起きる。`MaxConcurrentPercentage=100` と `FailureToleranceCount=0`(厳格な適用の場合)のバランスを組織の規模に合わせて調整しろ。
2. ドリフト(Drift)検出を定期実行せよ
「誰かが本番環境で直接リソースを書き換えた」という恐怖の瞬間は必ず訪れる。`aws cloudformation detect-stack-set-drift` をEventBridgeとStep Functionsで定期実行し、Slackへ即座に通知するパイプラインを必ず構築すること。
まとめ
マルチアカウント・マルチリージョン環境のインフラ管理は、もはや根性や手作業で維持できる領域を超えている。
CloudFormation StackSetsの仕組みを深く理解し、適切な権限委譲と自動展開、そしてコード化されたデプロイフロー(IaCパイプライン)を構築することで、君のチームは「インフラの維持管理」という無駄な呪縛から解放され、「真に価値のあるプロダクト開発」へとリソースを集中させることができるはずだ。
さあ、今すぐコンソールを閉じ、エディタを開け。