terraform-google-modules / terraform-google-cloud-storage

Creates one or more Cloud Storage buckets and assigns basic permissions on them to arbitrary users
https://registry.terraform.io/modules/terraform-google-modules/cloud-storage/google
Apache License 2.0
169 stars 558 forks source link

fix: use null as default for lookup #332

Closed cyuanli closed 2 months ago

cyuanli commented 2 months ago

Currently, any retention_policy throws this error:

╷
│ Error: Invalid function argument
│
│   on .terraform\modules\my_buckets.gcs_bucket\main.tf line 114, in resource "google_storage_bucket" "buckets":
│  114:     for_each = lookup(var.retention_policy, each.value, {}) != {} ? [var.retention_policy[each.value]] : []
│     ├────────────────
│     │ while calling lookup(inputMap, key, default...)
│
│ Invalid value for "default" parameter: the default value must have the same type as the map elements.
╵

This fixes the default for the lookup, similar to https://github.com/terraform-google-modules/terraform-google-cloud-storage/pull/318. Given that this seems to be a recurring bug, it might be worth looking into

https://github.com/terraform-google-modules/terraform-google-cloud-storage/blob/07e3a4e2b34dc4c7a2a99ae5e6893a3670251870/main.tf#L122

https://github.com/terraform-google-modules/terraform-google-cloud-storage/blob/07e3a4e2b34dc4c7a2a99ae5e6893a3670251870/main.tf#L152

google-cla[bot] commented 2 months ago

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

cyuanli commented 2 months ago

When can I expect a review?

apeabody commented 2 months ago

/gcbrun

apeabody commented 2 months ago

/gcbrun

cyuanli commented 2 months ago

Is there anything else I can provide in order to have this PR reviewed?

cyuanli commented 2 months ago

So I realized it might be user error, here's a minimal example that reproduces the error that I get:

resource "random_string" "prefix" {
  length  = 4
  upper   = false
  special = false
}

module "cloud_storage" {
  source  = "terraform-google-modules/cloud-storage/google"
  version = "~> 6.0"

  project_id = var.project_id

  prefix           = "buckets-${random_string.prefix.result}"
  names            = ["one", "two"]

  retention_policy = true ? {
    "one" = {
      is_locked        = false
      retention_period = 3600
    }
  } : {}
}

and without the ternary operator

resource "random_string" "prefix" {
  length  = 4
  upper   = false
  special = false
}

module "cloud_storage" {
  source  = "terraform-google-modules/cloud-storage/google"
  version = "~> 6.0"

  project_id = var.project_id

  prefix           = "buckets-${random_string.prefix.result}"
  names            = ["one", "two"]

  retention_policy = {
    "one" = {
      is_locked        = false
      retention_period = 3600
    }
  }
}

it works fine.

I'm aware of conversions made by conditional expressions, but I don't know Terraform well enough to understand why it would complain here. Is that intended behavior?

In any case, I leave it up to the maintainers to judge if this PR is valuable still 😁

Edit: This also works

resource "random_string" "prefix" {
  length  = 4
  upper   = false
  special = false
}

module "cloud_storage" {
  source  = "terraform-google-modules/cloud-storage/google"
  version = "~> 6.0"

  project_id = var.project_id

  prefix           = "buckets-${random_string.prefix.result}"
  names            = ["one", "two"]

  retention_policy = {}
}

In any case, null would work for all the cases.

apeabody commented 2 months ago

retention_policy = true ? {

Thanks @cyuanli - What is the intention of true in the first example? Should that be var.something or local.something?

If we have a syntactically correct reproducible test case this resolves, I'm absolutely happy to merge it.

cyuanli commented 2 months ago

I added retention_policy in the example and adapted the integration test, let me know if I should adjust anything.

retention_policy = true ? {

Thanks @cyuanli - What is the intention of true in the first example? Should that be var.something or local.something?

I tried to keep it minimal there, in reality it's more something like

retention_policy = var.my_retention_policy != null ? { (var.my_bucket_name) = var.my_retention_policy } : {}
cyuanli commented 2 months ago

For reference, created an issue for terraform here: https://github.com/hashicorp/terraform/issues/35662

Very curious to find out if that is intended behavior 😄

cyuanli commented 2 months ago

https://github.com/hashicorp/terraform/issues/35662#issuecomment-2325254269

As explained here, the empty map shouldn't be used in these cases. I replaced them with nulls and added one integration test, let me know if I should adjust anything.

apeabody commented 2 months ago

/gcbrun

apeabody commented 2 months ago

Hi @cyuanli!

Great to have test coverage, but can we set retention_period for an extremely short period, as currently it blocks the CI test lifecycle :)

            Error:          Received unexpected error:
                            FatalError{Underlying: error while running command: exit status 1; 
                            Error: Error deleting contents of object prod/: googleapi: Error 403: Object 'multiple-buckets-gpev-two-b249/prod/' is subject to bucket's retention policy or object retention and cannot be deleted or overwritten until 2024-09-03T09:46:50.928463-07:00, retentionPolicyNotMet

                            Error: Error deleting contents of object dev/: googleapi: Error 403: Object 'multiple-buckets-gpev-two-b249/dev/' is subject to bucket's retention policy or object retention and cannot be deleted or overwritten until 2024-09-03T09:46:50.706047-07:00, retentionPolicyNotMet
                            }
            Test:           TestMultipleBuckets
cyuanli commented 2 months ago

Ah of course, set it to 1 ✌️

apeabody commented 2 months ago

/gcbrun