This post focuses on the CloudFormation WaitCondition resource, which can help you to initialize and configure your environment as per your requirement.
WaitCondition can be considered as a timed semaphore that pauses the execution of your CloudFormation template and waits for a number of success signals before it continues a stack creation operation. There are scenarios where you need to pause the execution of your CloudFormation stack, such as resource dependencies or user experience. Some scenarios also include:
When the WaitCondition resource is created, a timer is started. The WaitCondition becomes CREATE_COMPLETE after it receives a success signal. If no signal is received before the timeout, the WaitCondition enters the CREATE_FAILED state and the stack creation is rolled back.
To use WaitCondition with your CloudFormation template, you must have CloudFormation helper scripts configured on your instances. These helper scripts (cfn helper) are Python scripts that help you to install, configure and start services on your Amazon EC2 instances and are part of your stack creation process. If these scripts are not already configured on your Amazon EC2 instance, they can be configured as a part of your userdata.
Syntax:
{ "Type" : "AWS::CloudFormation::WaitCondition", "Properties" : { "Count" : String, "Handle" : String, "Timeout" : String } }
“Count” sets the number of success signals AWS CloudFormation must receive before it continues the stack creation process. If the wait condition does not receive the specified number of success signals before the Timeout period expires, CloudFormation assumes that the wait condition has failed and rolls the stack back.
“Handle” is a reference to the wait condition handle used to signal this wait condition. To use a wait condition in a stack, you have to declare an AWS::CloudFormation::WaitConditionHandle resource in the stack’s template. A wait condition handle has no properties; however, a reference to a WaitConditionHandle resource resolves to a presigned URL that you can use to signal success or failure to the WaitCondition.
Syntax:
{ "Type" : "AWS::CloudFormation::WaitConditionHandle", "Properties" : {} }
Anytime you add a WaitCondition resource during a stack update, you must associate the wait condition with a new WaitConditionHandle resource.
“Timeout” is the time (in seconds) to wait for the number of signals that the Count property specifies. The maximum time that can be specified for this property is 12 hours (43200 seconds). If you receive a positive signal before the timeout value, it will automatically stop the timer and execution of the template will start.
For dynamically installing and configuring your application on Amazon EC2 instances, CloudFormation provides a set of helper scripts (written in Python) that, in conjunction with the resource metadata you defined in the template, can be used to install software and start services. These helper scripts are run on the Amazon EC2 instance.
This is how AWS’s CloudFormation documentation describes these helper scripts:
CloudFormation helper scripts are already available on Amazon Linux AMIs and Amazon Windows AMIs however, if you want to use them for other linux distributions, RPM and source code is available on AWS website. These scripts can be installed as a part of userdata.
If you create your own Windows image for use with CloudFormation you must set up a Windows instance with EC2ConfigService to work with the AWS CloudFormation bootstrapping tools.
It is recommend to use the latest version of the AWS CloudFormation bootstrap scripts when you launch an Amazon Linux AMI. To ensure that happens, add a yum update –y aws-cfn-bootstrap command to the user data script, as shown in the following example (a sample template using the ‘WaitConditions’ and ‘WaitCondition Handle’ Resources):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "MyInstance": { "Type": "AWS::EC2::Instance", "Properties": { "DisableApiTermination": "FALSE", "ImageId": "AmazonLinuxAMIId", "InstanceType": "t2.micro", "KeyName": "MyKeypair", "Monitoring": "false", "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum update -y aws-cfn-bootstrap\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e 0 -r \"Instance Creation Complete\" ", { "Ref" : "WaitHandle" }, "'\n" ]]}}, "Tags": [ { "Key": "Name", "Value": "My_Instance" } ], "NetworkInterfaces": [ { "DeleteOnTermination": "true", "Description": "Primary network interface", "DeviceIndex": 0, "AssociatePublicIpAddress": "true" } ] } }, "WaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "WaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "MyInstance", "Properties" : { "Handle" : { "Ref" : "WaitHandle" }, "Timeout" : "300" } } } }
User data execution enables you to inject scripts into the instance metadata during the first launch. By default, all Amazon Windows AMIs have user data execution enabled for the initial boot. However, if you want to use any custom Windows AMI and want to enable userdata execution then you need to follow these instructions:
The following is a sample template for a Windows Base AMI using the ‘WaitConditions’ and ‘WaitCondition Handle’ resources.
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "MyInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "files" : { "c:\\cfn\\cfn-hup.conf" : { "content" : { "Fn::Join" : ["", [ "[main]\n", "stack=", { "Ref" : "AWS::StackId" }, "\n", "region=", { "Ref" : "AWS::Region" }, "\n" ]]} }, "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" : { "content": { "Fn::Join" : ["", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.MyInstance.Metadata.AWS::CloudFormation::Init\n", "action=cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" }, " -r MyInstance", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]} }, "c:\\scripts\\test.ps1" : { "content": { "Fn::Join" : ["", [ "Write-Host Hello World!\n" ]]} } }, "commands" : { "1-run-script" : { "command" : { "Fn::Join" : [ "", [ "Powershell.exe Set-ExecutionPolicy Unrestricted -force \n", "Powershell.exe C:\\scripts\\test.ps1" ]]}} }, "services": { "windows": { "cfn-hup": { "enabled": "true", "ensureRunning": "true", "files": ["c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"] } } } } } }, "Properties": { "DisableApiTermination": "FALSE", "ImageId": "WindowsBaseAMIId", "InstanceType": "t2.micro", "KeyName": "MyKeypair", "Monitoring": "false", "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "<script>\n", "cfn-init.exe -v -s ", { "Ref" : "AWS::StackName" }, " -r MyInstance", " --region ", { "Ref" : "AWS::Region" }, "\n", "cfn-signal.exe -e 0 ", { "Fn::Base64" : { "Ref" : "WindowsServerWaitHandle" }}, "\n", "</script>\n" ]]}}, "Tags": [ { "Key": "Name", "Value": "CloudAcademy_Instance" } ], "NetworkInterfaces": [ { "DeleteOnTermination": "true", "Description": "Primary network interface", "DeviceIndex": 0, "AssociatePublicIpAddress": "true" } ] } }, "WindowsServerWaitHandle": { "Type": "AWS::CloudFormation::WaitConditionHandle" }, "WindowsServerWaitCondition": { "Type": "AWS::CloudFormation::WaitCondition", "DependsOn": "MyInstance", "Properties": { "Handle": { "Ref": "WindowsServerWaitHandle" }, "Timeout": "1800" } } }
The WaitCondition CloudFormation resource might look similar to the DependsOn attribute, but they’re actually different. DependsOn controls the order in which your CloudFormation resources are created, i.e., creation of a specific resource follows another. DependsOn doesn’t wait for success or failure signals from AWS resources before moving forward. While, on the other hand, WaitCondition waits for success signals from your AWS resources and resumes the execution of the CloudFormation template. However, WaitCondition and DependsOn can work together when there is a resource creation dependency requirement.
WaitCondition is a very useful AWS feature that’s widely used for building a complete automated deployment system. For more information on CloudFormation WaitCondition resource, refer to these links :
It's Flash Sale time! Get 50% off your first year with Cloud Academy: all access to AWS, Azure, and Cloud…
In this blog post, we're going to answer some questions you might have about the new AWS Certified Data Engineer…
This is my 3rd and final post of this series ‘Navigating the Vocabulary of Gen AI’. If you would like…