Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make terraform_labels field immutable for immutable resources #16469

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/9394.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
provider: made `terraform_labels` immutable in immutable resources to not block the upgrade. This will create a Terraform plan that recreates the resource on `4.X` -> `5.6.0` upgrade for affected resources. A mitigation to backfill the values during the upgrade is planned, and will release resource-by-resource.
```
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Please refer to the field 'effective_labels' for all of the labels present on th
"terraform_labels": {
Type: schema.TypeMap,
Computed: true,
ForceNew: true,
Description: `The combination of labels configured directly on the resource
and default labels configured on the provider.`,
Elem: &schema.Schema{Type: schema.TypeString},
Expand Down
1 change: 1 addition & 0 deletions google/services/bigquery/resource_bigquery_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ Creation, truncation and append actions occur as one atomic update upon job comp
"terraform_labels": {
Type: schema.TypeMap,
Computed: true,
ForceNew: true,
Description: `The combination of labels configured directly on the resource
and default labels configured on the provider.`,
Elem: &schema.Schema{Type: schema.TypeString},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`,
"terraform_labels": {
Type: schema.TypeMap,
Computed: true,
ForceNew: true,
Description: `The combination of labels configured directly on the resource
and default labels configured on the provider.`,
Elem: &schema.Schema{Type: schema.TypeString},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-c
"terraform_labels": {
Type: schema.TypeMap,
Computed: true,
ForceNew: true,
Description: `The combination of labels configured directly on the resource
and default labels configured on the provider.`,
Elem: &schema.Schema{Type: schema.TypeString},
Expand Down
32 changes: 32 additions & 0 deletions google/services/cloudrun/resource_cloud_run_domain_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,35 @@ resource "google_cloud_run_domain_mapping" "default" {
}
`, context)
}

func TestAccCloudRunDomainMapping_migration(t *testing.T) {
acctest.SkipIfVcr(t)
t.Parallel()

context := map[string]interface{}{
"namespace": envvar.GetTestProjectFromEnv(),
"random_suffix": acctest.RandString(t, 10),
}

oldVersion := map[string]resource.ExternalProvider{
"google": {
VersionConstraint: "4.84.0", // a version that doesn't separate user defined labels and system labels
Source: "registry.terraform.io/hashicorp/google",
},
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
CheckDestroy: testAccCheckCloudRunDomainMappingDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccCloudRunDomainMapping_cloudRunDomainMappingUpdated2(context),
ExternalProviders: oldVersion,
},
{
Config: testAccCloudRunDomainMapping_cloudRunDomainMappingUpdated2(context),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
},
},
})
}
25 changes: 24 additions & 1 deletion google/services/compute/resource_compute_instance_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func ResourceComputeInstanceTemplate() *schema.Resource {
return &schema.Resource{
Create: resourceComputeInstanceTemplateCreate,
Read: resourceComputeInstanceTemplateRead,
Update: resourceComputeInstanceTemplateUpdate,
Delete: resourceComputeInstanceTemplateDelete,
Importer: &schema.ResourceImporter{
State: resourceComputeInstanceTemplateImportState,
Expand Down Expand Up @@ -358,6 +359,7 @@ Google Cloud KMS.`,
"metadata_fingerprint": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The unique fingerprint of the metadata.`,
},
"network_performance_config": {
Expand Down Expand Up @@ -421,6 +423,7 @@ Google Cloud KMS.`,
"name": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The name of the network_interface.`,
},
"nic_type": {
Expand Down Expand Up @@ -455,6 +458,7 @@ Google Cloud KMS.`,
"public_ptr_domain_name": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The DNS domain name for the public PTR record.The DNS domain name for the public PTR record.`,
},
},
Expand Down Expand Up @@ -489,47 +493,55 @@ Google Cloud KMS.`,
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"IPV4_ONLY", "IPV4_IPV6", ""}, false),
Description: `The stack type for this network interface to identify whether the IPv6 feature is enabled or not. If not specified, IPV4_ONLY will be used.`,
},

"ipv6_access_type": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `One of EXTERNAL, INTERNAL to indicate whether the IP can be accessed from the Internet. This field is always inherited from its subnetwork.`,
},

"ipv6_access_config": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Description: `An array of IPv6 access configurations for this interface. Currently, only one IPv6 access config, DIRECT_IPV6, is supported. If there is no ipv6AccessConfig specified, then this instance will have no external IPv6 Internet access.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"network_tier": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The service-level to be provided for IPv6 traffic when the subnet has an external subnet. Only PREMIUM tier is valid for IPv6`,
},
// Possibly configurable- this was added so we don't break if it's inadvertently set
// (assuming the same ass access config)
"public_ptr_domain_name": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The domain name to be used when creating DNSv6 records for the external IPv6 ranges.`,
},
"external_ipv6": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The first IPv6 address of the external IPv6 range associated with this instance, prefix length is stored in externalIpv6PrefixLength in ipv6AccessConfig. The field is output only, an IPv6 address from a subnetwork associated with the instance will be allocated dynamically.`,
},
"external_ipv6_prefix_length": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The prefix length of the external IPv6 range.`,
},
"name": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The name of this access configuration.`,
},
},
Expand All @@ -539,12 +551,14 @@ Google Cloud KMS.`,
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: true,
Description: `The prefix length of the primary internal IPv6 range.`,
},
"ipv6_address": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
DiffSuppressFunc: ipv6RepresentationDiffSuppress,
Description: `An IPv6 internal network address for this network interface. If not specified, Google Cloud will automatically assign an internal IPv6 address from the instance's subnetwork.`,
},
Expand Down Expand Up @@ -622,6 +636,7 @@ Google Cloud KMS.`,
"min_node_cpus": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
AtLeastOneOf: schedulingInstTemplateKeys,
Description: `Minimum number of cpus for the instance.`,
},
Expand All @@ -643,6 +658,7 @@ Google Cloud KMS.`,
"local_ssd_recovery_timeout": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Description: `Specifies the maximum amount of time a Local Ssd Vm should wait while
recovery of the Local Ssd state is attempted. Its value should be in
between 0 and 168 hours with hour granularity and the default value being 1
Expand Down Expand Up @@ -676,12 +692,14 @@ be from 0 to 999,999,999 inclusive.`,
"self_link": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The URI of the created resource.`,
},

"self_link_unique": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `A special URI of the created resource that uniquely identifies this instance template.`,
},

Expand Down Expand Up @@ -851,13 +869,13 @@ be from 0 to 999,999,999 inclusive.`,
"tags_fingerprint": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
Description: `The unique fingerprint of the tags.`,
},

"labels": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
Description: `A set of key/value label pairs to assign to instances created from this template.
Expand Down Expand Up @@ -1301,6 +1319,11 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
return resourceComputeInstanceTemplateRead(d, meta)
}

func resourceComputeInstanceTemplateUpdate(d *schema.ResourceData, meta interface{}) error {
// Only the field "labels" and "terraform_labels" is mutable
return resourceComputeInstanceTemplateRead(d, meta)
}

type diskCharacteristics struct {
mode string
diskType string
Expand Down
Loading