Troubleshooting Windows EC2 instance user-data

Often while we are troubleshooting for EC2 user data, we want to have visibility to what happens to the script at launch. Whether it failed or which line of code is not executing by the instance.

We usually have to RDP to see the log itself or use Session Manager to connect to the instance. But we often found the SSM agent is not running. It is quite frustrating and time-consuming to fix every hurdle to get to the log file.

So in this article, I'd like to share my user-data by utilizing the CloudWatch agent to push the user-data log to CloudWatch Logs.

This example will install Python and AWS CLIV2 in Windows EC2 instance.

<powershell>
$instanceId = (invoke-webrequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).content
$config = '{
   "logs":{
      "logs_collected":{
         "files":{
            "collect_list":[
               {
                  "file_path":"C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Log\\UserdataExecution.log",
                  "log_group_name":"UserdataExecution.log",
                  "log_stream_name":"{instance_id}"
               }
            ]
         }
      }
   },
   "metrics":{
      "append_dimensions":{
         "AutoScalingGroupName":"${aws:AutoScalingGroupName}",
         "ImageId":"${aws:ImageId}",
         "InstanceId":"${aws:InstanceId}",
         "InstanceType":"${aws:InstanceType}"
      },
      "metrics_collected":{
         "LogicalDisk":{
            "measurement":[
               "% Free Space"
            ],
            "metrics_collection_interval":60,
            "resources":[
               "*"
            ]
         },
         "Memory":{
            "measurement":[
               "% Committed Bytes In Use"
            ],
            "metrics_collection_interval":60
         },
         "statsd":{
            "metrics_aggregation_interval":60,
            "metrics_collection_interval":10,
            "service_address":":8125"
         }
      }
   }
}'

mkdir C:\Downloads\Amazon\AmazonCloudWatchAgent
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://s3.amazonaws.com/amazoncloudwatch-agent/windows/amd64/latest/amazon-cloudwatch-agent.msi','C:\Downloads\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent.msi')"
do{
   C:\Downloads\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent.msi
   Start-Sleep 2
   $config | Set-Content 'C:\Downloads\Amazon\AmazonCloudWatchAgent\config.json'
    & "C:\Program Files\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent-ctl.ps1" -a fetch-config -m ec2 -s -c file:"C:\Downloads\Amazon\AmazonCloudWatchAgent\config.json"
   $agent_status = & "C:\Program Files\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent-ctl.ps1" -a status | ConvertFrom-Json
   $agent_status
}
until($agent_status.status -eq "running")
Restart-Service AmazonSSMAgent


[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Ssl3
[Net.ServicePointManager]::SecurityProtocol = "Tls, Tls11, Tls12, Ssl3"
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
choco install python -y
$dlurl = "https://awscli.amazonaws.com/AWSCLIV2.msi"
$installerPath = Join-Path $env:TEMP (Split-Path $dlurl -Leaf)
Invoke-WebRequest $dlurl -OutFile $installerPath
Start-Process -FilePath msiexec -Args "/i $installerPath /passive" -Verb RunAs -Wait
Remove-Item $installerPath
</powershell>

Thanks for visiting the blog.

See you in the next post.

No Comments Yet