Reputation: 93
I am attempting to spin up an ec2 instance using AWS CDK, for the most part it works great but I want the userData to persist so it runs on each boot... Annoyingly this is not documented (anywhere I can find) and I just cant figure out where/how to define it. Below is my code that works but because the userdata is by forWindows()
I cannot just add xxx.addCommands('<persist>true</persist>')
because the forWindows() puts the code in tags...
// Instance details
const ssmaUserData = UserData.forWindows()
ssmaUserData.addCommands('mkdir -p C:/helloworld; ');
const ec2Instance = new ec2.Instance(this, 'SdkInstance', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
machineImage: awsAMI,
securityGroup: mySecurityGroup,
vpcSubnets: {subnetType: ec2.SubnetType.PUBLIC},
keyName: "EC2Connect",
userData: ssmaUserData
});
I have attempted to use ssmaUserData.addOnExitCommands("<persist>true</persist>")
and variants of that but without success, anyone know how to get this done?
Below are the logs that indicate that this is not running with persistence...
2021/03/11 12:56:51Z: Userdata execution begins
2021/03/11 12:56:51Z: Zero or more than one <persist> tag was not provided
2021/03/11 12:56:51Z: Unregistering the persist scheduled task
2021/03/11 12:56:55Z: Zero or more than one <runAsLocalSystem> tag was not provided
2021/03/11 12:56:55Z: Zero or more than one <script> tag was not provided
2021/03/11 12:56:55Z: Zero or more than one <powershellArguments> tag was not provided
2021/03/11 12:56:55Z: <powershell> tag was provided.. running powershell content
2021/03/11 13:08:34Z: Userdata execution begins
2021/03/11 13:08:34Z: Zero or more than one <persist> tag was not provided
2021/03/11 13:08:34Z: Unregistering the persist scheduled task
2021/03/11 13:08:37Z: Zero or more than one <runAsLocalSystem> tag was not provided
2021/03/11 13:08:37Z: Zero or more than one <script> tag was not provided
2021/03/11 13:08:37Z: Zero or more than one <powershellArguments> tag was not provided
2021/03/11 13:08:37Z: <powershell> tag was provided.. running powershell content
2021/03/11 13:08:42Z: Message: The output from user scripts:
Upvotes: 1
Views: 6098
Reputation: 465
Have you tried adding userDataCausesReplacement: true I got the same problem before, adding userDataCausesReplacement made it worked.
// Instance details
const ssmaUserData = UserData.forWindows()
ssmaUserData.addCommands('mkdir -p C:/helloworld; ');
const ec2Instance = new ec2.Instance(this, 'SdkInstance', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
machineImage: awsAMI,
securityGroup: mySecurityGroup,
vpcSubnets: {subnetType: ec2.SubnetType.PUBLIC},
keyName: "EC2Connect",
userData: ssmaUserData,
userDataCausesReplacement: true
});
Upvotes: 0
Reputation: 4907
To avoid writing all the script in a string, you can use the methods provided, specially if you want to do things like S3 download.
When you're done with the UserData, just get the script and append the flag.
Example (in python, but can be done in the same way in typescript):
instance_userdata = ec2.UserData.for_windows()
#... do lots os actions like: instance_userdata.add_s3_download_command(...)
data_script = instance_userdata.render()
#https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html#user-data-execution
data_script += "<persist>true</persist>"
persistent_userdata = ec2.UserData.custom(data_script)
Upvotes: 0
Reputation: 93
Got it! So whenever I used the UserData.forWindows()
which is well documented by AWS it would automatically add the <PowerShell>
tags which mean if I defined <Persist>
it would be encompass the tag... To get around this I needed to use UserData.custom()
instead. I have tested the code below and it is working a great!
const script = `
<powershell>
Start-Transcript -OutputDirectory C:/
Write-Output HelloWorld
Stop-Transcript
</powershell>
<persist>true</persist>
`;
const ssmaUserData = UserData.custom(script)
const ec2Instance = new ec2.Instance(this, 'SdkInstance', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
machineImage: awsAMI,
securityGroup: mySecurityGroup,
vpcSubnets: {subnetType: ec2.SubnetType.PUBLIC},
keyName: "EC2Connect",
userData: ssmaUserData,
});
Upvotes: 4