如何将/concat变量传递到`aws_instance`资源中的`data.aws_ami`部分



我在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

最终目标是根据不同的操作系统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

您显示的代码: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
}

我在这里的方法是在aws_ami中使用for_each,这将给我们一个数组,我们可以稍后在aws_instance资源中使用它:

  • data.aws_ami.os["ubuntu"].id
    这里我们使用硬编码值来访问代码中的特定AMI。

  • data.aws_ami.os[var.ami_name].id
    或者通过这种方式使用将由用户或配置文件提供的变量。

您可以向数组中添加更多项以添加其他操作系统,与筛选器相同,您只需更改allowed_os本地变量即可满足您的需要。

另外,我为您的ami_name变量添加了验证,以匹配我们在for_each中使用的允许的不同操作系统,这样我们就可以在问题导致错误之前防止任何问题。

最新更新