Как я могу автоматически вывести идентификатор ami id упаковщика в переменные терраформы?

Я использую упаковщик с возможным помощником для создания ami и terraform для настройки инфраструктуры с помощью этого ami в качестве источника - несколько похожа на эту статью: http://www.paulstack.co.uk/blog/2016/01/02/building-an-elasticsearch-cluster-in-aws-with-packer-and-terraform

Когда команда packer build pack.json завершается успешно, я получаю вывод ami id в этом формате:

eu-central-1: ami-12345678

В моих переменных terraform variables.tf Мне нужно указать источник ami id, region и т.д. Проблема здесь в том, что я не хочу указывать их вручную или несколько раз. Для региона (который я знаю заранее) легко, так как я могу использовать переменные среды в обеих ситуациях, но как насчет выхода ami? Есть ли встроенный способ связать эти продукты или какой-то не такой хакерский подход, чтобы сделать это?

EDIT: Хакерный подход для всех, кто может быть заинтересован. В этом решении я grep в области aws и ami из вывода пакета и использую регулярное выражение в perl для записи результата в файл terraform.tfvars:

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}

Ответ 1

Вам следует рассмотреть возможность использования Terraform Data Source для aws_ami. При этом вы можете полагаться на пользовательские теги, которые вы устанавливаете в AMI, когда они созданы (например, номер версии или временная метка). Затем в конфигурации Terraform вы можете просто отфильтровать доступные AMI для этой учетной записи и региона, чтобы получить требуемый идентификатор AMI.

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"]
}

ПРИМЕЧАНИЕ. В приведенном выше примере (из документов) комбинация фильтров, вероятно, чрезмерна. Вероятно, вы можете просто получить что-то вроде:

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}"
}

Дополнительным преимуществом этого является возможность развертывания в нескольких регионах с одинаковой конфигурацией и без переменной карты!

Ответ 2

"Официальным" способом, рекомендованным Hashicorp, является использование своего продукта Atlas как "посредника" между ними. Вы должны использовать постпроцессор Atlas в Packer для записи артефактов (идентификаторы AMI в вашем случае), а затем используйте ресурс atlas_artifact в Terraform, чтобы прочитать идентификаторы снова для использования в Terraform.

В этом случае вы должны получить идентификаторы из ресурса, а не передавать их при использовании переменных.

Помимо атласа, другие варианты довольно ограничены, а в некоторых случаях хакерские.

Если вы хотите сделать это без каких-либо внешних сервисов, вы можете поэкспериментировать с локальным пост-процессором оболочки в качестве способа запуска локальной команды на своем артефакт, или вы можете использовать машиночитаемый вывод для извлечения идентификаторов AMI и записать их в файл переменных для Terraform.

Еще один вариант - написать свой собственный постпроцессорный плагин, который взаимодействует с некоторым программным обеспечением, которое вы уже используете, в качестве альтернативы Atlas. Например, с некоторыми из моих коллег я написал постпроцессор для записи артефактов как метаданных в Buildkite, которые затем мы извлекаем с помощью API Buildkite. Для этого требуется написать собственный код в Go.

На момент написания Terraform версия 0.7 все еще находится в разработке, но планируется включить новую функцию, которая позволяет напрямую запрашивать API EC2 для AMI, который (если он действительно приземляется на 0,7) позволяет еще один вариант пометка AMI с помощью Packer, а затем поиск его непосредственно из EC2 с использованием этих тегов. Это использует EC2 как "посредника", что, возможно, менее неудобно, поскольку оно уже было задействовано как хранилище для AMI.