Do Cloud Better.

Install the AWS CodeDeploy service with CloudFormation

Posted by Jaaromy Zierse on Oct 22, 2018 4:08:02 PM

When creating an AWS EC2 instance, there is a User Data section where you can include scripts that will be run immediately upon instance creation. I was attempting to use AWS CloudFormation to define the infrastructure of my current project and ran into the issue of how to include the User Data section in the CloudFormation JSON definition.

 

After several false starts, I was able to come up with this:

"UserData": {
  "Fn::Base64": {
    "Fn::Join": [
      "",
      [
        "#!/bin/bash -ex\n",
        "yum update -y\n",
        "yum -y install ruby\n",
        "yum -y install wget\n",
        "yum -y install libcurl-devel\n",
        "yum -y install zlib-devel\n",
        "yum -y install git\n",
        "yum group install -y \"Development Tools\"\n",
        "cd /home/ec2-user\n",
        "wget https://aws-codedeploy-us-east-1.s3.amazonaws.com/latest/install\n",
        "chmod +x ./install\n",
        "./install auto\n"
      ]
    ]
  }
}

The key was realizing that Fn::Join, since it simply concatenates each array item, needed each item to end with \n before the Base64 encoding. Without the \n, each line of the script is pushed right up next to it’s predecessor and you get #!/bin/bash -exyum update -yyum -y install ruby... etc.

And here is the entire Auto Scaling Launch Configuration to put the User Data section in context. Each instance of the Auto Scaling Group will have the CodeDeploy service and Git installed on startup.

"Resources": {
  "LaunchConfig": {
    "Type": "AWS::AutoScaling::LaunchConfiguration",
    "Properties": {
      "InstanceMonitoring": false,
      "InstanceType": {
        "Fn::FindInMap": ["EnvMap", {
          "Ref": "EnvType"
        }, "InstanceType"]
      },
      "KeyName": {
        "Ref": "KeyName"
      },
      "ImageId": {
        "Fn::FindInMap": ["EnvMap", {
          "Ref": "EnvType"
        }, "AMI"]
      },
      "BlockDeviceMappings": [{
        "DeviceName": "/dev/xvda",
        "Ebs": {
          "VolumeSize": {
            "Fn::FindInMap": ["EnvMap", {
              "Ref": "EnvType"
            }, "VolumeSize"]
          },
          "VolumeType": "gp2",
          "DeleteOnTermination": true
        }
      }],
      "SecurityGroups": [{
        "Ref": "SecurityGroup"
      }],
      "AssociatePublicIpAddress": true,
      "UserData": {
        "Fn::Base64": {
          "Fn::Join": [
            "", [
              "#!/bin/bash -ex\n",
              "yum update -y\n",
              "yum -y install ruby\n",
              "yum -y install wget\n",
              "yum -y install libcurl-devel\n",
              "yum -y install zlib-devel\n",
              "yum -y install git\n",
              "yum group install -y \"Development Tools\"\n",
              "cd /home/ec2-user\n",
              "wget https://aws-codedeploy-us-east-1.s3.amazonaws.com/latest/install\n",
              "chmod +x ./install\n",
              "./install auto\n"
            ]
          ]
        }
      }
    }
  }
}

Tags: AWS, CloudFormation, DevOps

All Things Cloud.

This is a collection of articles from the Observian team that we hope provide value to those trying to learn more about cloud computing.

Subscribe to Email Updates

Recent Posts