If ECS AutoScalingGroup is used with Windows containers, resulting UserData has invalid commands, not applicable to Windows nodes:
<powershell>
echo ECS_CLUSTER=win-cluster611F8AFF-UX2YM1DXYE1E >> /etc/ecs/ecs.config
sudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP
sudo service iptables save
echo ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config
</powershell>
There is no way to override this, as far as I can tell. Here is the responsible code:
Here is the snippet (in C#, TypeScript would be a direct equivalent):
```c#
var userData = UserData.ForWindows();
// It is necessary to run this command to join the cluster
userData.AddCommands($"Initialize-ECSAgent -Cluster {cluster.ClusterName} -EnableTaskIAMRole -LoggingDrivers '[\"json-file\",\"awslogs\"]'");
var autoScalingGroup = new AutoScalingGroup(this, "autoScalingGroup", new AutoScalingGroupProps
{
// ...
UserData = userData
});
cluster.AddAutoScalingGroup(autoScalingGroup);
Resulting CloudFormation:
```yaml
UserData:
Fn::Base64:
Fn::Join:
- ""
- - "<powershell>Initialize-ECSAgent -Cluster "
- Ref: cluster611F8AFF
- >-2
-EnableTaskIAMRole -LoggingDrivers '["json-file","awslogs"]'
echo ECS_CLUSTER=
- Ref: cluster611F8AFF
- >-2
>> /etc/ecs/ecs.config
sudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP
sudo service iptables save
echo ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config</powershell>
I believe what we are trying to do here is to codify the best practices for cluster nodes so CDK customer does not need to worry about these details. The problem is that the best practices are different between Linux and Windows platforms.
At the moment Windows cluster nodes have to be configured manually, according to AWS docs.
It would be great to incorporate these guidelines into CDK to streamline ECS cluster creation for Windows AMIs.
Is there a workaround to this?
I have the same issue and I'm unable to figure out a way to drill down to the cfn resource and add a property override.
@amit-polyglot PowerShell commands you put in user data _are_ getting executed, regardless of the invalid (for Windows instances) linux-based commands present. That's the default behavior for PowerShell scripts.
So the code I provided in the bug description above actually works - the Windows instance is getting registered with ECS cluster. Proper solution would be to incorporate the correct commands for Windows instances, as described in the documentation so you don't need to do this manually in your CDK app.
I figured out how to mutate the user data.
const launchConfig = asg.node.findChild('LaunchConfig') as CfnLaunchConfiguration;
const userDataScript = '<powershell>Import-Module ECSTools' + '\n' + `Initialize-ECSAgent -Cluster ${ecsCluster.clusterName} -EnableTaskIAMRole</powershell>`+ '\n' +'<persist>true</persist>';
launchConfig.addPropertyOverride('UserData', Fn.base64(userDataScript));
Is there a workaround to this?
I have the same issue and I'm unable to figure out a way to drill down to the cfn resource and add a property override.
I had a similar issue on an AmazonLinux2 ECS AMI, it doesn't allow service iptables save, workaround should be to define the canContainersAccessInstanceRole property when adding the asg to the cluster...
cluster.addAutoScalingGroup(asgAppliance, {canContainersAccessInstanceRole: true,});
Most helpful comment
I figured out how to mutate the user data.