Skip to content

Commit

Permalink
reduce name prefix in compute resources (#11448) (#19152)
Browse files Browse the repository at this point in the history
[upstream:ce440583cb42cfef57c0271cead35f41f3374d9f]

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Aug 15, 2024
1 parent 4d46319 commit d8b4d70
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .changelog/11448.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: changed the behavior of `name_prefix` in multiple Compute resources to allow for a longer max length of 54 characters. See the upgrade guide and resource documentation for more details.
```
15 changes: 10 additions & 5 deletions google/services/compute/resource_compute_instance_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ func ResourceComputeInstanceTemplate() *schema.Resource {
Optional: true,
Computed: true,
ForceNew: true,
Description: `Creates a unique name beginning with the specified prefix. Conflicts with name.`,
Description: `Creates a unique name beginning with the specified prefix. Conflicts with name. Max length is 54 characters. Prefixes with lengths longer than 37 characters will use a shortened UUID that will be more prone to collisions.`,
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
// https://cloud.google.com/compute/docs/reference/latest/instanceTemplates#resource
// uuid is 26 characters, limit the prefix to 37.
// shortened uuid is 9 characters, limit the prefix to 55.
value := v.(string)
if len(value) > 37 {
if len(value) > 54 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 37 characters, name is limited to 63", k))
"%q cannot be longer than 54 characters, name is limited to 63", k))
}
return
},
Expand Down Expand Up @@ -1377,7 +1377,12 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
if v, ok := d.GetOk("name"); ok {
itName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
itName = id.PrefixedUniqueId(v.(string))
prefix := v.(string)
if len(prefix) > 37 {
itName = tpgresource.ReducedPrefixedUniqueId(prefix)
} else {
itName = id.PrefixedUniqueId(prefix)
}
} else {
itName = id.UniqueId()
}
Expand Down
61 changes: 61 additions & 0 deletions google/services/compute/resource_compute_instance_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,45 @@ func TestAccComputeInstanceTemplate_invalidDiskType(t *testing.T) {
})
}

func TestAccComputeInstanceTemplate_withNamePrefix(t *testing.T) {
t.Parallel()

// 8 + 46 = 54 which is the valid max
normalPrefix := "tf-test-" + fmt.Sprintf("%046s", "")
reducedSuffixPrefix := "tf-test-" + fmt.Sprintf("%029s", "")
invalidPrefix := "tf-test-" + fmt.Sprintf("%047s", "")

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
Steps: []resource.TestStep{
{
Config: testAccComputeInstanceTemplate_withNamePrefix(normalPrefix),
},
{
ResourceName: "google_compute_instance_template.foobar",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"name_prefix"},
},
{
Config: testAccComputeInstanceTemplate_withNamePrefix(invalidPrefix),
PlanOnly: true,
ExpectError: regexp.MustCompile("cannot be longer than 54 characters"),
},
{
Config: testAccComputeInstanceTemplate_withNamePrefix(reducedSuffixPrefix),
},
{
ResourceName: "google_compute_instance_template.foobar",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"name_prefix"},
},
},
})
}

func TestAccComputeInstanceTemplate_withScratchDisk(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -2341,6 +2380,28 @@ resource "google_compute_instance_template" "foobar" {
`, suffix, suffix)
}

func testAccComputeInstanceTemplate_withNamePrefix(prefix string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
family = "debian-12"
project = "debian-cloud"
}
resource "google_compute_instance_template" "foobar" {
name_prefix = "%s"
machine_type = "n1-standard-1" // can't be e2 because of local-ssd
can_ip_forward = false
disk {
source_image = data.google_compute_image.my_image.name
auto_delete = true
boot = true
}
network_interface {
network = "default"
}
}
`, prefix)
}

func testAccComputeInstanceTemplate_with375GbScratchDisk(suffix string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ func ResourceComputeRegionInstanceTemplate() *schema.Resource {
Description: `Creates a unique name beginning with the specified prefix. Conflicts with name.`,
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
// https://cloud.google.com/compute/docs/reference/latest/instanceTemplates#resource
// uuid is 26 characters, limit the prefix to 37.
// uuid is 9 characters, limit the prefix to 54.
value := v.(string)
if len(value) > 37 {
if len(value) > 54 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 37 characters, name is limited to 63", k))
"%q cannot be longer than 54 characters, name is limited to 63", k))
}
return
},
Expand Down Expand Up @@ -1085,7 +1085,12 @@ func resourceComputeRegionInstanceTemplateCreate(d *schema.ResourceData, meta in
if v, ok := d.GetOk("name"); ok {
itName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
itName = id.PrefixedUniqueId(v.(string))
prefix := v.(string)
if len(prefix) > 37 {
itName = tpgresource.ReducedPrefixedUniqueId(prefix)
} else {
itName = id.PrefixedUniqueId(prefix)
}
} else {
itName = id.UniqueId()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ If it is not provided, the provider region is used.`,
Description: "Creates a unique name beginning with the specified prefix. Conflicts with name.",
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
// https://cloud.google.com/compute/docs/reference/latest/sslCertificates#resource
// uuid is 26 characters, limit the prefix to 37.
// uuid is 9 characters, limit the prefix to 54.
value := v.(string)
if len(value) > 37 {
if len(value) > 54 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 37 characters, name is limited to 63", k))
"%q cannot be longer than 54 characters, name is limited to 63", k))
}
return
},
Expand Down Expand Up @@ -456,7 +456,12 @@ func expandComputeRegionSslCertificateName(v interface{}, d tpgresource.Terrafor
if v, ok := d.GetOk("name"); ok {
certName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
certName = id.PrefixedUniqueId(v.(string))
prefix := v.(string)
if len(prefix) > 37 {
certName = tpgresource.ReducedPrefixedUniqueId(prefix)
} else {
certName = id.PrefixedUniqueId(prefix)
}
} else {
certName = id.UniqueId()
}
Expand Down
13 changes: 9 additions & 4 deletions google/services/compute/resource_compute_ssl_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ These are in the same namespace as the managed SSL certificates.`,
Description: "Creates a unique name beginning with the specified prefix. Conflicts with name.",
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
// https://cloud.google.com/compute/docs/reference/latest/sslCertificates#resource
// uuid is 26 characters, limit the prefix to 37.
// uuid is 9 characters, limit the prefix to 54.
value := v.(string)
if len(value) > 37 {
if len(value) > 54 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 37 characters, name is limited to 63", k))
"%q cannot be longer than 54 characters, name is limited to 63", k))
}
return
},
Expand Down Expand Up @@ -422,7 +422,12 @@ func expandComputeSslCertificateName(v interface{}, d tpgresource.TerraformResou
if v, ok := d.GetOk("name"); ok {
certName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
certName = id.PrefixedUniqueId(v.(string))
prefix := v.(string)
if len(prefix) > 37 {
certName = tpgresource.ReducedPrefixedUniqueId(prefix)
} else {
certName = id.PrefixedUniqueId(prefix)
}
} else {
certName = id.UniqueId()
}
Expand Down
7 changes: 6 additions & 1 deletion google/services/workflows/resource_workflows_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,12 @@ func resourceWorkflowsWorkflowEncoder(d *schema.ResourceData, meta interface{},
if v, ok := d.GetOk("name"); ok {
ResName = v.(string)
} else if v, ok := d.GetOk("name_prefix"); ok {
ResName = id.PrefixedUniqueId(v.(string))
prefix := v.(string)
if len(prefix) > 37 {
ResName = tpgresource.ReducedPrefixedUniqueId(prefix)
} else {
ResName = id.PrefixedUniqueId(prefix)
}
} else {
ResName = id.UniqueId()
}
Expand Down
14 changes: 14 additions & 0 deletions google/tpgresource/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/hashicorp/go-cty/cty"
fwDiags "github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"golang.org/x/exp/maps"
Expand Down Expand Up @@ -880,3 +881,16 @@ func DefaultProviderZone(_ context.Context, diff *schema.ResourceDiff, meta inte

return nil
}

// id.UniqueId() returns a timestamp + incremental hash
// This function truncates the timestamp to provide a prefix + 9 using
// YYmmdd + last 3 digits of the incremental hash
func ReducedPrefixedUniqueId(prefix string) string {
// uniqueID is timestamp + 8 digit counter (YYYYmmddHHMMSSssss + 12345678)
uniqueId := id.PrefixedUniqueId("")
// last three digits of the counter (678)
counter := uniqueId[len(uniqueId)-3:]
// YYmmdd of date
date := uniqueId[2:8]
return prefix + date + counter
}
9 changes: 7 additions & 2 deletions website/docs/guides/version_6_upgrade.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,14 @@ terraform {

## Provider

### Provider-level change example header
### Compute: `name_prefix` max length has been extended from 37 to 54 characters

Description of the change and how users should adjust their configuration (if needed).
Affected resources: `google_compute_instance_template`, `google_compute_region_instance_template`, `google_compute_ssl_certificate`,
and `google_compute_region_ssl_certificate`

Previously, the max length of `name_prefix` was 37 characters since the autogenerated UUID suffix was 26 characters which combined to
the total max length for names of 63 characters.
In 6.0, providing a `name_prefix` larger than 37 characters will prompt the provider to use a shortened suffix of only 9 characters, leading to a new max of 54 characters for `name_prefix`. This shortened suffix is inevitably more prone to collisions, so use the longer max `name_prefix` length with caution.

## Datasources

Expand Down
9 changes: 8 additions & 1 deletion website/docs/r/compute_instance_template.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,14 @@ The following arguments are supported:
this blank, Terraform will auto-generate a unique name.

* `name_prefix` - (Optional) Creates a unique name beginning with the specified
prefix. Conflicts with `name`.
prefix. Conflicts with `name`. Max length is 54 characters.
Prefixes with lengths longer than 37 characters will use a shortened
UUID that will be more prone to collisions.

Resulting name for a `name_prefix` <= 37 characters:
`name_prefix` + YYYYmmddHHSSssss + 8 digit incremental counter
Resulting name for a `name_prefix` 38 - 54 characters:
`name_prefix` + YYmmdd + 3 digit incremental counter

* `can_ip_forward` - (Optional) Whether to allow sending and receiving of
packets with non-matching source or destination IPs. This defaults to false.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,14 @@ The following arguments are supported:
this blank, Terraform will auto-generate a unique name.

* `name_prefix` - (Optional) Creates a unique name beginning with the specified
prefix. Conflicts with `name`.
prefix. Conflicts with `name`. Max length is 54 characters.
Prefixes with lengths longer than 37 characters will use a shortened
UUID that will be more prone to collisions.

Resulting name for a `name_prefix` <= 37 characters:
`name_prefix` + YYYYmmddHHSSssss + 8 digit incremental counter
Resulting name for a `name_prefix` 38 - 54 characters:
`name_prefix` + YYmmdd + 3 digit incremental counter

* `can_ip_forward` - (Optional) Whether to allow sending and receiving of
packets with non-matching source or destination IPs. This defaults to false.
Expand Down
8 changes: 7 additions & 1 deletion website/docs/r/compute_region_ssl_certificate.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,13 @@ The following arguments are supported:
If it is not provided, the provider project is used.

* `name_prefix` - (Optional) Creates a unique name beginning with the
specified prefix. Conflicts with `name`.
specified prefix. Conflicts with `name`. Max length is 54 characters.
Prefixes with lengths longer than 37 characters will use a shortened
UUID that will be more prone to collisions.
Resulting name for a `name_prefix` <= 37 characters:
`name_prefix` + YYYYmmddHHSSssss + 8 digit incremental counter
Resulting name for a `name_prefix` 38 - 54 characters:
`name_prefix` + YYmmdd + 3 digit incremental counter

## Attributes Reference

Expand Down
8 changes: 7 additions & 1 deletion website/docs/r/compute_ssl_certificate.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,13 @@ The following arguments are supported:
If it is not provided, the provider project is used.

* `name_prefix` - (Optional) Creates a unique name beginning with the
specified prefix. Conflicts with `name`.
specified prefix. Conflicts with `name`. Max length is 54 characters.
Prefixes with lengths longer than 37 characters will use a shortened
UUID that will be more prone to collisions.
Resulting name for a `name_prefix` <= 37 characters:
`name_prefix` + YYYYmmddHHSSssss + 8 digit incremental counter
Resulting name for a `name_prefix` 38 - 54 characters:
`name_prefix` + YYmmdd + 3 digit incremental counter

## Attributes Reference

Expand Down

0 comments on commit d8b4d70

Please sign in to comment.