Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 44 additions & 13 deletions packages/@aws-cdk/aws-ecs/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,20 +183,51 @@ export class Cluster extends Resource implements ICluster {
this._hasEc2Capacity = true;
this.connections.connections.addSecurityGroup(...autoScalingGroup.connections.securityGroups);

// Tie instances to cluster
autoScalingGroup.addUserData(`echo ECS_CLUSTER=${this.clusterName} >> /etc/ecs/ecs.config`);

if (!options.canContainersAccessInstanceRole) {
// Deny containers access to instance metadata service
// Source: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html
autoScalingGroup.addUserData('sudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP');
autoScalingGroup.addUserData('sudo service iptables save');
// The following is only for AwsVpc networking mode, but doesn't hurt for the other modes.
autoScalingGroup.addUserData('echo ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config');
}
if ( autoScalingGroup.osType === ec2.OperatingSystemType.WINDOWS ) {

// clear the cache of the agent
autoScalingGroup.addUserData('Remove-Item -Recurse C:\\ProgramData\\Amazon\\ECS\\Cache');

// pull the latest ECS Tools
autoScalingGroup.addUserData('Import-Module ECSTools');

// set the cluster name environment variable
autoScalingGroup.addUserData(`[Environment]::SetEnvironmentVariable("ECS_CLUSTER", "${this.clusterName}", "Machine")`);
autoScalingGroup.addUserData('[Environment]::SetEnvironmentVariable("ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE", "true", "Machine")');
// tslint:disable-next-line: max-line-length
autoScalingGroup.addUserData('[Environment]::SetEnvironmentVariable("ECS_AVAILABLE_LOGGING_DRIVERS", "[\"json-file\",\"awslogs\"]", "Machine")');

// enable instance draining
if (autoScalingGroup.spotPrice && options.spotInstanceDraining) {
autoScalingGroup.addUserData('[Environment]::SetEnvironmentVariable("ECS_ENABLE_SPOT_INSTANCE_DRAINING", "true", "Machine")');
}

// enable task iam role
if (!options.canContainersAccessInstanceRole) {
autoScalingGroup.addUserData('[Environment]::SetEnvironmentVariable("ECS_ENABLE_TASK_IAM_ROLE", "true", "Machine")');
autoScalingGroup.addUserData(`Initialize-ECSAgent -Cluster '${this.clusterName}' -EnableTaskIAMRole'`);
} else {
autoScalingGroup.addUserData(`Initialize-ECSAgent -Cluster '${this.clusterName}'`);
}

} else {

// Tie instances to cluster
autoScalingGroup.addUserData(`echo ECS_CLUSTER=${this.clusterName} >> /etc/ecs/ecs.config`);

if (!options.canContainersAccessInstanceRole) {
// Deny containers access to instance metadata service
// Source: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html
autoScalingGroup.addUserData('sudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP');
autoScalingGroup.addUserData('sudo service iptables save');
// The following is only for AwsVpc networking mode, but doesn't hurt for the other modes.
autoScalingGroup.addUserData('echo ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config');
}

if (autoScalingGroup.spotPrice && options.spotInstanceDraining) {
autoScalingGroup.addUserData('echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config');
}

if (autoScalingGroup.spotPrice && options.spotInstanceDraining) {
autoScalingGroup.addUserData('echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config');
}

// ECS instances must be able to do these things
Expand Down
53 changes: 53 additions & 0 deletions packages/@aws-cdk/aws-ecs/test/test.ecs-cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,59 @@ export = {
test.done();
},

"configures userdata with powershell if windows machine image is specified"(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'MyVpc', {});

const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
cluster.addCapacity('WindowsAutoScalingGroup', {
instanceType: new ec2.InstanceType('t2.micro'),
machineImage: new ecs.EcsOptimizedAmi({
windowsVersion: ecs.WindowsOptimizedVersion.SERVER_2019,
}),
});

// THEN
expect(stack).to(haveResource("AWS::AutoScaling::LaunchConfiguration", {
ImageId: {
Ref: "SsmParameterValueawsserviceecsoptimizedamiwindowsserver2019englishfullrecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter"
},
InstanceType: "t2.micro",
IamInstanceProfile: {
Ref: "EcsClusterWindowsAutoScalingGroupInstanceProfile65DFA6BB"
},
SecurityGroups: [
{
"Fn::GetAtt": [
"EcsClusterWindowsAutoScalingGroupInstanceSecurityGroupDA468DF1",
"GroupId"
]
}
],
UserData: {
"Fn::Base64": {
"Fn::Join": [
"",
[
"<powershell>Remove-Item -Recurse C:\\ProgramData\\Amazon\\ECS\\Cache\nImport-Module ECSTools\n[Environment]::SetEnvironmentVariable(\"ECS_CLUSTER\", \"",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own edification, where are the <powershell> tags being specified? I'm not seeing it in the changes to cluster.ts.

{
Ref: "EcsCluster97242B84"
},
"\", \"Machine\")\n[Environment]::SetEnvironmentVariable(\"ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE\", \"true\", \"Machine\")\n[Environment]::SetEnvironmentVariable(\"ECS_AVAILABLE_LOGGING_DRIVERS\", \"[\"json-file\",\"awslogs\"]\", \"Machine\")\n[Environment]::SetEnvironmentVariable(\"ECS_ENABLE_TASK_IAM_ROLE\", \"true\", \"Machine\")\nInitialize-ECSAgent -Cluster '",
{
Ref: "EcsCluster97242B84"
},
"' -EnableTaskIAMRole'</powershell>"
]
]
}
}
}));

test.done();
},

/*
* TODO:v2.0.0 BEGINNING OF OBSOLETE BLOCK
*/
Expand Down