如何将变量传递/连接到`aws_instance`资源中的`data.aws_ami`部分
Posted
技术标签:
【中文标题】如何将变量传递/连接到`aws_instance`资源中的`data.aws_ami`部分【英文标题】:How to pass/concat variable into the `data.aws_ami` section in the `aws_instance` resource 【发布时间】:2021-12-22 11:11:38 【问题描述】:我在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
添加到问题中并说明它们之间的区别。
【参考方案1】:
您显示的代码:data.aws_ami.$var.ami_name.id
这不是有效的 terraform 语法。
这是您所要求的可能性:
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 中使用的允许的不同操作系统,这样我们就可以防止任何问题在它们导致错误之前发生。
【讨论】:
感谢您的帮助。不幸的是,这对我不起作用。如果所有者是“亚马逊”,我仍然试图弄清楚这将如何适用于不同的操作系统。我如何将您的代码与默认的data "aws_ami" "ubuntu"
相关联,其值指向最新的图像?
@greenszpila 你的问题一开始就不是很详细......你没有aws_ami
的代码也许可以澄清所有这些,我们可以重新审视这个......你对数组有任何经验吗在地形?你用我的例子制定了计划吗?
感谢您回复我。我想要一个部署并取决于ami
行中resource
部分中指定的变量。这将部署基于 ubuntu、amazon、rhel 的 ec2 实例。我使用的命令是 terraform apply -var-file=ubuntu.tf for ubuntu image 等等。我已经在上面的代码中添加了aws_ami
部分。不,我没有使用 tf 中的数组的经验,当我使用您的示例运行计划时,我遇到了与 UEFI 相关的奇怪错误。谢谢。
@greenszpila 我更新了我的代码以遵循您在 aws_ami 上所做的事情
感谢@HelderSepulveda,这很有效,非常感谢。非常感谢!以上是关于如何将变量传递/连接到`aws_instance`资源中的`data.aws_ami`部分的主要内容,如果未能解决你的问题,请参考以下文章