Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Ubuntu CloudFormation Tools installation snippet. Modified version of http://krunchtime.it/setting-up-bootstrapping-using-cfn-init-for-aws-ubuntu-ec2-instance
"UserData": {
"Fn::Base64": { "Fn::Join":["", [
"#!/bin/bash -ex\n",
"apt-get update\n",
"apt-get -y install python-setuptools\n",
"mkdir aws-cfn-bootstrap-latest\n",
"curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1\n",
"easy_install aws-cfn-bootstrap-latest\n",
"/usr/local/bin/cfn-init --stack ", { "Ref":"AWS::StackName" }, " --resource WebServer", " --region ", { "Ref": "AWS::Region" }, "\n",
"\n",
"/usr/local/bin/cfn-signal --exit-code $? '", { "Ref" : "WaitHandle" }, "'\n"
]]}
}

I got this working by adding a comma at the end of line 9 and defining the "WaitHandle" earlier in the template.

Owner

kixorz commented Oct 5, 2015

Thanks! I'll update it.

Another example which uses pip instead of easy_install and works behind a proxy:

    "UserData": {
          "Fn::Base64": {
            "Fn::Join": ["", [
              "#!/bin/bash\n",
              "set -o errexit; set -o nounset; set -o pipefail\n",
              "echo 'Acquire::http::proxy \"http://myproxy.example.com:8080 \";' > /etc/apt/apt.conf.d/80proxy\n",
              "echo 'Acquire::https::proxy \"http://myproxy.example.com:8080 \";' >> /etc/apt/apt.conf.d/80proxy\n",

              "# Install AWS cfn-bootstrap utilities\n",
              "apt-get update\n",
              "apt-get -y install python-pip\n",
              "pip install --proxy http://myproxy.example.com:8080 https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",

              "/usr/local/bin/cfn-init",
              " --stack ", { "Ref": "AWS::StackName" },
              " --resource MyLogicalResourceName",
              " --configsets bootstrap-chef",
              " --region ", { "Ref": "AWS::Region" }, "\n"
            ]]
          }
        }

Another more basic example with easy install for Debian 8.

    "UserData": {
      "Fn::Base64": { "Fn::Join":["", [
        "#!/bin/bash\n",
        "apt-get update\n",
        "apt-get -y install python-setuptools\n",
        "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
        "cfn-init --stack ", { "Ref": "AWS::StackName" }," --resource LaunchConfig --region ", { "Ref": "AWS::Region" }, "\n",
        "cfn-signal -e $? ","--stack ", { "Ref": "AWS::StackName" }," --resource WebServerGroup --region ", { "Ref": "AWS::Region" }, "\n"
      ]]}

wtfiwtz commented Oct 12, 2016 edited

On Ubuntu 16.04.1 LTS this works:

#!/bin/bash -xe

mkdir -p /tmp/aws-cfn-bootstrap-latest

curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-1.4-8.tar.gz | tar xz -C /tmp/aws-cfn-bootstrap-latest --strip-components 1

curl https://s3-ap-southeast-2.amazonaws.com/bucket/cfn-hup.service -o /etc/systemd/system/cfn-hup.service

apt-get update

apt-get install -y python-pip libssl-dev libffi-dev

pip install pyopenssl ndg-httpsclient pyasn1

pip install --upgrade /tmp/aws-cfn-bootstrap-latest

cp /tmp/aws-cfn-bootstrap-latest/init/ubuntu/cfn-hup /etc/init.d/cfn-hup
/etc/init.d/
update-rc.d cfn-hup defaults
chmod 755 /etc/init.d/cfn-hup


A sample cfn-hup.service file is here: adamreeve/asp.net-docker@96f86bf

... although you might need to set the launch path to /usr/local/bin/cfn-hup

Another issue was that I had to disable the cfn-hup service setup - maybe Cloudformation's cloud-init and cfn-init is not compatible with systemd. You can install the upstart-sysv Ubuntu package to switch back to upstart although I had other difficulties with that.

rozhok commented Mar 26, 2017

Another one taken from https://commscentral.net/tech/?post=50:

    "AppInstanceConfiguration": {
      "Type": "AWS::AutoScaling::LaunchConfiguration",
      "Metadata": {
        "AWS::CloudFormation::Init" : {
          "config" : {
            "files" : {

              "/etc/cfn/cfn-hup.conf" : {
                "content" : { "Fn::Join" : ["", [
                  "[main]\n",
                  "stack=", { "Ref" : "AWS::StackId" }, "\n",
                  "region=", { "Ref" : "AWS::Region" }, "\n"
                ]]},
                "mode"    : "000400",
                "owner"   : "root",
                "group"   : "root"
              },

              "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : {
                "content": { "Fn::Join" : ["", [
                  "[cfn-auto-reloader-hook]\n",
                  "triggers=post.update\n",
                  "path=Resources.AppInstanceConfiguration.Metadata.AWS::CloudFormation::Init\n",
                  "action=/usr/local/bin/cfn-init -v ",
                  "         --stack ", { "Ref" : "AWS::StackName" },
                  "         --resource AppInstanceConfiguration ",
                  "         --region ", { "Ref" : "AWS::Region" }, "\n",
                  "runas=root\n"
                ]]}
              }
            },

            "services" : {
              "sysvinit" : {
                "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true",
                  "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}
              }
            }
          }
        }
      },
      "Properties": {
        "ImageId" : { "Fn::FindInMap" : [ "AWSRegionToUbuntuAMI", { "Ref" : "AWS::Region" }, "AMIID" ] },
        "SecurityGroups": [{"Ref": "AppInstanceSecurityGroup" }],
        "InstanceType": {"Ref": "AppInstanceType" },
        "IamInstanceProfile": {"Ref": "AppInstanceEC2InstanceProfile"},
        "KeyName": {"Ref": "SSHKey"},
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["", [
          "Content-Type: multipart/mixed; boundary=\"=======6t461261365==\"\n",
          "MIME-Version: 1.0\n",
          "\n",
          "--=======6t461261365==\n",
          "Content-Type: text/x-shellscript; charset=\"us-ascii\"\n",
          "Content-Disposition: attachment; filename=\"cfn-setup.sh\"\n",
          "\n",
          "#!/bin/bash\n",
          "set -o errexit; set -o nounset; set -o pipefail\n",
          "# Install AWS cfn-bootstrap utilities\n",
          "apt-get update\n",
          "apt-get -y install python-pip\n",
          "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
          "cp /usr/local/init/ubuntu/cfn-hup /etc/init.d/cfn-hup \n",
          "chmod +x /etc/init.d/cfn-hup \n",
          "update-rc.d cfn-hup defaults \n ",
          "service cfn-hup start \n",
          
          "/usr/local/bin/cfn-init",
          " --stack ", { "Ref": "AWS::StackName" },
          " --resource AppInstanceConfiguration",
          " --region ", { "Ref": "AWS::Region" }, "\n",

          "/usr/local/bin/cfn-signal -e $? ",
          "         --stack ", { "Ref" : "AWS::StackName" },
          "         --resource AppInstanceAutoScalingGroup",
          "         --region ", { "Ref" : "AWS::Region" }, "\n",
          "\n",
          "--=======6t461261365==--\n"
          ]]}
        }
      }
    },

Works like a charm.

gregmac commented Jul 4, 2017

I was struggling with systemd service config, and finally got this working:

  BastionHost:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          default: 
          - config-cfn-hup
        config-cfn-hup:
          files:
            #cfn-hup configuration 
            '/etc/cfn/cfn-hup.conf':
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                interval=1
            '/etc/cfn/hooks.d/cfn-auto-reloader.conf':
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.BastionHost.Metadata.AWS::CloudFormation::Init
                action=/usr/local/bin/cfn-init -v --stack ${AWS::StackId} --resource BastionHost --region ${AWS::Region}
            #systemd service 
            '/etc/systemd/system/cfn-hup.service': 
              content: |
                [Unit]
                Description=Cloud formation helper daemon

                [Service]
                ExecStart=/usr/local/bin/cfn-hup
                Restart=always
                RestartSec=10s
                Type=notify
                NotifyAccess=all
                TimeoutStartSec=120
                TimeoutStopSec=15

                [Install]
                WantedBy=multi-user.target

          commands: 
            enable-cfn-hup:
              command: "systemctl enable cfn-hup.service" 
            start-cfn-hup:
              command: "systemctl start cfn-hup.service" 
    Properties:
      UserData:
        Fn::Base64: !Sub |
          #!bin/bash -xe
          apt-get update 
          apt-get -y install python-setuptools
          easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
          
          /usr/local/bin/cfn-init -v --stack ${AWS::StackId} --resource BastionHost --region ${AWS::Region}
          /usr/local/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource BastionHost --region ${AWS::Region}

cfn-init doesn't handle systemd at all, from what I can tell. This also means you can't use the services: section, you have to manually invoke systemctl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment