Skip to content

Instantly share code, notes, and snippets.

@kritro
Last active October 27, 2021 22:35
Show Gist options
  • Save kritro/e91a9ac05c3172d6279da3ae02e3efb2 to your computer and use it in GitHub Desktop.
Save kritro/e91a9ac05c3172d6279da3ae02e3efb2 to your computer and use it in GitHub Desktop.
//define the initData that will be used when creating the instance, this describes all the commands that will be ran on the instance
const initData = ec2.CloudFormationInit.fromElements(
// ec2.InitFile.fromUrl("c:\\cfn\\mysql.msi", "https://downloads.mysql.com/archives/get/p/25/file/mysql-installer-community-8.0.24.0.msi"),
ec2.InitFile.fromAsset("c:\\cfn\\BootstrapScript.ps1", "./BootstrapScript.ps1"),
ec2.InitFile.fromAsset("c:\\cfn\\CreateADGroups.ps1", "./CreateADGroups.ps1"),
ec2.InitPackage.msi("https://s3.amazonaws.com/aws-cli/AWSCLI64.msi"),
ec2.InitCommand.shellCommand('powershell.exe [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(\'https://chocolatey.org/install.ps1\'))', { key: "1-InstallChoco", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(5)) }),
ec2.InitCommand.shellCommand("powershell.exe -Command Rename-Computer (Get-EC2Tag -Filter @{Name='resource-id'; Values=(Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).Content}).Where({$_.Key -eq 'Name'}).Value", { key: "2-RenameComputer", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(5)) }),
ec2.InitCommand.shellCommand('powershell.exe -Command Restart-Service AmazonSSMAgent"', { key: "3-RestartSSMAgent", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(5)) }),
ec2.InitCommand.shellCommand('powershell.exe Add-EC2Volume -InstanceId (Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).Content -VolumeId ' + dVolume.volumeId + ' -Device ' + targetDevice + ' -Region ' + process.env.CDK_DEFAULT_REGION, { key: "4-AttachVolume", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(60)) }),
ec2.InitCommand.shellCommand('powershell.exe -File "c:\\cfn\\BootstrapScript.ps1"', { key: "5-install", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(10)) }),
ec2.InitCommand.shellCommand('powershell.exe -Command Send-SSMCommand -InstanceId (Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).Content -DocumentName ' + domainJoinDocument + ' -TimeoutSecond 600 -Region ' + process.env.CDK_DEFAULT_REGION, { key: "6-DomainJoinServer", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(60)) }),
ec2.InitCommand.shellCommand('powershell.exe -Command Restart-Computer -force', { key: "6-Restart", waitAfterCompletion: ec2.InitCommandWaitDuration.forever() }),
// // ec2.InitCommand.shellCommand('powershell.exe -File "c:\\cfn\\CreateADGroups.ps1"', { key: "7-CreateADGroups", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(5)) }),
ec2.InitCommand.shellCommand('powershell.exe -Command Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False', { key: "7-DisableFirewall", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(10)) }),
ec2.InitCommand.shellCommand('powershell.exe -File C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeDisks.ps1', { key: "8-Initialize", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(5)) }),
// ec2.InitCommand.shellCommand('msiexec /q /log c:\\cfn\\log\\mysql-install.log /i "C:\\cfn\\mysql.msi"', { key: "91-installMysql", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(30)) }),
ec2.InitCommand.shellCommand('powershell.exe choco install mysql -y', { key: "9-installMysql", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(30)) }),
ec2.InitCommand.shellCommand('cfn-signal.exe -e %ERRORLEVEL% --resource appmysqlserver --stack ' + this.stackId + ' --region ' + this.region, { key: "91-Signal", waitAfterCompletion: ec2.InitCommandWaitDuration.of(cdk.Duration.seconds(5)) })
)
@alam-musa
Copy link

Hi, I was following your example of using userdata as shown above. But I am running into issue where my EC2 is not sending the data back to SSM home before it is calling the userdata, and due to that CDK getting the failed signal back and doesnt continue with deployment.
Are you able to guide me how to resolve this please? Thanks

@kritro
Copy link
Author

kritro commented Oct 13, 2021 via email

@kritro
Copy link
Author

kritro commented Oct 13, 2021

Hi, I was following your example of using userdata as shown above. But I am running into issue where my EC2 is not sending the data back to SSM home before it is calling the userdata, and due to that CDK getting the failed signal back and doesnt continue with deployment. Are you able to guide me how to resolve this please? Thanks

What do you mean by ssm home? are you able to get into the instance and check the c:\cfn\log\cfn-init.log ?
regards

@alam-musa
Copy link

Hello, Sorry didn't reply earlier. When you spin up an EC2 instance it has an SSM agent which then send signal AWS saying I am up and running.
in my case I am spinning up 3 windows ec2 instance and one of them I tried to include user data. Those ec2s didnt have user data they came up find but the one with user data didnt work also I wasnt able to connect to the instance as SSM agent seems like wasnt up and running. I will send you the code for review. Hope this all explains my situation? Thanks.

@alam-musa
Copy link

Hi again managed to get the logs: seems like send ssm-command is not getting the instance ID. Wondering if we need to introduce wait?

2021-10-14 02:13:48,030 [DEBUG] Creating Scheduled Task for cfn-init resume
2021-10-14 02:13:48,499 [DEBUG] Scheduled Task created
2021-10-14 02:13:48,499 [INFO] Running configSets: default
2021-10-14 02:13:48,499 [INFO] Running configSet default
2021-10-14 02:13:48,499 [INFO] Running config config
2021-10-14 02:13:48,499 [DEBUG] No packages specified
2021-10-14 02:13:48,499 [DEBUG] No groups specified
2021-10-14 02:13:48,499 [DEBUG] No users specified
2021-10-14 02:13:48,499 [DEBUG] No sources specified
2021-10-14 02:13:48,499 [DEBUG] No files specified
2021-10-14 02:13:48,515 [DEBUG] No services specified
2021-10-14 02:13:48,562 [DEBUG] Running command 1-DisableFirewall
2021-10-14 02:13:48,562 [DEBUG] No test for command 1-DisableFirewall
2021-10-14 02:13:50,954 [INFO] Command 1-DisableFirewall succeeded
2021-10-14 02:13:50,954 [DEBUG] Command 1-DisableFirewall output:
2021-10-14 02:13:50,954 [INFO] Waiting 10 seconds for reboot
2021-10-14 02:14:01,008 [DEBUG] Running command 2-DomainJoin
2021-10-14 02:14:01,008 [DEBUG] No test for command 2-DomainJoin
2021-10-14 02:14:44,720 [ERROR] Command 2-DomainJoin (powershell.exe -Command Send-SSMCommand -InstanceId (Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).Content -DocumentName -TimeoutSecond 600 -Region us-east-2) failed
2021-10-14 02:14:44,720 [DEBUG] Command 2-DomainJoin output: Send-SSMCommand : The service returned an error with Error Code InvalidInstanceId and HTTP Body:

{"__type":"InvalidInstanceId"}

At line:1 char:1

  • Send-SSMCommand -InstanceId (Invoke-WebRequest http://169.254.169.254 ...

  • 
      + CategoryInfo          : InvalidOperation: (Amazon.PowerShe...SMCommandCmdlet:SendSSMCommandCmdlet) [Send-SSMComm 
    
     and], InvalidOperationException
    
      + FullyQualifiedErrorId : Amazon.SimpleSystemsManagement.Model.InvalidInstanceIdException,Amazon.PowerShell.Cmdlet 
    
     s.SSM.SendSSMCommandCmdlet
    
    
    
    
    

2021-10-14 02:14:44,720 [ERROR] Error encountered during build of config: Command 2-DomainJoin failed
Traceback (most recent call last):
File "cfnbootstrap\construction.pyc", line 575, in run_config
File "cfnbootstrap\construction.pyc", line 144, in run_commands
File "cfnbootstrap\command_tool.pyc", line 127, in apply
cfnbootstrap.construction_errors.ToolError: Command 2-DomainJoin failed
2021-10-14 02:14:44,736 [ERROR] -----------------------BUILD FAILED!------------------------
2021-10-14 02:14:44,736 [ERROR] Unhandled exception during build: Command 2-DomainJoin failed
Traceback (most recent call last):
File "cfn-init", line 176, in
File "cfnbootstrap\construction.pyc", line 135, in build
File "cfnbootstrap\construction.pyc", line 561, in build
File "cfnbootstrap\construction.pyc", line 575, in run_config
File "cfnbootstrap\construction.pyc", line 144, in run_commands
File "cfnbootstrap\command_tool.pyc", line 127, in apply
cfnbootstrap.construction_errors.ToolError: Command 2-DomainJoin failed

@kritro
Copy link
Author

kritro commented Oct 27, 2021

Sorry for late reply.
Have you tried to run
(Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).Content
localy on the instance to se if its able to resolve the instance id?
If it does, maybe it has something todo with qoutes.

@alam-musa
Copy link

Hi Thanks for replying,
I have tried several different ways to make this script work.
Script does work internally within the instance but it doesnt work when it tries to execute by calling cfn-int function within my CDK project.
I also tried to run the same command using the AWS UI systems manager --> automation this also works.
This is very weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment