From 71b1edad311cc2de5e61cd7a891a1ac2046e4661 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Wed, 12 Oct 2022 09:59:39 +0000 Subject: [PATCH] Promote `public_access_prevention` field on `google_storage_bucket` resource to GA, add to documentation (#6683) * Promote `public_access_prevention` field of `google_storage_bucket` resource to GA, add to documentation * Update description of new field, add new example Signed-off-by: Modular Magician --- .changelog/6683.txt | 3 ++ google/resource_storage_bucket.go | 18 ++++++++++- google/resource_storage_bucket_test.go | 33 +++++++++++++++++++++ website/docs/r/storage_bucket.html.markdown | 15 ++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .changelog/6683.txt diff --git a/.changelog/6683.txt b/.changelog/6683.txt new file mode 100644 index 00000000000..2e483db9562 --- /dev/null +++ b/.changelog/6683.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +storage: Promoted `public_access_prevention` field on `google_storage_bucket` resource to GA +``` diff --git a/google/resource_storage_bucket.go b/google/resource_storage_bucket.go index 6dd183abbd7..213a3bd3ea6 100644 --- a/google/resource_storage_bucket.go +++ b/google/resource_storage_bucket.go @@ -386,6 +386,12 @@ func resourceStorageBucket() *schema.Resource { }, Description: `The bucket's custom location configuration, which specifies the individual regions that comprise a dual-region bucket. If the bucket is designated a single or multi-region, the parameters are empty.`, }, + "public_access_prevention": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Prevents public access to a bucket.`, + }, }, UseJSONNumber: true, } @@ -650,7 +656,7 @@ func resourceStorageBucketUpdate(d *schema.ResourceData, meta interface{}) error } } - if d.HasChange("uniform_bucket_level_access") { + if d.HasChange("uniform_bucket_level_access") || d.HasChange("public_access_prevention") { sb.IamConfiguration = expandIamConfiguration(d) } @@ -1142,6 +1148,10 @@ func expandIamConfiguration(d *schema.ResourceData) *storage.BucketIamConfigurat }, } + if v, ok := d.GetOk("public_access_prevention"); ok { + cfg.PublicAccessPrevention = v.(string) + } + return cfg } @@ -1506,6 +1516,12 @@ func setStorageBucket(d *schema.ResourceData, config *Config, res *storage.Bucke } } + if res.IamConfiguration != nil && res.IamConfiguration.PublicAccessPrevention != "" { + if err := d.Set("public_access_prevention", res.IamConfiguration.PublicAccessPrevention); err != nil { + return fmt.Errorf("Error setting public_access_prevention: %s", err) + } + } + if res.Billing == nil { if err := d.Set("requester_pays", nil); err != nil { return fmt.Errorf("Error setting requester_pays: %s", err) diff --git a/google/resource_storage_bucket_test.go b/google/resource_storage_bucket_test.go index ba63fb90c98..f0ec417124b 100644 --- a/google/resource_storage_bucket_test.go +++ b/google/resource_storage_bucket_test.go @@ -866,6 +866,28 @@ func TestAccStorageBucket_encryption(t *testing.T) { }) } +func TestAccStorageBucket_publicAccessPrevention(t *testing.T) { + t.Parallel() + + bucketName := fmt.Sprintf("tf-test-acl-bucket-%d", randInt(t)) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccStorageBucket_publicAccessPrevention(bucketName, "enforced"), + }, + { + ResourceName: "google_storage_bucket.bucket", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"force_destroy"}, + }, + }, + }) +} + func TestAccStorageBucket_uniformBucketAccessOnly(t *testing.T) { t.Parallel() @@ -1785,6 +1807,17 @@ resource "google_storage_bucket" "bucket" { `, bucketName, enabled) } +func testAccStorageBucket_publicAccessPrevention(bucketName string, prevention string) string { + return fmt.Sprintf(` +resource "google_storage_bucket" "bucket" { + name = "%s" + location = "US" + public_access_prevention = "%s" + force_destroy = true +} +`, bucketName, prevention) +} + func testAccStorageBucket_encryption(context map[string]interface{}) string { return Nprintf(` resource "google_project" "acceptance" { diff --git a/website/docs/r/storage_bucket.html.markdown b/website/docs/r/storage_bucket.html.markdown index 46d34633d69..a994acbc29c 100644 --- a/website/docs/r/storage_bucket.html.markdown +++ b/website/docs/r/storage_bucket.html.markdown @@ -60,6 +60,19 @@ resource "google_storage_bucket" "auto-expire" { } } ``` + +## Example Usage - Enabling public access prevention + +```hcl +resource "google_storage_bucket" "auto-expire" { + name = "no-public-access-bucket" + location = "US" + force_destroy = true + + public_access_prevention = "enforced" +} +``` + ## Argument Reference The following arguments are supported: @@ -101,6 +114,8 @@ The following arguments are supported: * `uniform_bucket_level_access` - (Optional, Default: false) Enables [Uniform bucket-level access](https://cloud.google.com/storage/docs/uniform-bucket-level-access) access to a bucket. +* `public_access_prevention` - (Optional) Prevents public access to a bucket. Acceptable values are "inherited" or "enforced". If "inherited", the bucket uses [public access prevention](https://cloud.google.com/storage/docs/public-access-prevention). only if the bucket is subject to the public access prevention organization policy constraint. Defaults to "inherited". + * `custom_placement_config` - (Optional) The bucket's custom location configuration, which specifies the individual regions that comprise a dual-region bucket. If the bucket is designated a single or multi-region, the parameters are empty. Structure is [documented below](#nested_custom_placement_config). The `lifecycle_rule` block supports: