我正在编写一个自定义Terraform提供程序,我有一个资源,它的参数是map[string]string
,可能包含敏感值。我想使值敏感,但不使键敏感。我尝试将映射中Elem
的Sensitive
属性设置为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.
如何将值标记为敏感值而不是密钥?
在Terraform SDK当前的灵敏度模型中,没有办法实现您的目标。灵敏度是一次为整个属性设置的,而不是为属性的部分设置的。
尽管为了方便起见,SDK模型重新使用*schema.Schema
作为Elem
的可能类型,但在实践中,只有schema.Schema
字段的一小部分可以在该位置工作,因为这样的声明与在Terraform模块中声明如下变量大致相同:
variable "sensitive_map" {
type = map(string)
sensitive = true
}
注意;敏感的";概念适用于整个变量。它不是变量类型约束的一部分,因此没有任何方法可以写下";敏感字符串映射";作为类型约束。尽管提供程序参数实际上不是模块变量,但它们仍然与变量一样参与相同的值和类型系统,因此具有类似的功能。
我最终选择了使用嵌套块而不是简单映射的解决方案。模式定义比简单的映射更复杂,它使得userland配置更详细,但它确实很好地满足了我最初的需求。
"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)
}
我相信它可以进一步优化,但现在它还可以!