Building AMIs with Packer

In this example we'll run a job that creates an Amazon Machine Images (AMIs) with HashiCorp's Packer. Next we output the AMI ID from the build as a resource an consume it as an input to the job responsible for launching instances.

Packer Build Pipeline

Resources

  • code-repo - git repo containing the packer.json file
  • worker-ami - a text file repo containing the resulting AMI ID of the AMI built with packer
resources:
- name: code-repo
type: git
source:
branch: main
private_key: ((repo_key))
uri: git@gitlab.com:oozie/code-repo.git
- name: worker-ami
type: s3
source:
access_key_id: ((aws_access))
secret_access_key: ((aws_secret))
region_name: ((state_bucket_region))
bucket: ((state_bucket))
versioned_file: concourse/worker-ami.txt
jobs:
- name: create-worker-template
plan:
- get: code-repo
- task: packer-build
config:
platform: linux
image_resource:
type: docker-image
source:
repository: hashicorp/packer
tag: full-1.7.8
inputs:
- name: code-repo
outputs:
- name: worker-ami
params:
NAME_PREFIX: ((webvm_prefix))
VPC_ID: ((vpc_id))
SUBNET_ID: ((subnet_id))
AWS_ACCESS_KEY_ID: ((aws_access))
AWS_SECRET_ACCESS_KEY: ((aws_secret))
AWS_DEFAULT_REGION: ((aws_region))
run:
dir: code-repo
path: /bin/sh
args:
- -c
- |
set -o pipefail
packer build myvmtemplate/packer.json -machine-readable | tee /tmp/packer.log
echo $(grep ,artifact,0,id "/tmp/packer.log" | cut -d: -f 2) > ../worker-ami/worker-ami.txt
- put: worker-ami
params:
file: worker-ami/worker-ami.txt
- name: spawn-worker
plan:
- get: code-repo
- get: worker-ami
passed: [ create-worker-template ]
- task: ec2.create-instances
config:
platform: linux
image_resource:
type: docker-image
source:
repository: oozie/py3
inputs:
- name: code-repo
- name: worker-ami
params:
NAME_PREFIX: ((webvm_prefix))
SUBNET_ID: ((subnet_id))
AWS_ACCESS_KEY_ID: ((aws_access))
AWS_SECRET_ACCESS_KEY: ((aws_secret))
AWS_DEFAULT_REGION: ((aws_region))
run:
path: python3
args:
- -c
- |
import os
import boto3
import time
from pprint import pprint
with open('worker-ami/worker-ami.txt') as ami_file:
ami_id = ami_file.read().strip()
subnet_id = os.environ['SUBNET_ID']
name_prefix = os.environ['NAME_PREFIX']
ec2 = boto3.resource("ec2")
secondsnow = str(int(time.time()))
resp = ec2.create_instances(ImageId=ami_id, InstanceType="t2.medium",
SubnetId=subnet_id,
MinCount=1, MaxCount=1, TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'Name',
'Value': f'myvm-{name_prefix}/{secondsnow}'
},
]
},
],
BlockDeviceMappings=[
{"DeviceName": "/dev/sda1","Ebs" : { "VolumeSize" : 80}}
],
)
pprint(resp)