Search code examples
google-cloud-platformterraform-provider-gcp

Terraform Conditional IAM GCP


Trying to add a user to a role using Terraform with a time based condition.

My code looks like below

    for_each = toset(local.grantees)
    project = <project_id>
    role =  google_project_iam_custom_role.my-custom-role.id
    members = [
        "user:${each.value}"
    ]
     condition {
      title       = "expires_after_30days"
      description = "Expires in 30 dates from now"
      #expression  = "request.time < timestamp('2023-04-12T00:00:00.00Z')"
      expression  = "request.time < timestamp(${local.expiry})"
    }

}

I have defined a local variable "expiry" as below expiry = timeadd(timestamp(), "720h")

I have tried everything but unable to resolve this blocker.

Here is the error I get

Error: Request `Set IAM Binding for role "projects/xxxx/roles/xxx" on "project \"xxxxl\""` returned error: Batch request and retried single request "Set IAM Binding for role \"projects/xxx/roles/xxxx\" on \"project \\\"xxx\\\"\"" both failed. Final error: Error applying IAM policy for project "xxx": Error setting IAM policy for project "xxx": googleapi: Error 400: Condition expression compilation failed. Debug message: ERROR : ERROR: <expression>:1:36: mismatched input 'T16' expecting {'==', '!=', 'in', '<', '<=', '>=', '>', '&&', '||', '[', ')', '.', ',', '-', '?', '+', '*', '/', '%%'}
│  | request.time < timestamp(2023-09-03T16:05:22Z)
│  | ...................................^ , badRequest
│ 
│   with google_project_iam_binding.cwx_readonly_users["xxxx"],
│   on main.tf line 37, in resource "google_project_iam_binding" "cwx_readonly_users":
│   37: resource "google_project_iam_binding" "cwx_readonly_users" {

If I use this line instead, it works just fine

#expression  = "request.time < timestamp('2023-04-12T00:00:00.00Z')"

But, I am interested in using a variable time and not hard code a date for better usability


Solution

  • guillaume blaquiere is right, you are missing single quotes:

    expression  = "request.time < timestamp('${local.expiry}')"