如何将 pass/concat 变量放入 `aws_instance` 资源中的 `data.aws_ami` 部分
How to pass/concat variable into the `data.aws_ami` section in the `aws_instance` resource
我在 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
您显示的代码: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 中使用的允许的不同 OS,这样我们就可以在他们可以之前防止任何问题导致错误。
我在 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
您显示的代码: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 中使用的允许的不同 OS,这样我们就可以在他们可以之前防止任何问题导致错误。