-
Notifications
You must be signed in to change notification settings - Fork 10.3k
terraform plan -generate-config-out fails for map nested objects with keys with spaces #35752
Copy link
Copy link
Labels
bugconfirmeda Terraform Core team member has reproduced this issuea Terraform Core team member has reproduced this issuenewnew issue not yet triagednew issue not yet triaged
Description
Terraform Version
Terraform v1.9.5
on darwin_amd64Terraform Configuration Files
provider "example" {
}
import {
to = example_example.myExample
id = "str"
}Debug Output
https://gist.github.com/henryrecker-pingidentity/ae09eb59b71a2d0c02526018760dd254
Expected Behavior
HCL should be generated with the expected values
Actual Behavior
Error, no HCL is generated:
Planning failed. Terraform encountered an error while generating this plan.
╷
│ Error: Missing key/value separator
│
│ on generated_resources.tf line 2:
│ (source code not available)
│
│ Expected an equals sign ("=") to mark the beginning of the attribute value. If you intended to given an
│ attribute name containing periods or spaces, write the name in quotes to create a string literal.
╵
Steps to Reproduce
terraform plan -generate-config-out=generated_resources.tf with a provider schema that has a MapNestedAttribute with a key that includes spaces.
A simple provider that reproduces this issue can be found here: https://github.com/henryrecker-pingidentity/terraform-provider-example/tree/GenerateConfigBug
Relevant provider code, note the "Use Case" name with the space.
func (r *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Example resource.",
Attributes: map[string]schema.Attribute{
"string_val": schema.StringAttribute{
Description: "Optional string attribute",
Optional: true,
},
"map_val": schema.MapNestedAttribute{
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"values": schema.SetAttribute{
ElementType: types.StringType,
Optional: true,
Description: "A Set of values",
},
},
},
Optional: true,
Description: "Extended Properties allows to store additional information for IdP/SP Connections. The names of these extended properties should be defined in /extendedProperties.",
},
},
}
}
// Metadata returns the resource type name.
func (r *exampleResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_example"
}
func (r *exampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
plan := exampleResourceModel{
StringVal: types.StringValue("str"),
MapVal: types.MapValueMust(types.ObjectType{
AttrTypes: map[string]attr.Type{
"values": types.SetType{
ElemType: types.StringType,
},
}}, map[string]attr.Value{
"Use Case": types.ObjectValueMust(map[string]attr.Type{
"values": types.SetType{
ElemType: types.StringType,
},
}, map[string]attr.Value{
"values": types.SetValueMust(types.StringType, []attr.Value{
types.StringValue("CIAM"),
}),
}),
}),
}
diags := resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
}
func (r *exampleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
plan := exampleResourceModel{
StringVal: types.StringValue("str"),
MapVal: types.MapValueMust(types.ObjectType{
AttrTypes: map[string]attr.Type{
"values": types.SetType{
ElemType: types.StringType,
},
}}, map[string]attr.Value{
"Use Case": types.ObjectValueMust(map[string]attr.Type{
"values": types.SetType{
ElemType: types.StringType,
},
}, map[string]attr.Value{
"values": types.SetValueMust(types.StringType, []attr.Value{
types.StringValue("CIAM"),
}),
}),
}),
}
diags := resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
}
// Update updates the resource and sets the updated Terraform state on success.
func (r *exampleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
plan := exampleResourceModel{
StringVal: types.StringValue("str"),
MapVal: types.MapValueMust(types.ObjectType{
AttrTypes: map[string]attr.Type{
"values": types.SetType{
ElemType: types.StringType,
},
}}, map[string]attr.Value{
"Use Case": types.ObjectValueMust(map[string]attr.Type{
"values": types.SetType{
ElemType: types.StringType,
},
}, map[string]attr.Value{
"values": types.SetValueMust(types.StringType, []attr.Value{
types.StringValue("CIAM"),
}),
}),
}),
}
diags := resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
}
// No backend so no logic needed
func (r *exampleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
}
func (r *exampleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("string_val"), req, resp)
}
Additional Context
No response
References
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugconfirmeda Terraform Core team member has reproduced this issuea Terraform Core team member has reproduced this issuenewnew issue not yet triagednew issue not yet triaged