как динамически создавать terraform local_file - PullRequest
0 голосов
/ 24 апреля 2020

Я хочу создать несколько экземпляров EC2 и захватить их private_ips в файл стиля ec2.ini для дальнейшего использования с Ansible.

resource "local_file" "ec2_id" {
  count = var.instance_count
  content  = "${aws_instance.instance[count.index].private_ip} ansible_ssh_user=ec2-user\n"
  filename = "ec2.ini"
}

Это всегда печатает private_ip последнего созданного экземпляра EC2.

Любая идея, как решить эту проблему.

Обновление: -

data "template_file" "hehe" {
  count = var.instance_count
  template = "${element(aws_instance.instance.*.private_ip, count.index)} ansible_ssh_user=ec2-user subnetmask=${element(split("/", data.aws_subnet.selected-subnet-id.cidr_block),1)}\n"
}


resource "local_file" "ec2_id" {
  count = var.instance_count
  content  = "${element(data.template_file.hehe.*.rendered, count.index)}"
  filename = "ec2.ini"
}

не работает. дает мне последний созданный экземпляр private_ip.

1 Ответ

1 голос
/ 24 апреля 2020

Когда вы используете count внутри ресурса, вы просите Terraform создать несколько экземпляров этого ресурса. Однако в вашем случае вы не включили count.index в аргумент filename, и поэтому все ваши экземпляры конкурируют за перезапись одного и того же имени файла ec2.ini, и поэтому только один из них может "победить".

Похоже, ваша цель - создать только один файл, содержащий все IP-адреса. Это очень близко к одному из примеров, которые содержатся в документации Terraform String Templates на момент написания этой статьи, которую мы можем адаптировать к вашей цели следующим образом:

resource "local_file" "ec2_iini" {
  filename = "ec2.ini"
  content = <<-EOT
    %{ for ip in aws_instance.instance.*.private_ip ~}
    ${ip} ansible_ssh_user=ec2-user
    %{ endfor ~}
  EOT
}

In В приведенном выше примере сам ресурс local_file имеет , а не имеет count, потому что наша цель - создать только один файл. Вместо этого мы используем директиву шаблона for Terraform *, чтобы повторять шаблон строки один раз за экземпляр, собирая результат в виде одной строки, которую local_file может затем использовать в качестве аргумента content.

Я использовал здесь «heredo c» стиль строковый литерал , потому что я думаю, что это облегчает чтение директивы for, разбивая ее на несколько строк. Символ - в <<-EOT заставляет Terraform просмотреть все строки между открывающим <<-EOT и закрывающим EOT и найти наименьшее количество начальных пробелов, которые имеют эти линии, которые затем будут удалены рендеринг. Это означает, что вы можете иметь шаблон с отступом в вашей конфигурации, но избегайте тех отступов, которые появляются в отображаемой строке, которая должна выглядеть примерно так:

10.1.0.34 ansible_ssh_user=ec2-user
10.1.0.5 ansible_ssh_user=ec2-user
10.1.0.92 ansible_ssh_user=ec2-user

Маркеры ~ на конце двух * Директивы 1034 * предписывают механизму шаблонов Terraform игнорировать символы новой строки и пробелы после них, поэтому мы можем переносить шаблон на несколько строк, не вводя дополнительные символы новой строки в результат. Единственная строка шаблона, которая генерирует завершающий символ новой строки здесь, - это средняя строка, содержащая интерполяцию IP-адреса и часть ansible_ssh_user, поэтому в результате получается только одна строка новой строки на запись, как здесь и должно быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...