How do I troubleshoot helper scripts that won't bootstrap in an AWS CloudFormation stack with Windows instances?

Last updated: 2020-06-19

I want to bootstrap my helper scripts in an AWS CloudFormation stack with Windows instances.

Short description

If your helper scripts don't run after rebooting the Windows instance, complete the steps in the Troubleshoot bootstrapping issues section.

If you receive the "Received 0 conditions when expecting X or Failed to receive X resource signal(s) within the specified duration" error, then complete the steps in the Troubleshoot cfn-signal issues section.

Finally, complete the steps in the Follow the best practices for using a Windows operating system with AWS CloudFormation section.

Resolution

Troubleshoot bootstrapping issues

In a Windows instance, UserData (running as a child process of EC2ConfigService) invokes cfn-init.exe. Certain steps performed by cfn-init.exe might require a system reboot. For example, you must reboot the system if you rename a computer or join a computer to a domain. After the system finishes rebooting, cfn-init continues to run the rest of the configs remaining in AWS::CloudFormation::Init with the help of C:\cfn\cfn-init\resume_db.json.

If your script doesn't run after reboot, then complete the following steps:

1.    In the commands section of your cfn-init configuration set, confirm that waitAfterCompletion is set to forever. For example:

  "commands": {
 "0-restart": {
 "command": "powershell.exe -Command Restart-Computer",
 "waitAfterCompletion": "forever"
 }
 }

Note: A value of forever directs cfn-init to exit and resume only after the reboot is complete. For more information, see AWS::CloudFormation::Init.

2.    Check the following logs for errors:

The Amazon Elastic Compute Cloud (Amazon EC2) configuration log at C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2ConfigLog.txt (versions before Windows 2016) and C:\ProgramData\Amazon\EC2-Windows\Launch\Log\ (Windows 2016 and later)
The cfn-init log at C:\cfn\log\cfn-init.log
The Windows event logs at C:\Windows\System32\winevt\logs

Troubleshoot cfn-signal issues

1.    Confirm that the cfn-signal is configured correctly.

Important: Use -e $lastexitcode in PowerShell scripts, and use -e %ERRORLEVEL% for Windows cmd.exe scripts.

For PowerShell scripts in UserData, use the following tags:

<powershell></powershell>

Example PowerShell script:

UserData:
        Fn::Base64:
          Fn::Sub : |
            <powershell>
            $LASTEXITCODE=0
            echo Current date and time >> C:\Temp\test.log
            echo %DATE% %TIME% >> C:\Temp\test.log
            cfn-init.exe -s ${AWS::StackId} -r SInstance --region ${AWS::Region}
            New-Item -Path "C:\" -Name userdata -ItemType directory
            cfn-signal.exe -e $LASTEXITCODE --stack ${AWS::StackId} --resource WindowsInstance --region ${AWS::Region}
            </powershell>

For cmd.exe scripts in UserData, use the following tags:

<script></script>

Example cmd.exe script:

UserData:
  Fn::Base64: !Sub |
    <script>
    cfn-init.exe -v -s ${AWS::StackId} -r WindowsInstance --configsets ascending --region ${AWS::Region}
    cfn-signal.exe -e %ERRORLEVEL% --stack ${AWS::StackId} --resource WindowsInstance --region ${AWS::Region}
    </script>

2.    Increase the Timeout of the WaitCondition to 1800/3600 seconds based on AWS CloudFormation Windows examples.

Note: Step 2 is necessary because Windows instances usually take longer than Linux instances to complete their initial boot process.

3.    If you're using a custom Amazon Machine Image (AMI), then you must use Sysprep to create the AMI before you start. If you don't use Sysprep, you could experience metadata issues and get the following error in the userdata log for metadata:

Failed to get metadata: The result from http://169.254.169.254/latest/user-data was empty
Unable to execute userdata: Userdata was not provided

Follow the best practices for using a Windows operating system with AWS CloudFormation

Allow exceptions to be caught by including $ErrorActionPreference = "Stop" at the top of your PowerShell scripts.

When you refer to a Windows path in your AWS CloudFormation template, you must prepend any Windows path with a forward slash ("/") character. For example:

"commands" : {
  "1-extract" : {
    "command" : "C:\\SharePoint\\SharePointFoundation2010.exe /extract:C:\\SharePoint\\SPF2010 /quiet /log:C:\\SharePoint\\SharePointFoundation2010-extract.log"
  }

For Windows stacks, you must base64-encode the WaitCondition handle URL again. For example:

cfn-signal.exe -e %ERRORLEVEL% ", { "Fn::Base64" : { "Ref" : "SharePointFoundationWaitHandle" }}, "\n"

Did this article help you?

Anything we could improve?


Need more help?