Skip to content

cdk: deploy fails when VPC lands in an AgentCore-unsupported availability zone #353

Description

@AshrafBen10

Component

CDK / infrastructure

Describe the bug

On a fresh cdk deploy, the AWS::BedrockAgentCore::Runtime resource fails to stabilize and the stack rolls back when the auto-selected VPC subnets fall in an availability zone that AgentCore does not support. AgentVpc (cdk/src/constructs/agent-vpc.ts) only sets maxAzs: 2, so CDK selects the first two AZs by name (us-east-1a, us-east-1b). AZ names are aliased per-account to physical zone IDs, and AgentCore only allows specific physical zones. When an account's us-east-1a maps to an unsupported zone (e.g. use1-az6), deploy fails.

Expected behavior

cdk deploy should place the AgentCore Runtime subnets only in AgentCore-supported availability zones, so a fresh deploy succeeds regardless of how the account's AZ names map to physical zone IDs.

Current behavior

Deploy proceeds through most resource creation, then fails and rolls back:

Resource handler returned message: "Agent runtime creation failed with status:
CREATE_FAILED for runtime: backgroundagentdevRuntimeCC6E3A5A-UJ4CYSE0GV.
Reason: The following subnets are in unsupported availability zones in region
us-east-1: subnet-070f4a8f2871b9ed9 in us-east-1a (ID: use1-az6).
Supported availability zones are: use1-az4, use1-az1, use1-az2"
(HandlerErrorCode: NotStabilized)

For the affected account, the AZ name to zone ID mapping was:

us-east-1a -> use1-az6  (AgentCore unsupported)
us-east-1b -> use1-az1  (supported)
us-east-1c -> use1-az2  (supported)
us-east-1d -> use1-az4  (supported)
us-east-1e -> use1-az3  (unsupported)
us-east-1f -> use1-az5  (unsupported)

CDK picked us-east-1a + us-east-1b; the first is unsupported, so the Runtime failed to create.

Reproduction steps

  1. Use an AWS account whose us-east-1a maps to use1-az3, use1-az5, or use1-az6 (check with the detection command below).
  2. Run mise run //cdk:deploy in us-east-1 with the default AgentVpc configuration (no AZ override).
  3. Observe the AWS::BedrockAgentCore::Runtime CREATE_FAILED / ROLLBACK_COMPLETE.

Detection one-liner:

aws ec2 describe-availability-zones --region us-east-1 \
  --query 'AvailabilityZones[?ZoneName==`us-east-1a`].ZoneId' --output text
# use1-az3 / use1-az5 / use1-az6 => account is affected

Possible solution

Either:

  1. Auto-select supported AZs at synth time — intersect the account's available AZs with an AgentCore supported-zone list (per region) and pin the VPC to that intersection. Most robust.
  2. Expose an availabilityZones prop and document the requirement — cheaper.

Minimal version of option 2 (prototyped locally to unblock):

cdk/src/constructs/agent-vpc.ts — add optional availabilityZones to AgentVpcProps, use it when provided:

this.vpc = new ec2.Vpc(this, 'Vpc', {
  ...(props.availabilityZones
    ? { availabilityZones: props.availabilityZones }
    : { maxAzs: props.maxAzs ?? 2 }),
  // ...
});

cdk/src/stacks/agent.ts — pass supported AZs (account-specific):

const agentVpc = new AgentVpc(this, 'AgentVpc', {
  availabilityZones: ['us-east-1b', 'us-east-1c'], // use1-az1, use1-az2
});

The default (maxAzs: 2, no pinning) is effectively a gamble for any account whose us-east-1a does not map to a supported zone; AWS does not guarantee a stable name to zone-ID mapping across accounts. The hardcoded list above is account-specific and would need to be auto-detected for a general fix.

Node version

22.22.3

mise version

2026.6.0

AWS region

us-east-1

Local modifications

Yes — prototyped the option-2 override locally (availabilityZones prop on AgentVpc, pinned to us-east-1b/us-east-1c) to unblock deployment; deploy then reached CREATE_COMPLETE. Happy to open a PR, or adapt to the auto-detect approach if preferred.

Additional context

Severity: blocker for affected accounts; wastes ~10 minutes per attempt plus the cost of partial resource creation before rollback. AZ names are randomized per-account aliases over physical zone IDs, which is why this is account-specific rather than universal. Observed on main (commit e3abe92).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions