如果资源使用count参数指定terraform中的多个资源,则有一个简单的语法,用于为资源实例提供专用字段的列表/数组。
例如
aws_subnet.foo.*.id
由于有很多版本可以声明具有复杂结构的变量,例如地图列表。
variable "data" {
type = "list"
default = [
{
id = "1"
...
},
{
id = "10"
...
}
]
}
我正在寻找可以为多种资源做的变量做同样的事情:将数组投影到数组元素的字段值数组。
不幸的是
var.data.*.id
不适用于资源。有可能这样做吗?
答案 0 :(得分:14)
template_file可以帮助你。
data "template_file" "data_id" {
count = "${length(var.data)}"
template = "${lookup(var.data[count.index], "id")}"
}
然后你得到一个列表"${data.template_file.data_id.*.rendered}"
,其元素的值是“id”。
你可以按照这样的索引获取它的元素
"${data.template_file.data_id.*.rendered[0]}"
或通过功能元素()
"${element(data.template_file.data_id.*.rendered, 0)}"
答案 1 :(得分:5)
在撰写本文时,Terraform在其插值语言中没有广义投影功能。 " splat语法"作为资源的特殊情况实施。
虽然可以使用深层结构,但使用起来还不方便,因此建议保持相对平坦。将来很可能会添加新的语言功能,以使这种东西更有用。
答案 2 :(得分:2)
如果找到了使用模板渲染的工作解决方案来绕过地图问题列表:
(2400 dots - 1234 dots) ÷ 32 dots/line ≈ 36 lines
这将产生以下输出:
resource "aws_instance" "k8s_master" {
count = "${var.master_count}"
ami = "${var.ami}"
instance_type = "${var.instance_type}"
vpc_security_group_ids = ["${aws_security_group.k8s_sg.id}"]
associate_public_ip_address = false
subnet_id = "${element(var.subnet_ids,count.index % length(var.subnet_ids))}"
user_data = "${file("${path.root}/files/user_data.sh")}"
iam_instance_profile = "${aws_iam_instance_profile.master_profile.name}"
tags = "${merge(
local.k8s_tags,
map(
"Name", "k8s-master-${count.index}",
"Environment", "${var.environment}"
)
)}"
}
data "template_file" "k8s_master_names" {
count = "${var.master_count}"
template = "${lookup(aws_instance.k8s_master.*.tags[count.index], "Name")}"
}
output "k8s_master_name" {
value = [
"${data.template_file.k8s_master_names.*.rendered}",
]
}
答案 3 :(得分:0)
一个可能更简单的答案是使用zipmap
函数。
从与ECS模板定义兼容的环境变量映射开始:
locals {
shared_env = [
{
name = "DB_CHECK_NAME"
value = "postgres"
},
{
name = "DB_CONNECT_TIMEOUT"
value = "5"
},
{
name = "DB_DOCKER_HOST_PORT"
value = "35432"
},
{
name = "DB_DOCKER_HOST"
value = "localhost"
},
{
name = "DB_HOST"
value = "my-db-host"
},
{
name = "DB_NAME"
value = "my-db-name"
},
{
name = "DB_PASSWORD"
value = "XXXXXXXX"
},
{
name = "DB_PORT"
value = "5432"
},
{
name = "DB_QUERY_TIMEOUT"
value = "30"
},
{
name = "DB_UPGRADE_TIMEOUT"
value = "300"
},
{
name = "DB_USER"
value = "root"
},
{
name = "REDIS_DOCKER_HOST_PORT"
value = "6380"
},
{
name = "REDIS_HOST"
value = "my-redis"
},
{
name = "REDIS_PORT"
value = "6379"
},
{
name = "SCHEMA_SCRIPTS_PATH"
value = "db-scripts"
},
{
name = "USE_LOCAL"
value = "false"
}
]
}
在同一文件夹中启动terraform console
以测试内置功能。如果尚未,可能需要terraform init
。
terraform console
在控制台内:
zipmap([for m in local.shared_env: m.name], [for m in local.shared_env: m.value])
观察每个列表项映射的输出是单个映射的名称-值对:
{
"DB_CHECK_NAME" = "postgres"
"DB_CONNECT_TIMEOUT" = "5"
"DB_DOCKER_HOST" = "localhost"
"DB_DOCKER_HOST_PORT" = "35432"
"DB_HOST" = "my-db-host"
"DB_NAME" = "my-db-name"
"DB_PASSWORD" = "XXXXXXXX"
"DB_PORT" = "5432"
"DB_QUERY_TIMEOUT" = "30"
"DB_UPGRADE_TIMEOUT" = "300"
"DB_USER" = "root"
"REDIS_DOCKER_HOST_PORT" = "6380"
"REDIS_HOST" = "my-redis"
"REDIS_PORT" = "6379"
"SCHEMA_SCRIPTS_PATH" = "db-scripts"
"USE_LOCAL" = "false"
}