英文:
How to create a custom terraform datasource provider schema for a map of maps values?
问题
我有一个返回类型为map[string]map[string]string
的golang函数。
例如:
map[foo:map[name:abc env:dev id:465 project:e-1] boo:map[name:def env:prd id:82 project:e-1] doo:map[name:ght env:stg id:353 project:e-3]]
我为它创建了以下模式...
func dataSourceAccountHelper() *schema.Resource {
return &schema.Resource{
Read: accountHelperRead,
Schema: map[string]*schema.Schema{
"roles": {
Type: schema.TypeMap,
Elem: &schema.Schema{
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
Computed: true,
},
"id": &schema.Schema{
Computed: true,
Type: schema.TypeString,
},
},
}
}
并且创建了一个传递角色值到模式的创建方法
func rolesRead(d *schema.ResourceData, m interface{}) error {
filteredRoles := filterAccounts("john") // 返回`map[string]map[string]string`
if err := d.Set("account_map", filteredRoles); err != nil {
return err
}
d.SetId("-")
return nil
}
但是Terraform的输出是一个空映射,我该如何修复它,请帮忙
Outputs:
output = {
"roles" = tomap(null) /* of map of string */
"id" = tostring(null)
}
期望的输出如下
Outputs:
output = {
"roles" = {
foo = {name = "abc" env = "dev" id = 465 project = "e-1"}
boo = {name = "def" env = "prd" id = 82 project = "e-1"}
},
"id" = "-"
}
英文:
I have a golang function that returns roles of type map[string]map[string]string
eg:
map[foo:map[name:abc env:dev id:465 project:e-1] boo:map[name:def env:prd id:82 project:e-1] :doo[name:ght env:stg id:353 project:e-3]]
and I created a schema for it like the following...
func dataSourceAccountHelper() *schema.Resource {
return &schema.Resource{
Read: accountHelperRead,
Schema: map[string]*schema.Schema{
"roles": {
Type: schema.TypeMap,
Elem: &schema.Schema{
Type: schema.TypeMap,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
Computed: true,
},
"id": &schema.Schema{
Computed: true,
Type: schema.TypeString,
},
},
}
}
And the create method to pass the role values to the schema
func rolesRead(d *schema.ResourceData, m interface{}) error {
filteredRoles := filterAccounts("john") // returns `map[string]map[string]string`
if err := d.Set("account_map", filteredRoles); err != nil {
return err
}
//accountMaps := make(map[string]interface{})
d.SetId("-")
return nil
}
but the Terraform output is an empty map, how do I fix it please help
Outputs:
output = {
"roles" = tomap(null) /* of map of string */
"id" = tostring(null)
}
expecting output like
Outputs:
output = {
"roles" = { foo = {name = "abc" env = "dev" id= 465 project = "e-1"}
boo = {name = "efg" env = "prd" id= 82 project = "e-2"}
},
"id" = "-"
}
答案1
得分: 0
你在这里尝试做的事情是不可能的,因为你正在使用的是旧版的 Terraform SDK。Maps 只能包含原始类型:TypeString
、TypeInt
、TypeBool
。
要创建这种结构,你需要迁移到新的框架,该框架适用于现代 Terraform 的类型系统,而不是(对于 SDKv2)经典 Terraform v0.11 及更早版本的类型系统。
在 Terraform 插件框架中,与你在问题中尝试描述的结构相对应的是 MapNestedAttribute
,以下是你在问题中展示的模式结构的描述:
schema.MapNestedAttribute{
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
// ...
},
"env": schema.StringAttribute{
// ...
},
"id": schema.NumberAttribute{
// ...
},
"project": schema.StringAttribute{
// ...
},
},
},
}
这表示具有给定属性的对象映射,因此上述模式类型等同于在使用 Terraform 语言的类型约束语法 编写的 Terraform 模块中可能写的以下类型约束:
map(
object({
name = string
env = string
id = number
project = string
})
)
英文:
What you are trying to do here is not possbile with the legacy Terraform SDK that you are using. Maps can only be of primitive types: TypeString
, TypeInt
, TypeBool
.
To create this structure you'll need to migrate to the new framework, which is built for the type system of modern Terraform rather than (as is the case for SDKv2) the type system of classic Terraform v0.11 and earlier.
In the Terraform Plugin Framework, the equivalent structure to what you tried to describe here is MapNestedAttribute
, with the following describing the schema structure you showed in your question:
schema.MapNestedAttribute{
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
// ...
},
"env": schema.StringAttribute{
// ...
},
"id": schema.NumberAttribute{
// ...
},
"project": schema.StringAttribute{
// ...
},
},
},
}
This represents a map of objects with the given attributes, and so the above schema type is equivalent to the following type constraint as might be written in a Terraform module using the Terraform language's type constraint syntax:
map(
object({
name = string
env = string
id = number
project = string
})
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论