[英]Terraform variable inteporlation and evaluation
我正在使用 Yaml 方法在 Terraform 中处理模块来管理变量。 我有一个非常简单的模块,它应该根据我的 RDS 和 IAM 用户模块输出在 AWS Parameter Store 中创建参数。所以,我编写了这个模块:
resource "aws_ssm_parameter" "ssm_parameter" {
name = var.parameter_name
type = var.parameter_type
value = var.parameter_value
overwrite = var.overwrite
tags = var.tags
}
我使用的变量存储在这样的 Yaml 文件中:
ssms:
/arquitetura/catalogo/gitlab/token:
type: SecureString
value: ManualInclude
/arquitetura/catalogo/s3/access/key:
type: String
value: module.iam_user.access_key
/arquitetura/catalogo/s3/secret/access/key:
type: SecureString
value: module.iam_user.secret_access_key
/arquitetura/catalogo/rds/user:
type: String
value: module.rds_instance.database_username
/arquitetura/catalogo/rds/password:
type: SecureString
value: module.rds_instance.database_password
如我们所见,我在“值”中设置了我想发送到 Parameter Store 的模块输出。 我正在使用 file 和 yamldecode 函数加载这个变量文件:
ssmfile = "./env/${terraform.workspace}/ssm.yaml"
ssmfilecontent = fileexists(local.ssmfile) ? file(local.ssmfile) : "ssmFileNotFound: true"
ssmsettings = yamldecode(local.ssmfilecontent)
所以,我有一个 local.ssmsettings,我可以像这样编写一个模块调用:
module "ssm_parameter" {
source = "../aws-ssm-parameter-tf"
for_each = local.ssmsettings.ssms
parameter_name = each.key
parameter_type = each.value.type
parameter_value = each.value.value
tags = local.tags
}
这样做,我的参数存储为:
{
"Parameter": {
"Name": "/arquitetura/catalogo/rds/user",
"Type": "String",
"Value": "module.rds_instance.database_username",
"Version": 1,
"LastModifiedDate": "2022-12-15T19:02:01.825000-03:00",
"ARN": "arn:aws:ssm:sa-east-1:111111111111:parameter/arquitetura/catalogo/rds/user",
"DataType": "text"
}
}
值正在接收字符串 module.rds_instance.database_username 而不是模块输出。
我知道file
函数不会插入变量,而且我知道 Terraform 没有eval
函数。
有没有人有同样的情况可以告诉我你是如何解决这个问题的,或者有什么线索可以让我遵循?
我已经尝试使用 Terraform 模板,但没有成功。
提前致谢。
Terraform 无法理解 YAML 文件中的value
字符串旨在引用模块中其他地方的值,即使它理解了也无法从那里解析它们,因为这个 YAML 文件实际上不是一个Terraform 模块的一部分,而只是 Terraform 加载到内存中的数据文件。
但是,您可以通过将 YAML 文件可能引用的所有值放入模块内的字符串映射中来获得类似的效果:
locals {
ssm_indirect_values = tomap({
manual_include = "ManualInclude"
aws_access_key_id = module.iam_user.access_key
aws_secret_access_key = module.iam_user.secret_access_key
database_username = module.rds_instance.database_username
database_password = module.rds_instance.database_password
})
}
然后更改您的 YAML 数据,使value
字符串与此映射中的键匹配:
ssms:
/arquitetura/catalogo/gitlab/token:
type: SecureString
value: manual_include
/arquitetura/catalogo/s3/access/key:
type: String
value: aws_access_key_id
/arquitetura/catalogo/s3/secret/access/key:
type: SecureString
value: aws_secret_access_key
/arquitetura/catalogo/rds/user:
type: String
value: database_username
/arquitetura/catalogo/rds/password:
type: SecureString
value: database_password
然后,您可以在使用for_each
中的数据结构之前替换实际值而不是占位符:
locals {
ssm_file = "${path.module}/env/${terraform.workspace}/ssm.yaml"
ssm_file_content = file(local.ssm_file)
ssm_settings = yamldecode(local.ssm_file_content)
ssms = tomap({
for k, obj in local.ssm_settings.ssms :
k => {
type = obj.type
value = local.ssm_indirect_values[obj.value]
}
})
}
module "ssm_parameter" {
source = "../aws-ssm-parameter-tf"
for_each = local.ssms
parameter_name = each.key
parameter_type = each.value.type
parameter_value = each.value.value
tags = local.tags
}
local.ssms
定义中的for
表达式使用源value
字符串作为local.ssm_indirect_values
中的查找键,从而插入实际值。
module "ssm_parameter"
块现在引用派生的local.ssms
而不是原始的local.ssm_settings.ssms
,因此each.value.value
将是最终解析的值而不是查找键,因此您的参数应存储为你打算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.