Skip to content

Instantly share code, notes, and snippets.

@danrigsby
Last active December 14, 2023 15:07
Show Gist options
  • Select an option

  • Save danrigsby/11354917 to your computer and use it in GitHub Desktop.

Select an option

Save danrigsby/11354917 to your computer and use it in GitHub Desktop.
Get AMI ID from a packer build
packer build packer.json 2>&1 | sudo tee output.txt
tail -2 output.txt | head -2 | awk 'match($0, /ami-.*/) { print substr($0, RSTART, RLENGTH) }' > sudo ami.txt
@grayaii
Copy link
Copy Markdown

grayaii commented Dec 5, 2014

Thanks for finding this! This really helped. It's a bit unfortunate that packer does not provide a way to do this for you. If they change the output, then this will start failing. Thanks for posting here: https://groups.google.com/forum/#!searchin/packer-tool/ami$20id/packer-tool/FjwlZU2lo3g/Hq0Y7l-UwiwJ

@irgeek
Copy link
Copy Markdown

irgeek commented Dec 10, 2014

I try to avoid output parsing -- and running output through tee also causes Packer to strip colours -- so I came up with a different technique that has been working very well. Basically, have Packer tag the AMI with a unique value you know, then use AWS' built-in filtering to find the correct AMI after the build finishes.

More details in this gist: https://gist.github.com/irgeek/2f5bb964e3ce298e15b7

@rafaelmagu
Copy link
Copy Markdown

Why not use packer build -machine-readable and parse that output?

I use:

packer build -machine-readable packer.json | tee build.log
grep 'artifact,0,id' build.log | cut -d, -f6 | cut -d: -f2

@stefanteixeira
Copy link
Copy Markdown

Thanks @rafaelmagu, it worked very nicely!

@stefanteixeira
Copy link
Copy Markdown

I needed to grep the snapshot-id to delete it via AWS CLI. Based on @rafaelmagu answer, I created a gist that returns the snapshot-id: https://gist.github.com/stefanteixeira/ab91dfacda81bc030148

@rbowlby
Copy link
Copy Markdown

rbowlby commented Nov 20, 2015

Perfect, thanks for the share.

@sidarta-luizalabs
Copy link
Copy Markdown

Nice!
I've changed a little bit, based on @rafaelmagu :

packer build -machine-readable packer.json | tee build.log
egrep -m1 -oe 'ami-.{8}' build.log

cheers!

@delaman
Copy link
Copy Markdown

delaman commented Jun 14, 2016

This works good too:

$ packer build -machine-readable packer.json | awk -F, '$0 ~/artifact,0,id/ {print $6}'

@huyanhvn
Copy link
Copy Markdown

Just adding to @delaman, if you're doing multi-regions, you can do this to parse:

$ packer build -machine-readable packer.json | awk -F, '$0 ~/artifact,0,id/ {print $6}' | sed 's/%!(PACKER_COMMA)/\n/g'

@carlosonunez
Copy link
Copy Markdown

carlosonunez commented Jan 4, 2017

These are nice solutions. I went with the grep approach below, but the awk approach is just as clean.

packer build -machine-readable ... | egrep 'artifact,0,id' | rev | cut -f1 -d, | rev

@dayer4b
Copy link
Copy Markdown

dayer4b commented Jan 26, 2017

you might try the manifest post-processor instead.

https://www.packer.io/docs/post-processors/manifest.html

It can produce a JSON file with the relevant data that looks like:

{                                                                  
  "builds": [                                                      
    {                                                              
      "name": "amazon-ebs",                                        
      "builder_type": "amazon-ebs",                                
      "build_time": 1485460577,                                    
      "files": null,                                               
      "artifact_id": "us-west-1:ami-XXXXXXXX",                     
      "packer_run_uuid": "cd66f925-1eb5-c43e-4370-e696a66d53aa"    
    }                                                              
  ],                                                               
  "last_run_uuid": "cd66f925-1eb5-c43e-4370-e696a66d53aa"          
}                                                                  

@rquadling
Copy link
Copy Markdown

With regard to the manifest file post-processor, you need to be on at least https://github.com/mitchellh/packer/blob/master/CHANGELOG.md#0110-october-21-2016, but https://github.com/mitchellh/packer/blob/master/CHANGELOG.md#0121-december-15-2016 has changes to the manifest config, so would probably be a better option.

Otherwise, you'll get a message saying that the manifest post-processor cannot be found.

(As I did!)

@mschiessl
Copy link
Copy Markdown

mschiessl commented Jul 14, 2017

The Manifest output does not work, if you create your own ami (for example with the virtualbox bulder) and use the "amazon-import" post-processor, since it is just treating the build processor :(

@wmbutler
Copy link
Copy Markdown

wmbutler commented Apr 7, 2018

The manifest postprocessor worked great for me:

  "post-processors": [
    [
      {
        "output": "manifest.json",
        "strip_path": true,
        "type": "manifest"
      }
    ]
  ]

Then this chain of events will capture the ami-XXXXXX as shown by @dayer4b above.

cat manifest.json | jq -r .builds[0].artifact_id |  cut -d':' -f2

@Aagat
Copy link
Copy Markdown

Aagat commented Jun 8, 2018

I ended up using this along with manifest post processor to get the latest ami

cat manifest.json | jq -r '.builds[-1].artifact_id' |  cut -d':' -f2

@nishadmehendale
Copy link
Copy Markdown

How can we directly export the AMI_ID to global variable?

@sfdc-afraley
Copy link
Copy Markdown

This is old, but comes up when you search for how to get the ami id from the amazon-import post-processor. Note that the manifest will contain the AMI id, but you have to wrap the amazon-import post-processor and the manifest post-processor within the same list, or as Packer calls it, a sequence.

"post-processors": [
    [
      {
      "type": "amazon-import",
      "ami_name": "import_test",
      "region": "{{ user `target_region` }}",
      "s3_bucket_name": "{{ user `s3_artifact_bucket` }}",
      "role_name": "{{ user `aws_vmimport_role` }}"
      },
      { "type":"manifest" }
    ]
  ]

More info here: hashicorp/packer#7297

@piedmont01
Copy link
Copy Markdown

You can omit the cat command and pass the file file to jq directly or jq -r '.builds[-1].artifact_id' manifest.json | cut -d':' -f2

@electrawn
Copy link
Copy Markdown

Gist is one of those sites where it pays to read the comments. I was able to take this and combine it with some of the above additional techniques and wrap it together in a modern AWS demonstration. Enjoy: https://gist.github.com/electrawn/be0c239e46517a859e31bf0a2496235e

@dougireton
Copy link
Copy Markdown

Using a post-processor with jq works as well.

jq -r '.builds[0].artifact_id|split(":")[1]' ./manifest.json

@CodeForcer
Copy link
Copy Markdown

CodeForcer commented Jul 2, 2021

Seriously, we shouldn't have to do all this parsing of text. Packer should just have a way to spit out the ami_id in the language itself so we can use it in future build stages without having to parse arrays in json manifest files

@enishalilaj
Copy link
Copy Markdown

@CodeForcer yes, definitely I agree!!!

@galvarado
Copy link
Copy Markdown

Complete example using HCL with a manifest post-processor and the jq command from @dougireton:

packer {
  required_plugins {
    amazon = {
      version = ">= 0.0.2"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

source "amazon-ebs" "ubuntu" {
  ami_name      = "custom-ami-{{timestamp}}"
  instance_type = "t2.micro"
  region        = "eu-west-1"
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"]
  }
  ssh_username = "ubuntu"
  tags = {
    Name = "my-app"
    Os   = "ubuntu-jammy-22.04-amd64-server"
  }
}

build {
  name = "custom-ami"
  sources = ["source.amazon-ebs.ubuntu"]
    post-processor "manifest" {
        output = "manifest.json"
        strip_path = true
    }
}

Then just:
jq -r '.builds[0].artifact_id|split(":")[1]' ./manifest.json
Expected output:
ami-0dcbaf6794c89f392

But agree with @CodeForcer 2022 and packer still does not have a built-in method to spit out the id.

@pawanbahuguna
Copy link
Copy Markdown

For multiple AWS regions, try:

jq -r '.builds[0].artifact_id' ./manifest.json | tr ',' '\n'

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