Как передать/объединить переменную в раздел «data.aws_ami` в ресурсе «aws_instance»

#variables #amazon-ec2 #terraform #terraform-provider-aws

Вопрос:

У меня возникли трудности с определением переменной внутри ami=data.aws_ami.$var.ami_name.id строки.

Я пробовал ami= "${data.aws_ami.(var.ami_name).id}" , но в обоих случаях я получаю:

 79: ami = data.aws_ami.(var.ami_name)).id │  │ An attribute name is required after a dot.  

Он работает только со строковым значением data.aws_ami.ubuntu-1804.id .

Мой вопрос в том, как связать переменную с ? data.aws_ami

Конечная цель состоит в обеспечении на основе различных экземпляров OS ec2 (Suse,Ubuntu,RHEL) Все зависит от переменной, предоставленной при ее развертывании.

 variable "ami_name" {  default = "ubuntu" }  data "aws_ami" "amazon" {  most_recent = true  owners = ["amazon"]  filter {  name = "name"  values = ["amzn2-ami-hvm*"]  } }  data "aws_ami" "ubuntu" {  most_recent = true  owners = ["099720109477"] # Canonical  filter {  name = "name"  values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]  }  filter {  name = "virtualization-type"  values = ["hvm"]  } }  resource "aws_instance" "linux" {  key_name = var.ami_key_pair_name  //ami = var.ami_id  //I want this to be dynamic so I can deploy either Amazon or Ubuntu in all regions.   ami = data.aws_ami.$var.ami_name.id   //ami = data.aws_ami.ubuntu.id # this works  instance_type = "t2.micro" tags = {  Name = var.instance_name  }  vpc_security_group_ids = [  aws_security_group.allow-ssh-http.id  ] }  

Я провел поиск, но не смог найти ничего связанного. Я использую Terraform v0.15.4

Комментарии:

1. Пожалуйста, добавьте data.aws_ami к вопросу и укажите различия между ними.

Ответ №1:

Код, который вы показываете: data.aws_ami.$var.ami_name.id это недопустимый синтаксис терраформирования.

Вот возможность того, о чем вы просите:

 provider "aws" { region = "us-east-2" }  locals {  allowed_os = {  "amazon": {owner: "amazon", filter: "amzn2-ami-hvm*"},  "suse": {owner: "amazon", filter: "*suse*"},  "RHEL": {owner: "amazon", filter: "*RHEL*"},  "ubuntu": {owner: "099720109477", filter: "*ubuntu-bionic-18.04-amd64-*"},  } }  variable "ami_name" {  default = "ubuntu"   validation {  condition = can(regex("amazon|suse|RHEL|ubuntu", var.ami_name))  error_message = "Invalid ami name, allowed_values = [amazon suse RHEL ubuntu]."  } }  data "aws_ami" "os" {  for_each = local.allowed_os   most_recent = true  owners = [each.value.owner]  filter {  name = "name"  values = [each.value.filter]  } }  resource "aws_instance" "linux" {  ami = data.aws_ami.os[var.ami_name].id  instance_type = "t2.micro"  # ... todo add arguments here }  

Мой подход здесь заключается в использовании a for_each в aws_ami, что даст нам массив, который мы сможем использовать позже в ресурсе aws_instance:

  • data.aws_ami.os["ubuntu"].id
    Здесь мы используем жестко закодированное значение для доступа к определенному AMI в вашем коде.
  • data.aws_ami.os[var.ami_name].id
    Или таким образом с переменной, которая будет предоставлена пользователем или файлом конфигурации.

Вы можете добавить больше элементов в массив, чтобы добавить другие операционные системы, и то же самое с фильтрами, вы можете просто изменить allowed_os локальную переменную в соответствии с вашими потребностями.

В качестве дополнительного я добавил проверку в вашу ami_name переменную, чтобы она соответствовала разрешенным различным ОС, которые мы используем в for_each, таким образом, мы предотвращаем любые проблемы прямо перед тем, как они могут привести к ошибкам.

Комментарии:

1. спасибо за вашу помощь. к сожалению, это не сработало для меня. Все еще пытаюсь сообразить, как это будет работать для разных ОС, если владельцами являются «amazon». Как бы я соотнес ваш код со значениями по умолчанию data "aws_ami" "ubuntu"{} , указывающими на последнее изображение?

2. @greenszpila с самого начала ваш вопрос был не очень подробным … у вас нет кода для aws_ami того, чтобы, возможно, прояснить все это, и мы можем вернуться к этому… Есть ли у вас какой-либо опыт работы с массивами в terraform? Вы разработали план на моем примере?

3. спасибо, что перезвонил мне. Я хотел бы иметь одно развертывание и в зависимости от переменной, указанной в ami строке в resource разделе. Это позволит развернуть либо экземпляр ec2 на базе ubuntu, amazon, rhel. Команда, которую я использую,- terraform apply-var-file=ubuntu.tf для образа ubuntu и так далее. Я добавил оба aws_ami раздела в приведенный выше код. Нет, у меня нет опыта работы с массивами в tf, и когда я запускаю план с вашим примером, у меня возникают странные ошибки, связанные с UEFI. Спасибо.

4. @greenszpila Я обновил свой код, чтобы следить за тем, что вы делаете на своем aws_ami

5. спасибо @HelderSepulveda, это сработало, очень ценю это. большое спасибо!