Enable adding custom user data to ECS cluster
See original GitHub issueCurrently, adding additional user data to an Autoscaling group and adding it to an ECS cluster is not a smooth experience.
The implementation of autoscalinggroup.addUserData()
does not correctly process MIME multitype archives. E.g.:
const asg = new autoscaling.AutoScalingGroup(this, 'MyFleet', {
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.M4, ec2.InstanceSize.Large),
machineImage: new ec2.AmazonLinuxImage(),
associatePublicIpAddress: true,
vpc
});
const userData = `
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt
--//
`
asg.addUserData(userData);
cluster.addAutoScalingGroupCapacity(asg);
Results in the following CFN for LaunchConfiguration:
MyFleetLaunchConfig5D7F9801:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: ami-01e24be29428c15b2
InstanceType: m4.large
AssociatePublicIpAddress: true
IamInstanceProfile:
Ref: MyFleetInstanceProfile70A58496
KeyName: hhh-2
SecurityGroups:
- Fn::GetAtt:
- MyFleetInstanceSecurityGroup774E8234
- GroupId
UserData:
Fn::Base64:
Fn::Join:
- ""
- - |-
#!/bin/bash
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt
--//
echo ECS_CLUSTER=
- Ref: Ec2ClusterEE43E89D
- >-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
When deployed, the User Data on the ec2 instance looks like this:
#!/bin/bash
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt
--//
echo ECS_CLUSTER=CustomUserData-Ec2ClusterEE43E89D-1H8KFTDM00P66 >> /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
It should look like this:
Content-Type: multipart/mixed; boundary="36b51cd254c2a10606cc4ea1d7c161a960c25b43fbcf3f2275bfea986b64"
MIME-Version: 1.0
--36b51cd254c2a10606cc4ea1d7c161a960c25b43fbcf3f2275bfea986b64
Content-Disposition: attachment; filename="cloud-config.txt"
Content-Transfer-Encoding: 7bit
Content-Type: text/cloud-config; charset="us-ascii"
Mime-Version: 1.0
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--36b51cd254c2a10606cc4ea1d7c161a960c25b43fbcf3f2275bfea986b64
Content-Disposition: attachment; filename="userdata.txt"
Content-Transfer-Encoding: 7bit
Content-Type: text/x-shellscript; charset="us-ascii"
Mime-Version: 1.0
#!/bin/bash
/bin/echo "Hello World" >> /tmp/testfile.txt
--36b51cd254c2a10606cc4ea1d7c161a960c25b43fbcf3f2275bfea986b64
Content-Type: text/text/x-shellscript; charset="utf-8"
Mime-Version: 1.0
#!/bin/bash
echo ECS_CLUSTER=blargh >> /etc/ecs/ecs.config
--36b51cd254c2a10606cc4ea1d7c161a960c25b43fbcf3f2275bfea986b64--
The above was generated using the ECS-cli with custom user data flag:
ecs-cli up --extra-user-data custom-user-data.txt --cluster blargh --capability-iam
Though the ECS CLI is able to leverage some go libraries for MIME multipart archive constructing/unpacking.
It would nice to have a smoother API around adding custom user data – not sure if that’s better served through an integration with a higher-level ECS construct or modifying the existing API in the Autoscaling library.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:4
- Comments:21 (13 by maintainers)
Top GitHub Comments
@kristianmandrup, This property is a getter (it’s a function), it can give undefined value if the capacity has not been defined in props, during creation of cluster (that’s one way of defining capacity).
If you use method addCapacity to add a capacity (instead of props), then the result value is an autoscaling group (cluster can be associated with multiple ASG) and you can use it to operate on user data.
As a side note, there’s new set of changes enabling capacity providers, AFIK.
Custom user data generously supplied by @hoegertn should give you a way to achieve what you need:
https://github.com/aws/aws-cdk/pull/4193
@marcb still interested to hear in what you need to achieve that cfn-init can not cover in the same way that userdata would?