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

Last updated: 2022-09-09

My helper scripts won't bootstrap in an AWS CloudFormation stack with Microsoft Windows instances. How do I resolve this issue?

Short description

In a Windows instance, UserData that runs as a child process of EC2ConfigService invokes cfn-init.exe. Certain steps that cfn-init.exe performs 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 reboots, cfn-init continues to run the rest of the configurations that remain in AWS::CloudFormation::Init with the help of C:\cfn\cfn-init\resume_db.json.

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

If you receive the following error, then you might have issues with cfn-signal:

"Received 0 conditions when expecting X or Failed to receive X resource signal(s) within the specified duration"

To resolve the preceding error, complete the steps in the Troubleshoot cfn-signal issues section.

For both issues, complete the steps in the Follow the best practices for using a Windows operating system with CloudFormation section.

Resolution

Troubleshoot bootstrapping issues

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: The forever value 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:

  • Amazon Elastic Compute Cloud (Amazon EC2) configuration log at C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2ConfigLog.txt (versions before Windows 2016)
  • Amazon EC2 configuration log at C:\ProgramData\Amazon\EC2-Windows\Launch\Log\ (Windows 2016 and later)
  • cfn-init log at C:\cfn\log\cfn-init.log
  • 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 the example of bootstrapping a Windows stack.

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, then you might experience metadata issues and get the following error in the user data 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 CloudFormation

Include $ErrorActionPreference = "Stop" at the top of your PowerShell scripts to catch exceptions.

When you refer to a Windows path in your CloudFormation template, you must add a forward slash (/) at the beginning of the path. 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?


Do you need billing or technical support?