diff --git a/google_permissions/README.md b/google_permissions/README.md index bc6745c2..4dbf0a14 100644 --- a/google_permissions/README.md +++ b/google_permissions/README.md @@ -66,13 +66,13 @@ module "permissions" { | [app\_code](#input\_app\_code) | The application code for the permissions. See https://github.com/mozilla-services/inventory/blob/master/application_component_registry.csv. | `string` | `""` | no | | [developer\_ids](#input\_developer\_ids) | List of developer IDs to add to the project. | `list(string)` | `[]` | no | | [entitlement\_data](#input\_entitlement\_data) | The entitlement data for the project. |
object({
enabled = bool
additional_roles = list(string)
additional_entitlements = list(object({
name = string
roles = list(string)
principals = list(string)
approval_workflow = optional(object({
principals = list(string)
}))
}))
})
|
{
"additional_entitlements": [],
"additional_roles": [],
"enabled": false
}
| no | -| [entitlement\_enabled](#input\_entitlement\_enabled) | Whether or not to enable entitlements. | `bool` | `false` | no | | [entitlement\_slack\_topic](#input\_entitlement\_slack\_topic) | The name of the pubsub topic to use for slack notifications. | `string` | `""` | no | | [feed\_id](#input\_feed\_id) | The ID of the feed to be created | `string` | `"grant_feed"` | no | | [folder\_roles](#input\_folder\_roles) | List of roles to apply at the folder level. Also used as the roles in the entitlement. | `list(string)` | `[]` | no | | [google\_folder\_id](#input\_google\_folder\_id) | The ID of the folder to create the project in. | `string` | n/a | yes | | [google\_nonprod\_project\_id](#input\_google\_nonprod\_project\_id) | The ID of the nonprod project. | `string` | `""` | no | | [google\_prod\_project\_id](#input\_google\_prod\_project\_id) | The ID of the prod project. | `string` | `""` | no | +| [legacy\_admin\_entitlement\_01](#input\_legacy\_admin\_entitlement\_01) | Whether this module keeps the tenant's legacy default admin entitlement
(admin-entitlement-01).
Set to true only in stacks that already have the legacy admin-entitlement-01, to keep it.
New tenants should leave it false. | `bool` | `false` | no | | [nonprod\_roles](#input\_nonprod\_roles) | List of roles to apply to the nonprod project. | `list(string)` | `[]` | no | | [prod\_roles](#input\_prod\_roles) | List of roles to apply to the prod project. | `list(string)` | `[]` | no | | [viewer\_ids](#input\_viewer\_ids) | List of viewer IDs to add to the project. | `list(string)` | `[]` | no | diff --git a/google_permissions/examples/entitlement_basic/locals.tf b/google_permissions/examples/entitlement_basic/locals.tf index ce7592b6..fa952240 100644 --- a/google_permissions/examples/entitlement_basic/locals.tf +++ b/google_permissions/examples/entitlement_basic/locals.tf @@ -6,6 +6,5 @@ locals { tenant_entitlements = data.terraform_remote_state.platform_shared.outputs.tenant_entitlements[local.application] google_prod_project_id = local.tenant_entitlements.prod google_nonprod_project_id = local.tenant_entitlements.nonprod - entitlement_enabled = local.tenant_entitlements.entitlements.enabled entitlement_data = local.tenant_entitlements.entitlements } diff --git a/google_permissions/examples/entitlement_basic/permissions.tf b/google_permissions/examples/entitlement_basic/permissions.tf index e1b4ecef..ff989faf 100644 --- a/google_permissions/examples/entitlement_basic/permissions.tf +++ b/google_permissions/examples/entitlement_basic/permissions.tf @@ -5,8 +5,7 @@ module "permissions" { // the appcode (aka application or tenant name) is used to create the workgroups and entitlements if used app_code = local.application - entitlement_enabled = local.entitlement_enabled - entitlement_data = local.entitlement_data + entitlement_data = local.entitlement_data google_folder_id = local.project.folder.id diff --git a/google_permissions/main.tf b/google_permissions/main.tf index 1b78bc8e..32fa723f 100644 --- a/google_permissions/main.tf +++ b/google_permissions/main.tf @@ -67,7 +67,6 @@ resource "google_project_iam_member" "developers_secretmanager_secretVersionAdde // if admin_only is true OR var.use_entitlements is true, we don't create these permissions at all resource "google_folder_iam_binding" "owner" { - #count = var.admin_only || var.entitlement_enabled == true ? 0 : 1 folder = var.google_folder_id role = "roles/owner" members = module.admins_workgroup.members diff --git a/google_permissions/pam_entitlement.tf b/google_permissions/pam_entitlement.tf index c9076211..0ed09580 100644 --- a/google_permissions/pam_entitlement.tf +++ b/google_permissions/pam_entitlement.tf @@ -83,11 +83,18 @@ locals { } } - +# legacy_admin_entitlement_01 only keeps an existing admin-entitlement-01; it must never create one. +# This read fails the plan with "... not found" for a tenant that doesn't already have it. +data "google_privileged_access_manager_entitlement" "legacy_admin_entitlement_01_must_exist" { + for_each = var.legacy_admin_entitlement_01 ? toset(local.environments) : toset([]) + parent = "projects/${each.value == "prod" ? var.google_prod_project_id : var.google_nonprod_project_id}" + location = "global" + entitlement_id = local.default_admin_entitlement_name +} # now we handle the additional entitlements - these need to be created for BOTH environments resource "google_privileged_access_manager_entitlement" "default_prod_entitlement" { - count = var.entitlement_enabled && (var.google_prod_project_id != "") ? 1 : 0 + count = var.legacy_admin_entitlement_01 && (var.google_prod_project_id != "") ? 1 : 0 entitlement_id = local.default_admin_entitlement_name location = "global" max_request_duration = "${local.max_allowed_request_duration}s" @@ -139,7 +146,7 @@ resource "google_privileged_access_manager_entitlement" "default_prod_entitlemen # now we handle the additional entitlements - these need to be created for BOTH environments resource "google_privileged_access_manager_entitlement" "default_nonprod_entitlement" { - count = var.entitlement_enabled && (var.google_nonprod_project_id != "") ? 1 : 0 + count = var.legacy_admin_entitlement_01 && (var.google_nonprod_project_id != "") ? 1 : 0 entitlement_id = local.default_admin_entitlement_name location = "global" max_request_duration = "${local.max_allowed_request_duration}s" @@ -188,10 +195,12 @@ resource "google_privileged_access_manager_entitlement" "default_nonprod_entitle # } } +# Not gated on entitlement_enabled, so tenants can add these without the legacy default +# entitlement. resource "google_privileged_access_manager_entitlement" "additional_entitlements" { - for_each = var.entitlement_enabled ? { + for_each = { for entitlement in local.additional_entitlements : entitlement.key => entitlement - } : {} + } entitlement_id = each.value.entitlement.name location = "global" max_request_duration = "${local.max_allowed_request_duration}s" @@ -241,7 +250,7 @@ resource "google_privileged_access_manager_entitlement" "additional_entitlements // ref: https://stackoverflow.com/questions/63785247/gcp-managed-service-account-is-not-created-for-cloud-asset-api // resource "google_project_service_identity" "cloud_asset_sa" { - for_each = var.entitlement_enabled && var.entitlement_slack_topic != "" ? toset(local.environments) : [] + for_each = var.entitlement_slack_topic != "" ? toset(local.environments) : [] provider = google-beta project = each.value == "nonprod" ? var.google_nonprod_project_id : var.google_prod_project_id service = "cloudasset.googleapis.com" @@ -249,7 +258,7 @@ resource "google_project_service_identity" "cloud_asset_sa" { // Create a feed that sends notifications about network resource updates. resource "google_cloud_asset_project_feed" "project_feed" { - for_each = var.entitlement_enabled && var.entitlement_slack_topic != "" ? toset(local.environments) : [] + for_each = var.entitlement_slack_topic != "" ? toset(local.environments) : [] project = each.value == "nonprod" ? var.google_nonprod_project_id : var.google_prod_project_id feed_id = var.feed_id content_type = "RESOURCE" @@ -267,14 +276,14 @@ resource "google_cloud_asset_project_feed" "project_feed" { # custom role for JIT access - created at the org level resource "google_project_iam_member" "developers_jitaccess_nonprod" { - for_each = var.entitlement_enabled && var.google_nonprod_project_id != "" ? toset(module.developers_workgroup.members) : toset([]) + for_each = var.legacy_admin_entitlement_01 && var.google_nonprod_project_id != "" ? toset(module.developers_workgroup.members) : toset([]) project = var.google_nonprod_project_id role = local.jit_access_user_role member = each.value } resource "google_project_iam_member" "developers_jitaccess_prod" { - for_each = var.entitlement_enabled && var.google_prod_project_id != "" ? toset(module.developers_workgroup.members) : toset([]) + for_each = var.legacy_admin_entitlement_01 && var.google_prod_project_id != "" ? toset(module.developers_workgroup.members) : toset([]) project = var.google_prod_project_id role = local.jit_access_user_role member = each.value diff --git a/google_permissions/variables.tf b/google_permissions/variables.tf index 27cb0c54..41ba5da3 100644 --- a/google_permissions/variables.tf +++ b/google_permissions/variables.tf @@ -4,8 +4,13 @@ variable "app_code" { default = "" } -variable "entitlement_enabled" { - description = "Whether or not to enable entitlements." +variable "legacy_admin_entitlement_01" { + description = <<-EOT + Whether this module keeps the tenant's legacy default admin entitlement + (admin-entitlement-01). + Set to true only in stacks that already have the legacy admin-entitlement-01, to keep it. + New tenants should leave it false. + EOT type = bool default = false } diff --git a/google_permissions/versions.tf b/google_permissions/versions.tf index 37ea1d76..42c60def 100644 --- a/google_permissions/versions.tf +++ b/google_permissions/versions.tf @@ -2,7 +2,7 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 6.0, < 8.0" + version = ">= 6.5, < 8.0" } google-beta = { source = "hashicorp/google-beta"