我不确定这是否是正确的方法,但我想使用变量作为属性。
例如,我有一个根据用户输入而变化的变量:os_name = ubuntu
。
我想像下面这样使用这个变量名,
resource "aws_instance" "workerNode" {
..................
ami = data.aws_ami.${var.os_name}.image_id
..................
}
以下是数据块的示例
data "aws_ami" "suse" {
count = "${var.os_name == "suse" ? 1 : 0}"
owners = ["amazon"]
most_recent = true
filter {
name = "name"
values = ["suse-sles-${var.os_version}-sp*-v????????-hvm-ssd-x86_64"]
}
}
结果如下,
"architecture" = "x86_64"
"hypervisor" = "xen"
"id" = "ami-0d3905203a039e3b0"
"image_id" = "ami-0d3905203a039e3b0"
但地形不允许我这么做。有什么办法可以做到这一点,或者我必须更改工作流程吗?
在不适合使用for_each
将所有实例收集到单个资源下的情况下(这会隐式地使该资源显示为对象映射(,可以通过编写本地值表达式来构造等效映射来显式地获得类似的结果:
locals {
amis = {
suse = data.aws_ami.suse
ubuntu = data.aws_ami.ubuntu
}
}
然后,您可以引用local.amis["ubuntu"]
或local.amis["suse"]
(如果需要,可以用变量替换元素键。
话虽如此,但对于您的情况,似乎有一种可能的不同方法,只需一个data
块即可实现:
locals {
os_ami_queries = {
suse = {
owners = ["amazon"]
filters = {
name = ["suse-sles-${var.os_version}-sp*-v????????-hvm-ssd-x86_64"]
}
}
ubuntu = {
owners = ["amazon"]
filters = {
name = ["ubuntu-${var.os_version}-something-something"]
}
}
}
ami_query = local.os_ami_queries[var.os_name]
}
data "aws_ami" "selected" {
owners = local.ami_query.owners
dynamic "filter" {
for_each = local.ami_query.filters
content {
name = filter.key
values = filter.value
}
}
}
这种不同的排列在data "aws_ami"
查找之前执行操作系统选择,因此它可以使用与调用方选择的任何操作系统相关的设置。AMI id将在data.aws_ami.selected.id
中。
话虽如此,这种方法的缺点是非常间接,并且使用了dynamic
块,所以我会将其与备选方案的可读性进行权衡,以选择一个对于不熟悉这种配置的人来说主观上最容易遵循的方案。对此没有一个单一的答案,因为在某种程度上这是一个品味问题,因此,如果你在团队环境中工作,这可能是一件需要与同事讨论的事情,看看哪种方法最适合权衡,比如你希望多久添加和删除一次受支持的操作系统,而不是改变如何使用结果的细节。
您可以通过用for_each
指定AMI,从而获得可以通过键访问的map
来使其工作。
我的data.aws_ami.myamis
看起来像这样:
data "aws_ami" "myamis" {
for_each = toset(["suse", "ubuntu"])
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["${each.value}*"]
}
}
出于测试目的,我定义了一个变量foo
,如下所示:
variable "foo" {
type = string
default = "suse"
}
现在我可以这样访问AMI:
$ tf console
> data.aws_ami.myamis[var.foo].image_id
"ami-0ea50c090ba6e85c5"
您可以根据os_name
和os_version
的需要进行调整。
我只通过使用条件表达式就解决了这个问题。
我不确定这是否是一种标准的做事方式,但它对我有效
我尝试过用嵌套的条件表达式来模拟if/elif/else。
output "name" {
value = "${ var.os_name == "ubuntu" ? data.aws_ami.ubuntu[0].image_id : (var.os_name == "redhat" ? data.aws_ami.redhat[0].image_id : (var.os_name == "centos" ? data.aws_ami.suse[0].image_id : data.aws_ami.suse[0].image_id ))}"
}