Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I chain packer output ami id to terraform variables automatically?

Tags:

I'm using packer with ansible provisioner to build an ami, and terraform to setup the infrastructure with that ami as a source - somewhat similar to this article: http://www.paulstack.co.uk/blog/2016/01/02/building-an-elasticsearch-cluster-in-aws-with-packer-and-terraform

When command packer build pack.json completes successfully I get the output ami id in this format:

eu-central-1: ami-12345678

In my terraform variables variables.tf I need to specify the source ami id, region etc. The problem here is that I don't want to specify them manually or multiple times. For region (that I know beforehand) it's easy since I can use environment variables in both situations, but what about the output ami? Is there a built-in way to chain these products or some not so hacky approach to do it?

EDIT: Hacky approach for anyone who might be interested. In this solution I'm greping the aws region & ami from packer output and use a regular expression in perl to write the result into a terraform.tfvars file:

vars=$(pwd)"/terraform.tfvars"
packer build pack.json | \
    tee /dev/tty | \
    grep -E -o '\w{2}-\w+-\w{1}: ami-\w+' | \
    perl -ne '@parts = split /[:,\s]+/, $_; print "aws_amis." . $parts[0] ." = \"" . $parts[1] . "\"\n"' > ${vars}
like image 941
fips Avatar asked May 21 '16 00:05

fips


People also ask

What is the difference between terraform and Packer?

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration file. It can build images for multiple cloud hosting platforms, including Scaleway. Terraform is an open source tool for building, changing, and versioning infrastructure safely and efficiently.


1 Answers

You should consider using Terraform's Data Source for aws_ami. With this, you can rely on custom tags that you set on the AMI when it is created (for example a version number or timestamp). Then, in the Terraform configuration, you can simply filter the available AMIs for this account and region to get the AMI ID that you need.

https://www.terraform.io/docs/providers/aws/d/ami.html

data "aws_ami" "nat_ami" {
  most_recent = true
  executable_users = ["self"]
  filter {
    name = "owner-alias"
    values = ["amazon"]
  }
  filter {
    name = "name"
    values = ["amzn-ami-vpc-nat*"]
  }
  name_regex = "^myami-\\d{3}"
  owners = ["self"]
}

NOTE: in the example above (from the docs), the combination of filters is probably excessive. You can probably get by just fine with something like:

data "aws_ami" "image" {
  most_recent = true
  owners = ["self"]
  filter {                       
    name = "tag:Application"     
    values = ["my-app-name"]
  }                              
}

output "ami_id" {
  value = "${data.aws_ami.image.id}"
}

An additional benefit of this is that you can deploy to multiple regions with the same configuration and no variable map!

like image 134
dayer4b Avatar answered Sep 22 '22 11:09

dayer4b