Golden image creation using Packer and AWS CodePipeline

Hi All, we know that Packer can be used to create Golden images for multiple platforms. Here we will use Packer to create an Golden image of Amazon Linux OS in AWS. The created images are called as AMI which appear in AWS dashboard. The image creation is necessarry in situations when we want the OS to have pre set of packages installed to support our application. The custom created AMI can be used to spin up EC2 instances when we need to build large infrastructure frequently to support the applications.

In this tutorial I will be using AWS CodeCommit, CodeBuild and create a CodePipeline with these. The CodePipeline will automatically get triggered when a commit happens to the CodeCommit repo. The pipeline will run the CodeBuild which will trigger the buildspec.yml and use the packer build command mentioned in it to build the Golden image (AMI)

I will be commiting 2 files to CodeCommit – buildspec.yml and CreateAMI.json file

Below is the content of buildspec.yml

---
version: 0.2

phases:
  pre_build:
    commands:
      - echo "Installing HashiCorp Packer..."
      - curl -qL -o packer.zip https://releases.hashicorp.com/packer/0.12.3/packer_0.12.3_linux_amd64.zip && unzip packer.zip
      - echo "Installing jq..."
      - curl -qL -o jq https://stedolan.github.io/jq/download/linux64/jq && chmod +x ./jq
      - echo "Validating CreateAMI.json"
      - ./packer validate CreateAMI.json
  build:
    commands:
      ### HashiCorp Packer cannot currently obtain the AWS CodeBuild-assigned role and its credentials
      ### Manually capture and configure the AWS CLI to provide HashiCorp Packer with AWS credentials
      ### More info here: https://github.com/mitchellh/packer/issues/4279
      - echo "Configuring AWS credentials"
      - curl -qL -o aws_credentials.json http://169.254.170.2/$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI > aws_credentials.json
      - aws configure set region $AWS_REGION
      - echo "AWS region set is:" $AWS_REGION
      - aws configure set aws_access_key_id `./jq -r '.AccessKeyId' aws_credentials.json`
      - aws configure set aws_secret_access_key `./jq -r '.SecretAccessKey' aws_credentials.json`
      - aws configure set aws_session_token `./jq -r '.Token' aws_credentials.json`
      - echo "Building HashiCorp Packer template, CreateAMI.json"
      - ./packer build CreateAMI.json
  post_build:
    commands:
      - echo "HashiCorp Packer build completed on `date`"

Below is the content of CreateAMI.json

{
    "variables": {
        "aws_region": "{{env `AWS_REGION`}}"
    },
  "builders": [
    {
      "type": "amazon-ebs",
      "region": "{{user `aws_region`}}",
      "instance_type": "t2.micro",
      "source_ami": "ami-0080e4c5bc078760e",
      "ssh_username": "ec2-user",
      "ami_name": "custom-Dev1",
      "ami_description": "Amazon Linux Image OS with pre-installed packages",
      "run_tags": {
        "Name": "custom-Dev1",
	"Env": "dev",
	"Project": "DevOps"
      }
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "sudo yum install java python wget -y",
	"sudo yum install tomcat -y"
      ]
    }
  ]
}

1. Create an AWS CodeCommit Repository and add these 2 files into it.
2. Create AWS CodeBuild project and select CodeCommit repo and master branch
3. Create CodePipeline by selecting CodeCommit repo and CodeBuild project as stages.
Screenshot from 2018-12-19 12-06-05

Screenshot from 2018-12-19 12-07-56

Screenshot from 2018-12-19 12-08-52

Skip Deploy stage and create the pipleine.

4. Select the created CodePipeline and click on Release changes which will start running the pipeline.

5. After the pipeline finishes successfully, go to the EC2 dashboard and click on AMI in left side and you should see the created Golden image.