繁体   English   中英

Terraform 变量的插值和评估

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM