terraform-provider-cloudflare: Multiple Gsuite groups in cloudflare_access_policy cause access.api.error.invalid_request

Confirmation

  • My issue isn’t already found on the issue tracker.
  • I have replicated my issue using the latest version of the provider and it is still present.

Terraform and Cloudflare provider version

Terraform v1.2.4
on linux_amd64
+ provider registry.terraform.io/cloudflare/cloudflare v3.18.0

Affected resource(s)

  • cloudflare_access_policy

Terraform configuration files

locals {
  google_groups = [
    "group-1@example.com",
    "group-2@example.com",
    "group-3@example.com",
    "group-4@example.com",
    "group-5@example.com",
    "group-6@example.com",
    "group-7@example.com",
    "group-8@example.com",
    "group-9@example.com",
    "group-10@example.com",
    "group-11@example.com",
    "group-12@example.com",
    "group-13@example.com",
    "group-14@example.com"
  ]
}

resource "cloudflare_access_policy" "prod" {
  account_id     = var.cloudflare_account_id
  application_id = cloudflare_access_application.prod.id
  name           = "Prod"
  decision       = "allow"
  precedence     = "1"

  include {
    gsuite {
      email                = local.google_groups
      identity_provider_id = var.google_workspace_idp_id
    }
  }

  require {
    group = [cloudflare_access_group.sentinelone_enabled.id, cloudflare_access_group.jumpcloud_enabled.id]
  }
}

Debug output

2022-07-05T03:55:05.583Z [DEBUG] provider.terraform-provider-cloudflare_v3.18.0: Cloudflare API Request Details:
---[ REQUEST ]---------------------------------------
PUT /client/v4/accounts/<REDACTED>/access/apps/<REDACTED>/policies/<REDACTED> HTTP/1.1
Host: api.cloudflare.com
User-Agent: terraform/1.2.4 terraform-plugin-sdk/2.10.1 terraform-provider-cloudflare/dev
Content-Length: 1947
Authorization: Bearer *****
Content-Type: application/json
Accept-Encoding: gzip

{
 "id": "<REDACTED>",
 "precedence": 1,
 "decision": "allow",
 "created_at": null,
 "updated_at": null,
 "name": "Prod",
 "purpose_justification_required": false,
 "purpose_justification_prompt": "",
 "approval_required": false,
 "approval_groups": null,
 "include": [
  {
   "gsuite": {
    "email": "group-1@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-2@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-3@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-4@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-5@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-6@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-7@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-8@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-9@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-10@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-12@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-13t@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-14@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  },
  {
   "gsuite": {
    "email": "group-15@example.com",
    "identity_provider_id": "<REDACTED>"
   }
  }
 ],
 "exclude": null,
 "require": null
}

2022-07-05T03:55:07.401Z [DEBUG] provider.terraform-provider-cloudflare_v3.18.0: Cloudflare API Response Details:
---[ RESPONSE ]--------------------------------------
HTTP/2.0 400 Bad Request
Cf-Cache-Status: DYNAMIC
Cf-Ray: <REDACTED>
Content-Security-Policy: frame-ancestors 'none'; default-src https: 'unsafe-inline'
Content-Type: application/json; charset=UTF-8
Date: Tue, 05 Jul 2022 03:55:07 GMT
Expect-Ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
Set-Cookie: <REDACTED>; SameSite=Lax; path=/; expires=Tue, 05-Jul-22 06:25:08 GMT; HttpOnly
Set-Cookie: <REDACTED>; path=/; domain=.api.cloudflare.com; HttpOnly; Secure; SameSite=None
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Envoy-Upstream-Service-Time: 469
X-Frame-Options: DENY
X-Xss-Protection: 1; mode=block

{
  "result": null,
  "success": false,
  "errors": [
    {
      "code": 12130,
      "message": "access.api.error.invalid_request"
    }
  ],
  "messages": []
}

Panic output

No response

Expected output

Updating the cloudflare_access_policy with a list of allowed Google Groups instead of deferring to cloudflare_access_groups should succeed.

Actual output

Updating the cloudflare_access_policy with a list of allowed Google Groups instead of deferring to cloudflare_access_groups fails with

Error: error updating Access Policy for ID "ae8d51bf-329f-4186-b762-741be43c7a57": access.api.error.invalid_request (12130)

Steps to reproduce

  1. Define resources with
locals {
  google_groups = [
    "group-1@example.com",
    "group-2@example.com",
    "group-3@example.com",
    "group-4@example.com",
    "group-5@example.com",
    "group-6@example.com",
    "group-7@example.com",
    "group-8@example.com",
    "group-9@example.com",
    "group-10@example.com",
    "group-11@example.com",
    "group-12@example.com",
    "group-13@example.com",
    "group-14@example.com"
  ]
}

resource "cloudflare_access_policy" "prod" {
  account_id     = var.cloudflare_account_id
  application_id = cloudflare_access_application.prod.id
  name           = "Prod"
  decision       = "allow"
  precedence     = "1"

  include {
    group = [for key, group in cloudflare_access_group.role : group.id]
  }

  require {
    group = [cloudflare_access_group.sentinelone_enabled.id, cloudflare_access_group.jumpcloud_enabled.id]
  }
}

resource "cloudflare_access_group" "role" {
  for_each   = toset(local.google_groups)
  account_id = var.cloudflare_account_id
  name       = "Role (${each.key})"

  include {
    gsuite {
      email                = [each.key]
      identity_provider_id = var.google_workspace_idp_id
    }
  }
}
  1. Run terraform apply
  2. Change resources to
locals {
  google_groups = [
    "group-1@example.com",
    "group-2@example.com",
    "group-3@example.com",
    "group-4@example.com",
    "group-5@example.com",
    "group-6@example.com",
    "group-7@example.com",
    "group-8@example.com",
    "group-9@example.com",
    "group-10@example.com",
    "group-11@example.com",
    "group-12@example.com",
    "group-13@example.com",
    "group-14@example.com"
  ]
}

resource "cloudflare_access_policy" "prod" {
  account_id     = var.cloudflare_account_id
  application_id = cloudflare_access_application.prod.id
  name           = "Prod"
  decision       = "allow"
  precedence     = "1"

  include {
    gsuite {
      email                = local.google_groups
      identity_provider_id = var.google_workspace_idp_id
    }
  }

  require {
    group = [cloudflare_access_group.sentinelone_enabled.id, cloudflare_access_group.jumpcloud_enabled.id]
  }
}
  1. Run terraform apply and see it failing

Additional factoids

No response

References

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 22 (10 by maintainers)

Most upvoted comments

Still an issue.

Bug very much still exists. Just closing the issue doesn’t mean the bug magically disappears 🙄

Thank you for reporting this issue! For maintainers to dig into issues it is required that all issues include the entirety of TF_LOG=DEBUG output to be provided. The only parts that should be redacted are your user credentials in the X-Auth-Key, X-Auth-Email and Authorization HTTP headers. Details such as zone or account identifiers are not considered sensitive but can be redacted if you are very cautious. This log file provides additional context from Terraform, the provider and the Cloudflare API that helps in debugging issues. Without it, maintainers are very limited in what they can do and may hamper diagnosis efforts.

This issue has been marked with triage/needs-information and is unlikely to receive maintainer attention until the log file is provided making this a complete bug report.