CloudFormation StackSets let you deploy your infrastructure as code to multiple AWS accounts and regions simultaneously. The most surprising thing about StackSets is how often they’re used reactively to fix compliance drift, rather than proactively to establish baseline configurations.
Let’s see StackSets in action. Imagine you need to ensure all your AWS accounts have a specific IAM policy attached to a shared service role, and you want this policy to be identical across the entire organization.
Here’s a simplified AWS::CloudFormation::StackSet resource in a CloudFormation template:
Resources:
MyOrgWidePolicyStackSet:
Type: AWS::CloudFormation::StackSet
Properties:
StackSetName: OrgWideIAMPolicyEnforcement
Description: Deploys IAM policy for shared service role across all accounts.
TemplateURL: https://my-s3-bucket.s3.amazonaws.com/iam-policy-template.yaml
PermissionModel: SERVICE_MANAGED
AutoDeployment:
Enabled: true
RetainStacksOnAccountRemoval: false
DeploymentTargets:
OrganizationalUnits:
- ou-abcdef123456
# ManagedExecution:
# Active: true # Only needed for SERVICE_MANAGED if not auto-deploying
# Parameters:
# PolicyName:
# - "MySharedServicePolicy"
# RoleName:
# - "SharedServiceRole"
This StackSet will take the CloudFormation template located at TemplateURL and deploy it to all accounts within the ou-abcdef123456 Organizational Unit. SERVICE_MANAGED permission model means CloudFormation assumes roles in the target accounts automatically using service-linked roles. AutoDeployment: Enabled: true means new accounts added to this OU will automatically get the stack deployed.
Now, what does iam-policy-template.yaml look like?
AWSTemplateFormatVersion: '2010-09-09'
Description: IAM policy for shared service role.
Parameters:
PolicyName:
Type: String
Description: Name of the IAM policy to create.
RoleName:
Type: String
Description: Name of the IAM role to attach the policy to.
Resources:
SharedServiceRolePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Ref PolicyName
Roles:
- !Ref RoleName
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "s3:GetObject"
- "s3:ListBucket"
Resource:
- arn:aws:s3:::my-shared-bucket/*
- arn:aws:s3:::my-shared-bucket
- Effect: Allow
Action:
- "ec2:DescribeInstances"
Resource: "*"
When you deploy the StackSet, you can provide values for PolicyName and RoleName. For example, you might specify PolicyName: "MySharedServicePolicy" and RoleName: "SharedServiceRole". CloudFormation then orchestrates the creation of these IAM resources in each account within the specified OU.
The DeploymentTargets property is where you define where the stacks are deployed. You can target specific AWS accounts by Account ID, or use Organizational Units (OUs) to target entire branches of your AWS Organization. For SERVICE_MANAGED permission model, you’ll need to have the AWSCloudFormationStackSetAdministrationAccess and AWSCloudFormationStackSetExecutionAccess service-linked roles already created in your organization. If you don’t have them, CloudFormation will prompt you to create them.
The PermissionModel is crucial. SERVICE_MANAGED is generally preferred for organizational deployments as it simplifies role management. CloudFormation automatically creates and manages the necessary IAM roles in the target accounts. The alternative is SELF_MANAGED, where you are responsible for creating and managing the IAM roles in each target account that grant StackSets permission to deploy resources. This is more complex and error-prone for large-scale deployments.
The AutoDeployment section is powerful for maintaining a desired state. When Enabled: true, any account added to the specified OUs after the StackSet is created will automatically have the stack deployed to it. RetainStacksOnAccountRemoval: false means that if an account is removed from an OU targeted by the StackSet, the deployed stack in that account will be deleted. Setting this to true would leave the stack in place, which can be useful for auditing but can lead to drift if not managed.
One common pitfall is understanding how DeploymentTargets interacts with AutoDeployment. If you specify a list of specific AccountIds under DeploymentTargets, AutoDeployment has no effect on those accounts. AutoDeployment only applies when you target OrganizationalUnits.
The true power of StackSets lies in their ability to enforce configuration drift. By setting up auto-deployment for compliance-related templates (e.g., ensuring specific VPC endpoints are present, or that S3 buckets have encryption enabled), you can automatically remediate deviations from your desired baseline across your entire organization.
The next concept you’ll likely explore is handling drift detection and manual remediation for StackSets, especially when auto-deployment isn’t feasible or desired for certain configurations.