[英]Terraform variable inteporlation and evaluation
I'm working with modules in Terraform using Yaml approach to manage variables.我正在使用 Yaml 方法在 Terraform 中处理模块来管理变量。 I have a very simple module that should create parameter in AWS Parameter Store based on my RDS and IAM User modules output.So, I wrote this module:我有一个非常简单的模块,它应该根据我的 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
}
The variables I'm using are stored into a Yaml file like this:我使用的变量存储在这样的 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
As we can see, I have in "value" the module output I would like to send to Parameter Store.如我们所见,我在“值”中设置了我想发送到 Parameter Store 的模块输出。 I'm loading this variable file using file and yamldecode functions:我正在使用 file 和 yamldecode 函数加载这个变量文件:
ssmfile = "./env/${terraform.workspace}/ssm.yaml"
ssmfilecontent = fileexists(local.ssmfile) ? file(local.ssmfile) : "ssmFileNotFound: true"
ssmsettings = yamldecode(local.ssmfilecontent)
So, I have a local.ssmsettings and I can write a module call like this:所以,我有一个 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
}
Doing this, my parameter is stored as:这样做,我的参数存储为:
{
"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"
}
}
Value is receiving the string module.rds_instance.database_username instead of the module output.值正在接收字符串 module.rds_instance.database_username 而不是模块输出。
I know that file
function doesn't interpolate variables and I know Terraform doesn't have an eval
function.我知道file
函数不会插入变量,而且我知道 Terraform 没有eval
函数。
Does anybody had the same situation that can tell me how you solved the problem or have any clue that I can follow?有没有人有同样的情况可以告诉我你是如何解决这个问题的,或者有什么线索可以让我遵循?
I already tried to work with Terraform templates, without success.我已经尝试使用 Terraform 模板,但没有成功。
Thanks in advance.提前致谢。
Terraform has no way to understand that the value
strings in your YAML files are intended to be references to values elsewhere in your module, and even if it did it wouldn't be possible to resolve them from there because this YAML file is not actually a part of the Terraform module, and is instead just a data file that Terraform has loaded into memory. Terraform 无法理解 YAML 文件中的value
字符串旨在引用模块中其他地方的值,即使它理解了也无法从那里解析它们,因为这个 YAML 文件实际上不是一个Terraform 模块的一部分,而只是 Terraform 加载到内存中的数据文件。
However, you can get a similar effect by placing all of the values your YAML file might refer to into a map of strings inside your module:但是,您可以通过将 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
})
}
Then change your YAML data so that the value
strings match with the keys in this map:然后更改您的 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
You can then substitute the real values instead of the placeholders before you use the data structure in for_each
:然后,您可以在使用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
}
The for
expression in the definition of local.ssms
uses the source value
string as a lookup key into local.ssm_indirect_values
, thereby inserting the real value. local.ssms
定义中的for
表达式使用源value
字符串作为local.ssm_indirect_values
中的查找键,从而插入实际值。
The module "ssm_parameter"
block now refers to the derived local.ssms
instead of the original local.ssm_settings.ssms
, so each.value.value
will be the final resolved value rather than the lookup key, and so your parameter should be stored as you intended. module "ssm_parameter"
块现在引用派生的local.ssms
而不是原始的local.ssm_settings.ssms
,因此each.value.value
将是最终解析的值而不是查找键,因此您的参数应存储为你打算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.