I was helping a customer deploy the AWS Landing Zone Accelerator (LZA) to 15 member accounts last week. The pipeline succeeded in the management account, but when it tried to deploy to the member accounts, it failed with cryptic CloudFormation errors. After checking CDK bootstrap stacks and cross-account IAM roles, we discovered three member accounts were missing the bootstrap stack entirely. In this post, I’ll walk through exactly what causes LZA member account deployment failures and how to fix them.

The Problem

Your LZA CodePipeline runs successfully in the management account, but fails when deploying to specific member accounts. You see CloudFormation errors like:

  • Stack:arn:aws:cloudformation:us-east-1:123456789012:stack/AWSAccelerator-xxxxxxxx does not exist
  • User: arn:aws:iam::123456789012:role/aws-accelerator-role is not authorized to perform: cloudformation:CreateStack
  • Network CIDR range 10.0.0.0/16 is already in use
Error Type Root Cause
Stack does not exist CDK bootstrap CloudFormation stack missing
Not authorized Cross-account IAM role lacks assume permissions
CIDR conflict Network config overlaps with existing VPCs
VPC limit exceeded Account has reached max VPCs per region

Why Does This Happen?

The LZA uses AWS CDK, which requires a bootstrap CloudFormation stack in every target account and region before it can deploy. Additionally, the LZA assumes cross-account roles in member accounts to perform deployments. If these prerequisites aren’t met, deployments fail:

  • Missing CDK bootstrap stack: The CDKToolkit CloudFormation stack must exist in the target account/region. Without it, CDK has nowhere to store template artifacts and can’t deploy infrastructure.
  • Insufficient cross-account permissions: The LZA uses AWSControlTowerExecution or a custom cross-account role. If the trust relationship doesn’t allow the management account to assume it, deployments fail.
  • Network configuration conflicts: If your network-config.yaml specifies CIDR ranges that already exist in the target account, CloudFormation will fail to create the VPC.
  • Service quotas exceeded: AWS accounts have default limits (5 VPCs per region, 5 EIPs per region). If the target account is near or at these limits, deployment fails.
  • Target account/region mismatch: If your accounts-config.yaml lists a region that doesn’t match the deployment regions in network-config.yaml, the pipeline will try to deploy resources in an account/region pair that doesn’t exist.

The Fix

Step 1: Identify the Failed Account and Region

Check the LZA CodePipeline execution to see which account/region combination failed:

aws codepipeline list-pipeline-executions \
  --pipeline-name aws-accelerator-pipeline \
  --region us-east-1

Click the failed execution in the console. Look at the stage names—they’re formatted like Deploy-123456789012-us-east-1. This tells you the account and region that failed.

Step 2: Verify CDK Bootstrap in Target Account

Log into the target account and check if the bootstrap stack exists:

# First, assume the cross-account role
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/AWSControlTowerExecution \
  --role-session-name lza-check \
  --duration-seconds 3600

# Then list CloudFormation stacks
aws cloudformation list-stacks \
  --region us-east-1 \
  --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE

Look for a stack named CDKToolkit. If it doesn’t exist, you need to bootstrap the account:

# Still in the assumed role session, run CDK bootstrap
npx cdk bootstrap aws://123456789012/us-east-1 \
  --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess

Repeat this for every account/region pair that failed. Check your accounts-config.yaml to see which regions are enabled per account.

Step 3: Verify Cross-Account Trust Relationship

Ensure the cross-account role has the correct trust relationship:

# In the target account, describe the role
aws iam get-role \
  --role-name AWSControlTowerExecution

# Get the trust policy
aws iam get-role-policy \
  --role-name AWSControlTowerExecution \
  --policy-name AssumeRolePolicy

The trust policy should allow the management account to assume the role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::MANAGEMENT-ACCOUNT-ID:role/aws-accelerator-role"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

If the trust policy is incorrect, update it:

aws iam update-assume-role-policy \
  --role-name AWSControlTowerExecution \
  --policy-document file://trust-policy.json

Step 4: Check Network Configuration

Review your network-config.yaml to ensure CIDR ranges don’t conflict:

# In target account, list existing VPCs
aws ec2 describe-vpcs \
  --region us-east-1 \
  --query 'Vpcs[].CidrBlock'

If your network config specifies a CIDR that already exists, edit network-config.yaml and choose a non-overlapping range. Then retry the pipeline.

Step 5: Check Service Quotas

Verify you haven’t hit VPC or EIP limits:

# Check VPC quota
aws service-quotas get-service-quota \
  --service-code vpc \
  --quota-code L-F678F1CE \
  --region us-east-1

# Check EIP quota
aws service-quotas get-service-quota \
  --service-code ec2 \
  --quota-code L-0287A674 \
  --region us-east-1

If you’re near the limit, request an increase:

aws service-quotas request-service-quota-increase \
  --service-code vpc \
  --quota-code L-F678F1CE \
  --desired-value 20 \
  --region us-east-1

Step 6: Retry the Pipeline

Once all prerequisites are met:

aws codepipeline start-pipeline-execution \
  --pipeline-name aws-accelerator-pipeline \
  --region us-east-1

Is This Safe?

Bootstrapping accounts and verifying IAM roles is safe. Requesting service quota increases is also safe—they’re typically approved within minutes. Just avoid changing network CIDR ranges without careful planning.

Key Takeaway

LZA member account deployment failures usually stem from missing CDK bootstrap stacks, cross-account role trust issues, or network configuration conflicts. Always bootstrap every account/region combination, verify cross-account trust relationships, and ensure your network config doesn’t conflict with existing VPCs before retrying.


Have questions or ran into a different LZA issue? Connect with me on LinkedIn or X.