0
votes

I created a Windows 2012 AMI and created an instance of that AMI using the CloudFormation template shown below.

In that JSON script I want to call a PowerShell script to disable a service (simple one). The EC2 Windows 2012 instance gets created. I made sure EC2Config service was running before I took AMI. It works now. Following is the code that works fine. But the question is, I don't clearly understand the interaction between cfn-hup, cfn-signal and cfn-init. Honestly I read about all the 4 helper scripts. But I am not wrap my brain around these helper scripts.

Are there any blogs or documentation about how these 4 helper scripts work together?

{
   "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;Unblock-File C:\\PowershellScripts\\WindowsServiceManager.ps1;. C:\\PowershellScripts\\WindowsServiceManager.ps1;SetWindowsServiceStartupType Dnscache Manual;StopWindowsService Dnscache"
             ]]}}
            },
       "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": "ami-3723c04f",
   "InstanceType": "t2.micro",
   "KeyName": "EC2Instances",
   "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"
     ]]}}

 }
   },
     "WindowsServerWaitHandle": {
      "Type": "AWS::CloudFormation::WaitConditionHandle"
     },
  "WindowsServerWaitCondition": {
   "Type": "AWS::CloudFormation::WaitCondition",
    "DependsOn": "MyInstance",
    "Properties": {
       "Handle": { "Ref": "WindowsServerWaitHandle" },
       "Timeout": "1800"
     }
   }        
}
}
1
Found a decent explanation here: aws.amazon.com/blogs/devops/… - Jason

1 Answers

0
votes

Found a decent explanation here:

https://aws.amazon.com/blogs/devops/best-practices-for-deploying-applications-on-aws-cloudformation-stacks/

Sequence of how AWS::CloudFormation::Init works:

  1. You specify application configuration using the AWS::CloudFormation::Init section for an EC2 instance in your CloudFormation template.
  2. You kick-off a CloudFormation stack creation using the template.
  3. The AWS CloudFormation service starts creating a stack, including the EC2 instance.
  4. After the EC2 instance is up and running, a CloudFormation helper script, cfn-init, is executed on the instance to configure the instance in accordance with your AWS::CloudFormation::Init template specification.*
  5. Another CloudFormation helper script, cfn-signal, is executed on the instance to let the remote AWS CloudFormation service know the result (success/failure) of the configuration.* You can optionally have the CloudFormation service hold off on marking the EC2 instance state and the stack state “CREATE_COMPLETE” until the CloudFormation service hears a success signal for the instance. The holding-off period is specified in the template using a CreationPolicy.

*You can download the CloudFormation helper scripts for both Linux and Windows. These come preinstalled on the Linux and Windows AMIs provided by Amazon. You need to specify the commands to trigger cfn-init and cfn-signal in the EC2 user data script. Once an instance is up and running, the EC2 user data script is executed automatically for most Linux distributions and Windows.

Once your application stack is up and running, chances are that you will update the application, apply an OS patch, or perform some other configuration update in a stack’s lifecycle. You just update the AWS::CloudFormation::Init section in your template (for example, specify a newer version of an application package), and call UpdateStack. When you do, CloudFormation updates the instance metadata in accordance with the updated template. Then the cfn-hup daemon running on the instance detects the updated metadata and reruns cfn-init to update the instance in accordance with the updated configuration. cfn-hup is one of the CloudFormation helper scripts available on both Linux and Windows.