Skip to content

[AWS::ECS::CapacityProvider] - [BUG] - SecurityGroups in ManagedInstancesNetworkConfiguration is Required, not Optional #2433

@garysassano

Description

@garysassano

Name of the resource

AWS::ECS::CapacityProvider

Resource Name

No response

Issue Description

Bug Description

There is a discrepancy between the CloudFormation documentation and the actual ECS API behavior for AWS::ECS::CapacityProvider with Managed Instances.

The CloudFormation documentation states that SecurityGroups is "Required: No" (see attached screenshot), but the actual ECS API rejects capacity provider creation without security groups:

Invalid request provided: CreateCapacityProvider error: Managed Instances capacity provider must specify a Network Configuration that contain security groups
(Service: Ecs, Status Code: 400, Request ID: 22245e8f-d8d8-4874-af93-2f3c13716ef2)

This causes CloudFormation deployments to fail even when following the documented schema.

Reproduction Steps

CDK Code

import { Size, Stack } from "aws-cdk-lib";
import { CpuManufacturer, SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";
import { Cluster, ManagedInstancesCapacityProvider } from "aws-cdk-lib/aws-ecs";
import { InstanceProfile, ManagedPolicy, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam";
import type { Construct } from "constructs";

export class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    super(scope, id, props);

    const vpc = new Vpc(this, "Vpc", {
      maxAzs: 2,
      natGateways: 1,
      subnetConfiguration: [
        {
          name: "Public",
          subnetType: SubnetType.PUBLIC,
          cidrMask: 18,
        },
        {
          name: "Private",
          subnetType: SubnetType.PRIVATE_WITH_EGRESS,
          cidrMask: 18,
        },
      ],
    });

    const cluster = new Cluster(this, "ManagedInstancesCluster", {
      vpc,
    });

    const instanceRole = new Role(this, "InstanceRole", {
      assumedBy: new ServicePrincipal("ec2.amazonaws.com"),
      managedPolicies: [
        ManagedPolicy.fromAwsManagedPolicyName("AmazonECSInstanceRolePolicyForManagedInstances"),
      ],
    });

    const instanceProfile = new InstanceProfile(this, "InstanceProfile", {
      role: instanceRole,
    });

    const miCapacityProvider = new ManagedInstancesCapacityProvider(this, "MICapacityProvider", {
      ec2InstanceProfile: instanceProfile,
      subnets: vpc.privateSubnets,
      instanceRequirements: {
        vCpuCountMin: 1,
        memoryMin: Size.gibibytes(2),
        cpuManufacturers: [CpuManufacturer.AMD],
      },
    });

    cluster.addManagedInstancesCapacityProvider(miCapacityProvider);
  }
}

Deployment Command

cdk deploy

Error Output

1:35:46 AM | CREATE_FAILED        | AWS::ECS::CapacityProvider            | MICapacityProviderC44A5890
Resource handler returned message: "Invalid request provided: CreateCapacityProvider error: Managed Instances capacity provider must specify a Network Configuration that contain security groups (Service: Ecs, Status Code: 400, Request ID: 22245e8f-d8d8-4874-af93-2f3c13716ef2) (SDK Attempt Count: 1)" (RequestToken: fa766a71-1b28-7fe6-e26b-9d6025f645ef, HandlerErrorCode: InvalidRequest)

❌  cdk-aws-ecs-managed-instance-dev failed: ToolkitError: The stack named cdk-aws-ecs-managed-instance-dev failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: Resource handler returned message: "Invalid request provided: CreateCapacityProvider error: Managed Instances capacity provider must specify a Network Configuration that contain security groups (Service: Ecs, Status Code: 400, Request ID: 22245e8f-d8d8-4874-af93-2f3c13716ef2) (SDK Attempt Count: 1)" (RequestToken: fa766a71-1b28-7fe6-e26b-9d6025f645ef, HandlerErrorCode: InvalidRequest)

Expected Behavior

One of the following should be corrected:

Option 1: Update Documentation (Most Likely)

The CloudFormation documentation should be updated to reflect that SecurityGroups is "Required: Yes" in the ManagedInstancesNetworkConfiguration property, matching the actual API validation behavior.

Option 2: Update API Validation

The ECS API should be updated to make SecurityGroups truly optional as the documentation claims, potentially using a default security group if none is specified.

Root Cause Analysis

The issue appears to be one of:

  1. Documentation Bug: The CloudFormation docs incorrectly state SecurityGroups as optional when it's actually required by the ECS API
  2. API Validation Bug: The ECS API incorrectly enforces security groups as required when they should be optional per the documentation

Based on the error message, Option 1 (documentation bug) seems most likely, as the API explicitly validates for security groups.

Environment

  • CDK CLI Version: 2.x (latest)
  • CDK Lib Version: 2.230.0
  • Framework Version: aws-cdk-lib 2.230.0
  • Node.js Version: 24.11.1
  • Operating System: Linux
  • Language: TypeScript 5.9.3

Impact

This documentation discrepancy affects:

  • CloudFormation users who follow the docs and omit security groups (deployment fails)
  • AWS CDK users using the L2 ManagedInstancesCapacityProvider construct (currently doesn't expose security groups property, likely because docs say it's optional)
  • AWS SAM users creating ECS Managed Instances capacity providers
  • Terraform users via the AWS provider

Evidence of Discrepancy

CloudFormation Documentation States:

SecurityGroups:
  Required: No
  Type: Array of String
  Update requires: No interruption

Actual ECS API Behavior:

Error: "Managed Instances capacity provider must specify a Network Configuration 
that contain security groups"
Status Code: 400

Suggested Fix

Update the CloudFormation documentation at:
https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-ecs-capacityprovider-managedinstancesnetworkconfiguration.html

Change:

SecurityGroups:
  Required: No  ❌ (Incorrect)

To:

SecurityGroups:
  Required: Yes  ✅ (Matches actual API behavior)

Additional Notes

Once the documentation is corrected, the AWS CDK team can then properly update the ManagedInstancesCapacityProvider L2 construct to expose the required securityGroups property.

Until this is resolved, users must either:

  • Use L1 constructs (CfnCapacityProvider) with explicit security groups, or
  • Use escape hatches to manually add the security groups configuration

Related CloudFormation Documentation:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions