Skip to content

Commit fd5ff76

Browse files
authored
feat(ecs): implement IConnectable interface for ManagedInstancesCapacityProvider (#35745)
### Issue # (if applicable) Call out from #35742 ManagedInstancesCapacityProvider should implement IConnectable to make managing the SGs for the provider easier. This was missed in the initial PR. ### Reason for this change Implement IConnectable for ManagedInstancesCapacityProvider. ManagedInstancesCapacityProvider makes use of EC2 security groups, so it should implement this interface. ### Description of changes Implement IConnectable for ManagedInstancesCapacityProvider ### Describe any new or updated permissions being added None ### Description of how you validated changes Modified and deployed integ test ### Checklist - [X] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 807b3de commit fd5ff76

File tree

9 files changed

+129
-11
lines changed

9 files changed

+129
-11
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.managedinstances-capacity-provider.js.snapshot/integ-managedinstances-capacity-provider.assets.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.managedinstances-capacity-provider.js.snapshot/integ-managedinstances-capacity-provider.template.json

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@
438438
{
439439
"Ref": "AWS::Partition"
440440
},
441-
":iam::aws:policy/AdministratorAccess"
441+
":iam::aws:policy/AmazonECSInfrastructureRolePolicyForManagedInstances"
442442
]
443443
]
444444
}
@@ -470,7 +470,7 @@
470470
{
471471
"Ref": "AWS::Partition"
472472
},
473-
":iam::aws:policy/AdministratorAccess"
473+
":iam::aws:policy/AmazonECSInstanceRolePolicyForManagedInstances"
474474
]
475475
]
476476
}
@@ -500,6 +500,34 @@
500500
"IpProtocol": "-1"
501501
}
502502
],
503+
"SecurityGroupIngress": [
504+
{
505+
"CidrIp": {
506+
"Fn::GetAtt": [
507+
"Vpc8378EB38",
508+
"CidrBlock"
509+
]
510+
},
511+
"Description": {
512+
"Fn::Join": [
513+
"",
514+
[
515+
"from ",
516+
{
517+
"Fn::GetAtt": [
518+
"Vpc8378EB38",
519+
"CidrBlock"
520+
]
521+
},
522+
":80"
523+
]
524+
]
525+
},
526+
"FromPort": 80,
527+
"IpProtocol": "tcp",
528+
"ToPort": 80
529+
}
530+
],
503531
"VpcId": {
504532
"Ref": "Vpc8378EB38"
505533
}

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.managedinstances-capacity-provider.js.snapshot/integ.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.managedinstances-capacity-provider.js.snapshot/manifest.json

Lines changed: 21 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.managedinstances-capacity-provider.js.snapshot/tree.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.managedinstances-capacity-provider.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ const infrastructureRole = new iam.Role(stack, 'InfrastructureRole', {
2424
roleName: 'AmazonECSInfrastructureRoleForOmakase',
2525
assumedBy: new iam.ServicePrincipal('ecs.amazonaws.com'),
2626
managedPolicies: [
27-
iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
27+
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInfrastructureRolePolicyForManagedInstances'),
2828
],
2929
});
3030

3131
const instanceRole = new iam.Role(stack, 'InstanceRole', {
3232
roleName: 'AmazonECSInstanceRoleForOmakase',
3333
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
3434
managedPolicies: [
35-
iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
35+
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInstanceRolePolicyForManagedInstances'),
3636
],
3737
});
3838

@@ -63,6 +63,9 @@ const miCapacityProvider = new ecs.ManagedInstancesCapacityProvider(stack, 'Mana
6363
},
6464
});
6565

66+
// Configure security group rules using IConnectable interface
67+
miCapacityProvider.connections.allowFrom(ec2.Peer.ipv4(vpc.vpcCidrBlock), ec2.Port.tcp(80));
68+
6669
// Add FMI capacity provider to cluster
6770
cluster.addManagedInstancesCapacityProvider(miCapacityProvider);
6871
cluster.addDefaultCapacityProviderStrategy([

packages/aws-cdk-lib/aws-ecs/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,9 @@ const miCapacityProvider = new ecs.ManagedInstancesCapacityProvider(this, 'MICap
16871687
propagateTags: ecs.PropagateManagedInstancesTags.CAPACITY_PROVIDER,
16881688
});
16891689

1690+
// Optionally configure security group rules using IConnectable interface
1691+
miCapacityProvider.connections.allowFrom(ec2.Peer.ipv4(vpc.vpcCidrBlock), ec2.Port.tcp(80));
1692+
16901693
// Add the capacity provider to the cluster
16911694
cluster.addManagedInstancesCapacityProvider(miCapacityProvider);
16921695

packages/aws-cdk-lib/aws-ecs/lib/cluster.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1653,7 +1653,7 @@ export interface ManagedInstancesCapacityProviderProps {
16531653
* Managed Instances for task placement with managed infrastructure.
16541654
*/
16551655
@propertyInjectable
1656-
export class ManagedInstancesCapacityProvider extends Construct {
1656+
export class ManagedInstancesCapacityProvider extends Construct implements ec2.IConnectable {
16571657
/**
16581658
* Uniquely identifies this class.
16591659
*/
@@ -1664,6 +1664,11 @@ export class ManagedInstancesCapacityProvider extends Construct {
16641664
*/
16651665
readonly capacityProviderName: string;
16661666

1667+
/**
1668+
* The network connections associated with this resource.
1669+
*/
1670+
readonly connections: ec2.Connections;
1671+
16671672
/**
16681673
* The CloudFormation capacity provider resource
16691674
*/
@@ -1738,6 +1743,10 @@ export class ManagedInstancesCapacityProvider extends Construct {
17381743

17391744
this.capacityProviderName = this.capacityProvider.ref;
17401745

1746+
this.connections = new ec2.Connections({
1747+
securityGroups: props.securityGroups,
1748+
});
1749+
17411750
this.node.defaultChild = this.capacityProvider;
17421751
}
17431752

packages/aws-cdk-lib/aws-ecs/test/cluster.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3264,6 +3264,59 @@ describe('cluster', () => {
32643264
}).toThrow(/Invalid Capacity Provider Name: fargatecp, If a name is specified, it cannot start with aws, ecs, or fargate./);
32653265
});
32663266

3267+
test('allows modifying security groups via IConnectable interface', () => {
3268+
// GIVEN
3269+
const app = new cdk.App();
3270+
const stack = new cdk.Stack(app, 'test');
3271+
const vpc = new ec2.Vpc(stack, 'Vpc');
3272+
3273+
const infrastructureRole = new iam.Role(stack, 'InfrastructureRole', {
3274+
assumedBy: new iam.ServicePrincipal('ecs.amazonaws.com'),
3275+
managedPolicies: [
3276+
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInfrastructureRolePolicyForManagedInstances'),
3277+
],
3278+
});
3279+
3280+
const instanceRole = new iam.Role(stack, 'InstanceRole', {
3281+
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
3282+
managedPolicies: [
3283+
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInstanceRolePolicyForManagedInstances'),
3284+
],
3285+
});
3286+
3287+
const instanceProfile = new iam.InstanceProfile(stack, 'InstanceProfile', {
3288+
role: instanceRole,
3289+
});
3290+
3291+
const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', {
3292+
vpc,
3293+
description: 'Test security group',
3294+
});
3295+
3296+
// WHEN
3297+
const capacityProvider = new ecs.ManagedInstancesCapacityProvider(stack, 'provider', {
3298+
infrastructureRole,
3299+
ec2InstanceProfile: instanceProfile,
3300+
subnets: vpc.privateSubnets,
3301+
securityGroups: [securityGroup],
3302+
});
3303+
3304+
// Use connections API to allow inbound traffic
3305+
capacityProvider.connections.allowFrom(ec2.Peer.anyIpv4(), ec2.Port.tcp(80));
3306+
3307+
// THEN
3308+
Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', {
3309+
SecurityGroupIngress: [
3310+
{
3311+
IpProtocol: 'tcp',
3312+
FromPort: 80,
3313+
ToPort: 80,
3314+
CidrIp: '0.0.0.0/0',
3315+
},
3316+
],
3317+
});
3318+
});
3319+
32673320
test('can add Managed Instances capacity via Capacity Provider', () => {
32683321
// GIVEN
32693322
const app = new cdk.App();

0 commit comments

Comments
 (0)