Skip to content

aws-ec2: Removal of -EnableTaskIAMRole parameter has broken ECS container host registration on Windows #36805

@caveman-dick

Description

@caveman-dick

Describe the bug

The change to this line has removed the -EnableTaskIAMRole parameter which is required for Windows container hosts:

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html#windows_task_IAM_roles

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Library Version

2.32.2

Expected Behavior

Container hosts are correctly registered with ECS

Current Behavior

Currently the container host seems to be registered correctly with the ECS cluster. However they are missing the required com.amazonaws.ecs.capability.task-iam-role attribute which means not tasks can be started on the instance. If tasks are attempted to be created and there is not enough capacity in the remaining cluster instance that are registered correctly, they they fail with TaskFailedToStart: ATTRIBUTE

As the change of the user-data triggers a rebuild of the cluster instances the cluster gets into a hung state of the old instances trying to drain but they can't because there are no container hosts that can run the tasks that are trying to be evicted:

Image

Reproduction Steps

import * as cdk from 'aws-cdk-lib';
import * as autoscaling from 'aws-cdk-lib/aws-autoscaling';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as iam from 'aws-cdk-lib/aws-iam';
import type { Construct } from 'constructs';

export class MinimalWindowsClusterStack extends cdk.Stack {
    constructor(scope: Construct) {
        super(scope, 'WindowsClusterMinimal');

        const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 2 });

        const clusterName = 'windows';

        const cluster = new ecs.Cluster(this, 'Cluster', {
            clusterName,
            vpc,
        });

        const taskDefinition = new ecs.TaskDefinition(
            this,
            'TaskDefinition',
            {
                compatibility: ecs.Compatibility.EC2,
                cpu: '512',
                memoryMiB: '1024',
                runtimePlatform: {
                    operatingSystemFamily:
                        ecs.OperatingSystemFamily.WINDOWS_SERVER_2022_CORE,
                },
            },
        );

        taskDefinition.addContainer('App', {
            image: ecs.ContainerImage.fromRegistry(
                'mcr.microsoft.com/windows/servercore:ltsc2022',
            ),
            memoryReservationMiB: 512,
            portMappings: [
                {
                    containerPort: 80,
                    protocol: ecs.Protocol.TCP,
                },
            ],
        });

        const instanceRole = new iam.Role(this, 'InstanceRole', {
            assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
        });
        instanceRole.addManagedPolicy(
            iam.ManagedPolicy.fromAwsManagedPolicyName(
                'service-role/AmazonEC2ContainerServiceforEC2Role',
            ),
        );

        const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplate', {
            instanceType: ec2.InstanceType.of(
                ec2.InstanceClass.T3A,
                ec2.InstanceSize.XLARGE2,
            ),
            machineImage: ecs.EcsOptimizedImage.windows(
                ecs.WindowsOptimizedVersion.SERVER_2022,
            ),
            role: instanceRole,
            userData: ec2.UserData.forWindows(),
        });

        const autoScalingGroup = new autoscaling.AutoScalingGroup(
            this,
            'AutoScalingGroup',
            {
                vpc,
                minCapacity: 1,
                maxCapacity: 2,
                launchTemplate,
            },
        );

        const capacityProvider = new ecs.AsgCapacityProvider(
            this,
            'AsgCapacityProvider',
            {
                autoScalingGroup,
                capacityProviderName: 'EC2_WINDOWS_2022',
            },
        );

        cluster.addAsgCapacityProvider(capacityProvider);

        new ecs.Ec2Service(this, 'Service', {
            cluster,
            taskDefinition,
            desiredCount: 1,
            capacityProviderStrategies: [
                {
                    capacityProvider: capacityProvider.capacityProviderName,
                    weight: 1,
                },
            ],
        });
    }
}

Possible Solution

Re-instate the required attribute for windows container hosts.

Additional Information/Context

No response

AWS CDK Library version (aws-cdk-lib)

2.235.1

AWS CDK CLI version

2.1033.0

Node.js Version

24.4.4

OS

Windows

Language

TypeScript

Language Version

5.9.2

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    @aws-cdk/aws-ec2Related to Amazon Elastic Compute CloudbugThis issue is a bug.effort/smallSmall work item – less than a day of effortfeature-requestA feature should be added or improved.p1

    Type

    No type
    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