簡體   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