使自定义 Terraform 提供程序中的地图值敏感

时间:2021-04-25 15:45:46

标签: terraform

我正在编写一个自定义 Terraform 提供程序,并且我有一个资源,该资源具有一个 map[string]string 参数,该参数可能包含敏感值。我想让 values 敏感而不是键。我尝试将地图中 SensitiveElem 属性设置为 true(参见下面的示例),但我仍然在计划阶段将值打印到控制台。

return &schema.Resource{
    // ...
    Schema: map[string]*schema.Schema{
        "sensitive_map": {
            Type:     schema.TypeMap,
            Optional: true,
            Elem: &schema.Schema{
                Type: schema.TypeString,
                // Sensitive: true,
            },
        },
    },
}

示例计划阶段输出:

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # deploy_project.this will be created
  + resource "my_resource" "this" {
      + sensitive_map                  = {
          + "key" = "value"
        }
      + id                        = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

如何将值标记为敏感而不是密钥?

2 个答案:

答案 0 :(得分:1)

在 Terraform SDK 的当前灵敏度模型中,无法实现您的目标。一次为整个属性设置敏感度,而不是为部分属性设置。

虽然为了方便起见,SDK 模型重新使用 *schema.Schema 作为 Elem 的可能类型,但实际上只有 schema.Schema 字段的一小部分可以在该位置工作,因为这样的声明与在 Terraform 模块中声明如下变量大致相同:

variable "sensitive_map" {
  type      = map(string)
  sensitive = true
}

请注意,“敏感”概念适用于整个变量。它不是变量类型约束的一部分,因此没有任何方法可以将“敏感字符串映射”写为类型约束。尽管提供者参数实际上不是模块变量,但它们仍然参与与变量相同的值和类型系统,因此具有一组相似的功能。

答案 1 :(得分:0)

我结束了使用嵌套块而不是简单地图的解决方案。模式定义比简单的映射更复杂,它使用户空间配置更加冗长,但它确实很好地满足了我的初始要求。

"sensitive_map": {
    Type:     schema.TypeList,
    Optional: true,
    Elem: &schema.Resource{
        Schema: map[string]*schema.Schema{
            "key": {
                Type:     schema.TypeString,
                Required: true,
                Elem:     &schema.Schema{Type: schema.TypeString},
            },
            "value": {
                Type:      schema.TypeString,
                Required:  true,
                Sensitive: true,
                Elem:      &schema.Schema{Type: schema.TypeString},
            },
        },
    },
},

它在计划阶段显示为:

  + resource "my_resource" "this" {
      + sensitive_map {
          + key   = "foo"
          + value = (sensitive value)
        }
    }

它将 Go 中的表示从 map[string]string 更改为 map[string]interface{},其中空接口本身就是 map[string]string。在资源的 Create 钩子中,这是解析输入配置的代码:

sensitiveMap := make(client.EnvVars)
tmp := d.Get("sensitive_map").([]interface{})
for _, v := range tmp {
    keyval := v.(map[string]interface{})
    vars[keyval["key"].(string)] = keyval["value"].(string)
}

我相信它可以进一步优化,但现在它工作得很好!