diff --git a/fast/stages/1-resman/README.md b/fast/stages/1-resman/README.md index 339b951700..91a120761f 100644 --- a/fast/stages/1-resman/README.md +++ b/fast/stages/1-resman/README.md @@ -288,8 +288,8 @@ terraform apply | name | description | sensitive | consumers | |---|---|:---:|---| -| [cicd_repositories](outputs.tf#L76) | WIF configuration for CI/CD repositories. | | | -| [folder_ids](outputs.tf#L88) | Folder ids. | | | -| [providers](outputs.tf#L94) | Terraform provider files for this stage and dependent stages. | ✓ | | -| [tfvars](outputs.tf#L101) | Terraform variable files for the following stages. | ✓ | | +| [cicd_repositories](outputs.tf#L74) | WIF configuration for CI/CD repositories. | | | +| [folder_ids](outputs.tf#L86) | Folder ids. | | | +| [providers](outputs.tf#L92) | Terraform provider files for this stage and dependent stages. | ✓ | | +| [tfvars](outputs.tf#L99) | Terraform variable files for the following stages. | ✓ | | diff --git a/fast/stages/1-resman/moved/v36.0.1-v37.0.0.tf b/fast/stages/1-resman/moved/v36.0.1-v37.0.0.tf new file mode 100644 index 0000000000..59e1988914 --- /dev/null +++ b/fast/stages/1-resman/moved/v36.0.1-v37.0.0.tf @@ -0,0 +1,35 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +moved { + from = module.net-folder-dev[0] + to = module.net-folder-envs["dev"] +} + +moved { + from = module.net-folder-prod[0] + to = module.net-folder-envs["prod"] +} + +moved { + from = module.sec-folder-dev[0] + to = module.sec-folder-envs["dev"] +} + +moved { + from = module.sec-folder-prod[0] + to = module.sec-folder-envs["prod"] +} diff --git a/fast/stages/1-resman/outputs.tf b/fast/stages/1-resman/outputs.tf index 0c81523719..e7a8ac19de 100644 --- a/fast/stages/1-resman/outputs.tf +++ b/fast/stages/1-resman/outputs.tf @@ -17,16 +17,14 @@ locals { folder_ids = merge( # stage 2 - !var.fast_stage_2.networking.enabled ? {} : { - networking = module.net-folder[0].id - networking-dev = try(module.net-folder-dev[0].id, null) - networking-prod = try(module.net-folder-prod[0].id, null) - }, - !var.fast_stage_2.security.enabled ? {} : { - security = module.sec-folder[0].id - security-dev = try(module.sec-folder-dev[0].id, null) - security-prod = try(module.sec-folder-prod[0].id, null) - }, + !var.fast_stage_2.networking.enabled ? {} : merge( + { networking = module.net-folder[0].id }, + { for k, v in module.net-folder-envs : "networking-${k}" => v.id } + ), + !var.fast_stage_2.security.enabled ? {} : merge( + { security = module.sec-folder[0].id }, + { for k, v in module.sec-folder-envs : "security-${k}" => v.id } + ), # stage 3 { for k, v in module.stage3-folder : k => v.id }, # top-level folders diff --git a/fast/stages/1-resman/stage-2-networking.tf b/fast/stages/1-resman/stage-2-networking.tf index ed11edead2..8ca86e8a26 100644 --- a/fast/stages/1-resman/stage-2-networking.tf +++ b/fast/stages/1-resman/stage-2-networking.tf @@ -15,7 +15,7 @@ */ locals { - # normalize IAM bindings for stage 3 service accounts + # filter and normalize stage 3 roles applied to this stage's top-level folder net_s3_iam = !var.fast_stage_2.networking.enabled ? {} : { for v in local.stage3_iam_in_stage2 : "${v.role}:${v.env}" => ( v.sa == "rw" @@ -143,27 +143,14 @@ module "net-folder" { # optional per-environment folders -module "net-folder-prod" { - source = "../../../modules/folder" - count = local.net_use_env_folders ? 1 : 0 - parent = module.net-folder[0].id - name = var.environments["prod"].name - tag_bindings = { - environment = try( - local.tag_values["${var.tag_names.environment}/${var.environments["prod"].tag_name}"].id, - null - ) - } -} - -module "net-folder-dev" { - source = "../../../modules/folder" - count = local.net_use_env_folders ? 1 : 0 - parent = module.net-folder[0].id - name = var.environments["dev"].name +module "net-folder-envs" { + source = "../../../modules/folder" + for_each = local.net_use_env_folders ? var.environments : {} + parent = module.net-folder[0].id + name = each.value.name tag_bindings = { environment = try( - local.tag_values["${var.tag_names.environment}/${var.environments["dev"].tag_name}"].id, + local.tag_values["${var.tag_names.environment}/${each.value.tag_name}"].id, null ) } diff --git a/fast/stages/1-resman/stage-2-security.tf b/fast/stages/1-resman/stage-2-security.tf index 70dec2246a..88e1fa7131 100644 --- a/fast/stages/1-resman/stage-2-security.tf +++ b/fast/stages/1-resman/stage-2-security.tf @@ -15,10 +15,7 @@ */ locals { - sec_use_env_folders = ( - var.fast_stage_2.security.enabled && - var.fast_stage_2.security.folder_config.create_env_folders - ) + # filter and normalize stage 3 roles applied to this stage's top-level folder sec_s3_iam = !var.fast_stage_2.security.enabled ? {} : { for v in local.stage3_iam_in_stage2 : "${v.role}:${v.env}" => ( v.sa == "rw" @@ -27,6 +24,10 @@ locals { )... if v.s2 == "security" } + sec_use_env_folders = ( + var.fast_stage_2.security.enabled && + var.fast_stage_2.security.folder_config.create_env_folders + ) } # top-level folder @@ -116,47 +117,14 @@ module "sec-folder" { # optional per-environment folders -module "sec-folder-prod" { - source = "../../../modules/folder" - count = local.sec_use_env_folders ? 1 : 0 - parent = module.sec-folder[0].id - name = var.environments["prod"].name - iam = { - # stage 3s service accounts - for role, attrs in local.sec_s3_iam.prod : role => [ - for v in attrs : ( - v.sa == "ro" - ? module.stage3-sa-ro[v.s3].iam_email - : module.stage3-sa-rw[v.s3].iam_email - ) - ] - } - tag_bindings = { - environment = try( - local.tag_values["${var.tag_names.environment}/${var.environments["prod"].tag_name}"].id, - null - ) - } -} - -module "sec-folder-dev" { - source = "../../../modules/folder" - count = local.sec_use_env_folders ? 1 : 0 - parent = module.sec-folder[0].id - name = var.environments["dev"].name - iam = { - # stage 3s service accounts - for role, attrs in local.sec_s3_iam.dev : role => [ - for v in attrs : ( - v.sa == "ro" - ? module.stage3-sa-ro[v.s3].iam_email - : module.stage3-sa-rw[v.s3].iam_email - ) - ] - } +module "sec-folder-envs" { + source = "../../../modules/folder" + for_each = local.sec_use_env_folders ? var.environments : {} + parent = module.sec-folder[0].id + name = each.value.name tag_bindings = { environment = try( - local.tag_values["${var.tag_names.environment}/${var.environments["dev"].tag_name}"].id, + local.tag_values["${var.tag_names.environment}/${each.value.tag_name}"].id, null ) } diff --git a/fast/stages/2-security/README.md b/fast/stages/2-security/README.md index aa13a0a152..318dfd68e7 100644 --- a/fast/stages/2-security/README.md +++ b/fast/stages/2-security/README.md @@ -286,9 +286,9 @@ tls_inspection = { | name | description | modules | resources | |---|---|---|---| -| [core-dev.tf](./core-dev.tf) | None | certificate-authority-service · kms · project | google_certificate_manager_trust_config · google_network_security_tls_inspection_policy | -| [core-prod.tf](./core-prod.tf) | None | certificate-authority-service · kms · project | google_certificate_manager_trust_config · google_network_security_tls_inspection_policy | -| [main.tf](./main.tf) | Module-level locals and resources. | folder | | +| [certs.tf](./certs.tf) | Per-environment certificate resources. | certificate-authority-service | google_certificate_manager_trust_config | +| [kms.tf](./kms.tf) | Per-environment KMS. | | | +| [main.tf](./main.tf) | Module-level locals and resources. | folder · project | | | [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object · local_file | | [variables-fast.tf](./variables-fast.tf) | None | | | | [variables.tf](./variables.tf) | Module variables. | | | @@ -299,26 +299,24 @@ tls_inspection = { |---|---|:---:|:---:|:---:|:---:| | [automation](variables-fast.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap | | [billing_account](variables-fast.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap | -| [environments](variables-fast.tf#L47) | Environment names. | map(object({…})) | ✓ | | 0-globals | -| [folder_ids](variables-fast.tf#L64) | Folder name => id mappings, the 'security' folder name must exist. | object({…}) | ✓ | | 1-resman | -| [prefix](variables-fast.tf#L74) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | -| [cas_configs](variables.tf#L17) | The CAS CAs to add to each environment. | object({…}) | | {…} | | +| [environments](variables-fast.tf#L47) | Environment names. | map(object({…})) | ✓ | | 0-globals | +| [folder_ids](variables-fast.tf#L65) | Folder name => id mappings, the 'security' folder name must exist. | object({…}) | ✓ | | 1-resman | +| [prefix](variables-fast.tf#L75) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | +| [certificate_authorities](variables.tf#L17) | Certificate Authority Service CAs. If environments is null the CA is created in all environments. | map(object({…})) | | {} | | | [custom_roles](variables-fast.tf#L38) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | -| [essential_contacts](variables.tf#L178) | Email used for essential contacts, unset if null. | string | | null | | -| [kms_keys](variables.tf#L184) | KMS keys to create, keyed by name. | map(object({…})) | | {} | | -| [ngfw_tls_configs](variables.tf#L223) | The CAS and trust configurations key names to be used for NGFW Enterprise. | object({…}) | | {…} | | -| [outputs_location](variables.tf#L249) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | string | | null | | -| [stage_config](variables-fast.tf#L84) | FAST stage configuration. | object({…}) | | {} | 1-resman | -| [tag_values](variables-fast.tf#L98) | Root-level tag values. | map(string) | | {} | 1-resman | -| [trust_configs](variables.tf#L255) | The trust configs grouped by environment. | object({…}) | | {…} | | +| [essential_contacts](variables.tf#L91) | Email used for essential contacts, unset if null. | string | | null | | +| [kms_keys](variables.tf#L97) | KMS keys to create, keyed by name. | map(object({…})) | | {} | | +| [outputs_location](variables.tf#L162) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | string | | null | | +| [stage_config](variables-fast.tf#L85) | FAST stage configuration. | object({…}) | | {} | 1-resman | +| [tag_values](variables-fast.tf#L99) | Root-level tag values. | map(string) | | {} | 1-resman | +| [trust_configs](variables.tf#L168) | The Certificate Manager trust configs. If environments is null the trust config is created in all environments. | map(object({…})) | | {} | | ## Outputs | name | description | sensitive | consumers | |---|---|:---:|---| -| [cas_configs](outputs.tf#L99) | Certificate Authority Service configurations. | | | -| [kms_keys](outputs.tf#L104) | KMS key ids. | | | -| [ngfw_tls_configs](outputs.tf#L109) | The NGFW Enterprise configurations. | | | -| [tfvars](outputs.tf#L114) | Terraform variable files for the following stages. | ✓ | | -| [trust_config_ids](outputs.tf#L120) | Certificate Manager trust-config ids. | | | +| [cas_configs](outputs.tf#L57) | Certificate Authority Service configurations. | | | +| [kms_keys](outputs.tf#L62) | KMS key ids. | | | +| [tfvars](outputs.tf#L67) | Terraform variable files for the following stages. | ✓ | | +| [trust_config_ids](outputs.tf#L73) | Certificate Manager trust-config ids. | | | diff --git a/fast/stages/2-security/certs.tf b/fast/stages/2-security/certs.tf new file mode 100644 index 0000000000..7e6111679b --- /dev/null +++ b/fast/stages/2-security/certs.tf @@ -0,0 +1,90 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Per-environment certificate resources. + +locals { + cas = flatten([ + for k, v in var.certificate_authorities : [ + for e in coalesce(v.environments, keys(var.environments)) : merge(v, { + environment = e + key = "${e}-${k}" + name = k + netsec_iam = contains(var.trust_configs.keys.dev.cas, k) + }) + ] + ]) + trust_configs = flatten([ + for k, v in var.trust_configs : [ + for e in coalesce(v.environments, keys(var.environments)) : merge(v, { + environment = e + key = "${e}-${k}" + name = k + }) + ] + ]) +} + +module "cas" { + source = "../../../modules/certificate-authority-service" + for_each = { for k in local.cas : k.key => k } + project_id = module.project[each.value.environment].project_id + ca_configs = each.value.ca_configs + ca_pool_config = each.value.ca_pool_config + iam = each.value.iam + iam_bindings = each.value.iam_bindings + iam_bindings_additive = merge( + each.value.iam_bindings_additive, + !each.value.netsec_iam ? {} : { + nsec_agent = { + member = module.project[each.value.environment].service_agents["networksecurity"].iam_email + role = "roles/privateca.certificateManager" + } + }) + iam_by_principals = each.value.iam_by_principals + location = each.value.location +} + +resource "google_certificate_manager_trust_config" "default" { + for_each = { for k in local.trust_configs : k.key => k } + name = each.value.name + project = module.project[each.value.environment].project_id + description = each.value.description + location = each.value.location + dynamic "allowlisted_certificates" { + for_each = each.value.allowlisted_certificates + content { + pem_certificate = file(allowlisted_certificates.value) + } + } + dynamic "trust_stores" { + for_each = each.value.trust_stores + content { + dynamic "intermediate_cas" { + for_each = trust_stores.value.intermediate_cas + content { + pem_certificate = file(intermediate_cas.value) + } + } + dynamic "trust_anchors" { + for_each = trust_stores.value.trust_anchors + content { + pem_certificate = file(trust_anchors.value) + } + } + } + } +} diff --git a/fast/stages/2-security/core-dev.tf b/fast/stages/2-security/core-dev.tf deleted file mode 100644 index 2c089db122..0000000000 --- a/fast/stages/2-security/core-dev.tf +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -locals { - ngfw_dev_locations = toset([ - for k, v in var.cas_configs.dev : v.location - if contains(var.ngfw_tls_configs.keys.dev.cas, k) - ]) -} - -module "dev-sec-project" { - source = "../../../modules/project" - name = "dev-sec-core-0" - parent = coalesce( - var.folder_ids.security-dev, var.folder_ids.security - ) - prefix = var.prefix - billing_account = var.billing_account.id - labels = { environment = "dev" } - services = local.project_services - tag_bindings = local.has_env_folders ? {} : { - environment = local.env_tag_values["dev"] - } - # optionally delegate a fixed set of IAM roles to selected principals - iam = { - (var.custom_roles.project_iam_viewer) = try(local.iam_viewer_principals["dev"], []) - } - iam_bindings = ( - lookup(local.iam_delegated_principals, "dev", null) == null ? {} : { - sa_delegated_grants = { - role = "roles/resourcemanager.projectIamAdmin" - members = try(local.iam_delegated_principals["dev"], []) - condition = { - title = "dev_stage3_sa_delegated_grants" - description = "${var.environments["dev"].name} project delegated grants." - expression = format( - "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])", - local.iam_delegated - ) - } - } - } - ) -} - -module "dev-sec-kms" { - for_each = toset(local.kms_locations) - source = "../../../modules/kms" - project_id = module.dev-sec-project.project_id - keyring = { - location = each.key - name = "dev-${each.key}" - } - keys = local.kms_locations_keys[each.key] -} - -module "dev-cas" { - for_each = var.cas_configs.dev - source = "../../../modules/certificate-authority-service" - project_id = module.dev-sec-project.project_id - ca_configs = each.value.ca_configs - ca_pool_config = each.value.ca_pool_config - iam = each.value.iam - iam_bindings = each.value.iam_bindings - iam_bindings_additive = ( - contains(var.ngfw_tls_configs.keys.dev.cas, each.key) - ? merge( - { - nsec_agent = { - member = module.dev-sec-project.service_agents["networksecurity"].iam_email - role = "roles/privateca.certificateManager" - } - }, - each.value.iam_bindings_additive - ) - : each.value.iam_bindings_additive - ) - iam_by_principals = each.value.iam_by_principals - location = each.value.location -} - -resource "google_certificate_manager_trust_config" "dev_trust_configs" { - for_each = var.trust_configs.dev - name = each.key - project = module.dev-sec-project.project_id - description = each.value.description - location = each.value.location - - dynamic "allowlisted_certificates" { - for_each = each.value.allowlisted_certificates - content { - pem_certificate = file(allowlisted_certificates.value) - } - } - - dynamic "trust_stores" { - for_each = each.value.trust_stores - content { - dynamic "intermediate_cas" { - for_each = trust_stores.value.intermediate_cas - content { - pem_certificate = file(intermediate_cas.value) - } - } - dynamic "trust_anchors" { - for_each = trust_stores.value.trust_anchors - content { - pem_certificate = file(trust_anchors.value) - } - } - } - } -} - -resource "google_network_security_tls_inspection_policy" "ngfw_dev_tls_ips" { - for_each = ( - var.ngfw_tls_configs.tls_inspection.enabled - ? local.ngfw_dev_locations : toset([]) - ) - name = "${var.prefix}-dev-tls-ip-0" - project = module.dev-sec-project.project_id - location = each.key - ca_pool = try([ - for k, v in module.dev-cas - : v.ca_pool_id - if v.ca_pool.location == each.key && contains(var.ngfw_tls_configs.keys.dev.cas, k) - ][0], null) - exclude_public_ca_set = var.ngfw_tls_configs.tls_inspection.exclude_public_ca_set - min_tls_version = var.ngfw_tls_configs.tls_inspection.min_tls_version - trust_config = try([ - for k, v in google_certificate_manager_trust_config.dev_trust_configs - : v.id - if v.location == each.key - ][0], null) -} diff --git a/fast/stages/2-security/core-prod.tf b/fast/stages/2-security/core-prod.tf deleted file mode 100644 index b74a5376a2..0000000000 --- a/fast/stages/2-security/core-prod.tf +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -locals { - ngfw_prod_locations = toset([ - for k, v in var.cas_configs.prod : v.location - if contains(var.ngfw_tls_configs.keys.prod.cas, k) - ]) -} - -module "prod-sec-project" { - source = "../../../modules/project" - name = "prod-sec-core-0" - parent = coalesce( - var.folder_ids.security-prod, var.folder_ids.security - ) - prefix = var.prefix - billing_account = var.billing_account.id - labels = { environment = "prod" } - services = local.project_services - tag_bindings = local.has_env_folders ? {} : { - environment = local.env_tag_values["prod"] - } - # optionally delegate a fixed set of IAM roles to selected principals - iam = { - (var.custom_roles.project_iam_viewer) = try(local.iam_viewer_principals["prod"], []) - } - iam_bindings = ( - lookup(local.iam_delegated_principals, "prod", null) == null ? {} : { - sa_delegated_grants = { - role = "roles/resourcemanager.projectIamAdmin" - members = try(local.iam_delegated_principals["prod"], []) - condition = { - title = "prod_stage3_sa_delegated_grants" - description = "${var.environments["prod"].name} project delegated grants." - expression = format( - "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])", - local.iam_delegated - ) - } - } - } - ) -} - -module "prod-sec-kms" { - for_each = toset(local.kms_locations) - source = "../../../modules/kms" - project_id = module.prod-sec-project.project_id - keyring = { - location = each.key - name = "prod-${each.key}" - } - keys = local.kms_locations_keys[each.key] -} - -module "prod-cas" { - for_each = var.cas_configs.prod - source = "../../../modules/certificate-authority-service" - project_id = module.prod-sec-project.project_id - ca_configs = each.value.ca_configs - ca_pool_config = each.value.ca_pool_config - iam = each.value.iam - iam_bindings = each.value.iam_bindings - iam_bindings_additive = ( - contains(var.ngfw_tls_configs.keys.prod.cas, each.key) - ? merge( - { - nsec_agent = { - member = module.prod-sec-project.service_agents["networksecurity"].iam_email - role = "roles/privateca.certificateManager" - } - }, - each.value.iam_bindings_additive - ) - : each.value.iam_bindings_additive - ) - iam_by_principals = each.value.iam_by_principals - location = each.value.location -} - -resource "google_certificate_manager_trust_config" "prod_trust_configs" { - for_each = var.trust_configs.prod - name = each.key - project = module.prod-sec-project.project_id - description = each.value.description - location = each.value.location - - dynamic "allowlisted_certificates" { - for_each = each.value.allowlisted_certificates - content { - pem_certificate = file(allowlisted_certificates.value) - } - } - - dynamic "trust_stores" { - for_each = each.value.trust_stores - content { - dynamic "intermediate_cas" { - for_each = trust_stores.value.intermediate_cas - content { - pem_certificate = file(intermediate_cas.value) - } - } - dynamic "trust_anchors" { - for_each = trust_stores.value.trust_anchors - content { - pem_certificate = file(trust_anchors.value) - } - } - } - } -} - -resource "google_network_security_tls_inspection_policy" "ngfw_prod_tls_ips" { - for_each = ( - var.ngfw_tls_configs.tls_inspection.enabled - ? local.ngfw_prod_locations : toset([]) - ) - name = "${var.prefix}-prod-tls-ip-0" - project = module.prod-sec-project.project_id - location = each.key - ca_pool = try([ - for k, v in module.prod-cas - : v.ca_pool_id - if v.ca_pool.location == each.key && contains(var.ngfw_tls_configs.keys.prod.cas, k) - ][0], null) - exclude_public_ca_set = var.ngfw_tls_configs.tls_inspection.exclude_public_ca_set - min_tls_version = var.ngfw_tls_configs.tls_inspection.min_tls_version - trust_config = try([ - for k, v in google_certificate_manager_trust_config.prod_trust_configs - : v.id - if v.location == each.key - ][0], null) -} - diff --git a/fast/stages/2-security/kms.tf b/fast/stages/2-security/kms.tf new file mode 100644 index 0000000000..1a911128e4 --- /dev/null +++ b/fast/stages/2-security/kms.tf @@ -0,0 +1,52 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Per-environment KMS. + +locals { + _kms_locations = distinct(flatten([ + for k, v in var.kms_keys : v.locations + ])) + kms_keyrings = flatten([ + for k, v in var.environments : [ + for l in local._kms_locations : { + environment = k + key = "${v.short_name}-${l}" + location = l + name = "${v.short_name}-${l}" + } + ] + ]) + # list of locations with keys + # map { location -> { key_name -> key_details } } + kms_keys = { + for loc in local._kms_locations : + loc => { + for k, v in var.kms_keys : k => v if contains(v.locations, loc) + } + } +} + +module "kms" { + for_each = { for k in local.kms_keyrings : k.key => k } + source = "../../../modules/kms" + project_id = module.project[each.value.environment].project_id + keyring = { + location = each.value.location + name = each.value.name + } + keys = local.kms_keys[each.value.location] +} diff --git a/fast/stages/2-security/main.tf b/fast/stages/2-security/main.tf index 5aa17e87ef..50ff5625d7 100644 --- a/fast/stages/2-security/main.tf +++ b/fast/stages/2-security/main.tf @@ -15,10 +15,6 @@ */ locals { - env_tag_values = { - for k, v in var.environments : - k => var.tag_values["environment/${v.tag_name}"] - } has_env_folders = var.folder_ids.security-dev != null iam_delegated = join(",", formatlist("'%s'", [ "roles/cloudkms.cryptoKeyEncrypterDecrypter" @@ -29,19 +25,6 @@ locals { iam_viewer_principals = try( var.stage_config["security"].iam_viewer_principals, {} ) - # list of locations with keys - kms_locations = distinct(flatten([ - for k, v in var.kms_keys : v.locations - ])) - # map { location -> { key_name -> key_details } } - kms_locations_keys = { - for loc in local.kms_locations : - loc => { - for k, v in var.kms_keys : - k => v - if contains(v.locations, loc) - } - } project_services = [ "certificatemanager.googleapis.com", "cloudkms.googleapis.com", @@ -63,3 +46,41 @@ module "folder" { : { (var.essential_contacts) = ["ALL"] } ) } + +module "project" { + source = "../../../modules/project" + for_each = var.environments + name = "${each.value.short_name}-sec-core-0" + parent = coalesce( + var.folder_ids["security-${each.key}"], var.folder_ids.security + ) + prefix = var.prefix + billing_account = var.billing_account.id + labels = { environment = each.key } + services = local.project_services + tag_bindings = local.has_env_folders ? {} : { + environment = var.tag_values["environment/${each.value.tag_name}"] + } + # optionally delegate a fixed set of IAM roles to selected principals + iam = { + (var.custom_roles.project_iam_viewer) = try( + local.iam_viewer_principals[each.key], [] + ) + } + iam_bindings = ( + lookup(local.iam_delegated_principals, each.key, null) == null ? {} : { + sa_delegated_grants = { + role = "roles/resourcemanager.projectIamAdmin" + members = try(local.iam_delegated_principals[each.key], []) + condition = { + title = "${each.key}_stage3_sa_delegated_grants" + description = "${var.environments[each.key].name} project delegated grants." + expression = format( + "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])", + local.iam_delegated + ) + } + } + } + ) +} diff --git a/fast/stages/2-security/moved/v36.0.1-v37.0.0.tf b/fast/stages/2-security/moved/v36.0.1-v37.0.0.tf new file mode 100644 index 0000000000..d73ee3c18e --- /dev/null +++ b/fast/stages/2-security/moved/v36.0.1-v37.0.0.tf @@ -0,0 +1,58 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +moved { + from = module.dev-sec-kms["europe"] + to = module.kms["dev-europe"] +} +moved { + from = module.dev-sec-kms["europe-west1"] + to = module.kms["dev-europe-west1"] +} +moved { + from = module.dev-sec-kms["europe-west3"] + to = module.kms["dev-europe-west3"] +} +moved { + from = module.dev-sec-kms["global"] + to = module.kms["dev-global"] +} +moved { + from = module.dev-sec-project + to = module.project["dev"] + +} + +moved { + from = module.prod-sec-kms["europe"] + to = module.kms["prod-europe"] +} +moved { + from = module.prod-sec-kms["europe-west1"] + to = module.kms["prod-europe-west1"] +} +moved { + from = module.prod-sec-kms["europe-west3"] + to = module.kms["prod-europe-west3"] +} +moved { + from = module.prod-sec-kms["global"] + to = module.kms["prod-global"] +} +moved { + from = module.prod-sec-project + to = module.project["prod"] +} diff --git a/fast/stages/2-security/outputs.tf b/fast/stages/2-security/outputs.tf index 9fdd127836..efb6ebee6e 100644 --- a/fast/stages/2-security/outputs.tf +++ b/fast/stages/2-security/outputs.tf @@ -15,70 +15,28 @@ */ locals { - _output_kms_keys = concat( - flatten([ - for location, mod in module.dev-sec-kms : [ - for name, id in mod.key_ids : { - key = "dev-${name}:${location}" - id = id - } - ] - ]), - flatten([ - for location, mod in module.prod-sec-kms : [ - for name, id in mod.key_ids : { - key = "prod-${name}:${location}" - id = id - } - ] - ]) - ) - cas_configs = { - dev = { - for k, v in module.dev-cas - : k => { - ca_pool_id = v.ca_pool_id - ca_ids = v.ca_ids - location = v.ca_pool.location + _output_kms_keys = flatten([ + for k, v in module.kms : [ + for name, id in v.key_ids : { + key = "${name}-${k}" + id = id } - } - prod = { - for k, v in module.prod-cas - : k => { + ] + ]) + tfvars = { + cas_configs = { + for k, v in module.cas : k => { ca_pool_id = v.ca_pool_id ca_ids = v.ca_ids location = v.ca_pool.location } } - } - ngfw_tls_configs = { - tls_enabled = var.ngfw_tls_configs.tls_inspection.enabled - tls_ip_ids_by_region = { - dev = { - for k, v in google_network_security_tls_inspection_policy.ngfw_dev_tls_ips - : v.location => v.id - } - prod = { - for k, v in google_network_security_tls_inspection_policy.ngfw_prod_tls_ips - : v.location => v.id - } - } - } - output_kms_keys = { for k in local._output_kms_keys : k.key => k.id } - tfvars = { - cas_configs = local.cas_configs - kms_keys = local.output_kms_keys - ngfw_tls_configs = local.ngfw_tls_configs - trust_config_ids = local.trust_config_ids - } - trust_config_ids = { - dev = { - for k, v in google_certificate_manager_trust_config.dev_trust_configs - : k => v.id + kms_keys = { + for k in local._output_kms_keys : k.key => k.id } - prod = { - for k, v in google_certificate_manager_trust_config.prod_trust_configs - : k => v.id + trust_configs = { + for k, v in google_certificate_manager_trust_config.default : + k => v.id } } } @@ -98,17 +56,12 @@ resource "google_storage_bucket_object" "tfvars" { output "cas_configs" { description = "Certificate Authority Service configurations." - value = local.cas_configs + value = local.tfvars.cas_configs } output "kms_keys" { description = "KMS key ids." - value = local.output_kms_keys -} - -output "ngfw_tls_configs" { - description = "The NGFW Enterprise configurations." - value = local.ngfw_tls_configs + value = local.tfvars.kms_keys } output "tfvars" { @@ -119,5 +72,5 @@ output "tfvars" { output "trust_config_ids" { description = "Certificate Manager trust-config ids." - value = local.trust_config_ids + value = local.tfvars.trust_configs } diff --git a/fast/stages/2-security/variables-fast.tf b/fast/stages/2-security/variables-fast.tf index b8a664e52d..86abeefb32 100644 --- a/fast/stages/2-security/variables-fast.tf +++ b/fast/stages/2-security/variables-fast.tf @@ -49,6 +49,7 @@ variable "environments" { description = "Environment names." type = map(object({ name = string + short_name = string tag_name = string is_default = optional(bool, false) })) diff --git a/fast/stages/2-security/variables.tf b/fast/stages/2-security/variables.tf index b13967c0dd..c6a78f99b5 100644 --- a/fast/stages/2-security/variables.tf +++ b/fast/stages/2-security/variables.tf @@ -14,165 +14,78 @@ * limitations under the License. */ -variable "cas_configs" { - description = "The CAS CAs to add to each environment." - type = object({ - dev = optional(map(object({ - ca_configs = map(object({ - deletion_protection = optional(string, true) - type = optional(string, "SELF_SIGNED") - is_ca = optional(bool, true) - lifetime = optional(string, null) - pem_ca_certificate = optional(string, null) - ignore_active_certificates_on_deletion = optional(bool, false) - skip_grace_period = optional(bool, true) - labels = optional(map(string), null) - gcs_bucket = optional(string, null) - key_spec = optional(object({ - algorithm = optional(string, "RSA_PKCS1_2048_SHA256") - kms_key_id = optional(string, null) - }), {}) - key_usage = optional(object({ - cert_sign = optional(bool, true) - client_auth = optional(bool, false) - code_signing = optional(bool, false) - content_commitment = optional(bool, false) - crl_sign = optional(bool, true) - data_encipherment = optional(bool, false) - decipher_only = optional(bool, false) - digital_signature = optional(bool, false) - email_protection = optional(bool, false) - encipher_only = optional(bool, false) - key_agreement = optional(bool, false) - key_encipherment = optional(bool, true) - ocsp_signing = optional(bool, false) - server_auth = optional(bool, true) - time_stamping = optional(bool, false) - }), {}) - subject = optional(object({ - common_name = string - organization = string - country_code = optional(string) - locality = optional(string) - organizational_unit = optional(string) - postal_code = optional(string) - province = optional(string) - street_address = optional(string) - }), { - common_name = "test.example.com" - organization = "Test Example" - }) - subject_alt_name = optional(object({ - dns_names = optional(list(string), null) - email_addresses = optional(list(string), null) - ip_addresses = optional(list(string), null) - uris = optional(list(string), null) - }), null) - subordinate_config = optional(object({ - root_ca_id = optional(string) - pem_issuer_certificates = optional(list(string)) - }), null) - })) - ca_pool_config = object({ - ca_pool_id = optional(string, null) - name = optional(string, null) - tier = optional(string, "DEVOPS") - }) - location = string - iam = optional(map(list(string)), {}) - iam_bindings = optional(map(any), {}) - iam_bindings_additive = optional(map(any), {}) - iam_by_principals = optional(map(list(string)), {}) - })), {}) - prod = optional(map(object({ - ca_configs = map(object({ - deletion_protection = optional(string, true) - type = optional(string, "SELF_SIGNED") - is_ca = optional(bool, true) - lifetime = optional(string, null) - pem_ca_certificate = optional(string, null) - ignore_active_certificates_on_deletion = optional(bool, false) - skip_grace_period = optional(bool, true) - labels = optional(map(string), null) - gcs_bucket = optional(string, null) - key_spec = optional(object({ - algorithm = optional(string, "RSA_PKCS1_2048_SHA256") - kms_key_id = optional(string, null) - }), {}) - key_usage = optional(object({ - cert_sign = optional(bool, true) - client_auth = optional(bool, false) - code_signing = optional(bool, false) - content_commitment = optional(bool, false) - crl_sign = optional(bool, true) - data_encipherment = optional(bool, false) - decipher_only = optional(bool, false) - digital_signature = optional(bool, false) - email_protection = optional(bool, false) - encipher_only = optional(bool, false) - key_agreement = optional(bool, false) - key_encipherment = optional(bool, true) - ocsp_signing = optional(bool, false) - server_auth = optional(bool, true) - time_stamping = optional(bool, false) - }), {}) - subject = optional(object({ - common_name = string - organization = string - country_code = optional(string) - locality = optional(string) - organizational_unit = optional(string) - postal_code = optional(string) - province = optional(string) - street_address = optional(string) - }), { - common_name = "test.example.com" - organization = "Test Example" - }) - subject_alt_name = optional(object({ - dns_names = optional(list(string), null) - email_addresses = optional(list(string), null) - ip_addresses = optional(list(string), null) - uris = optional(list(string), null) - }), null) - subordinate_config = optional(object({ - root_ca_id = optional(string) - pem_issuer_certificates = optional(list(string)) - }), null) - })) - ca_pool_config = object({ - ca_pool_id = optional(string, null) - name = optional(string, null) - tier = optional(string, "DEVOPS") +variable "certificate_authorities" { + description = "Certificate Authority Service CAs. If environments is null the CA is created in all environments." + type = map(object({ + environments = optional(list(string)) + ca_configs = map(object({ + deletion_protection = optional(string, true) + type = optional(string, "SELF_SIGNED") + is_ca = optional(bool, true) + lifetime = optional(string, null) + pem_ca_certificate = optional(string, null) + ignore_active_certificates_on_deletion = optional(bool, false) + skip_grace_period = optional(bool, true) + labels = optional(map(string), null) + gcs_bucket = optional(string, null) + key_spec = optional(object({ + algorithm = optional(string, "RSA_PKCS1_2048_SHA256") + kms_key_id = optional(string, null) + }), {}) + key_usage = optional(object({ + cert_sign = optional(bool, true) + client_auth = optional(bool, false) + code_signing = optional(bool, false) + content_commitment = optional(bool, false) + crl_sign = optional(bool, true) + data_encipherment = optional(bool, false) + decipher_only = optional(bool, false) + digital_signature = optional(bool, false) + email_protection = optional(bool, false) + encipher_only = optional(bool, false) + key_agreement = optional(bool, false) + key_encipherment = optional(bool, true) + ocsp_signing = optional(bool, false) + server_auth = optional(bool, true) + time_stamping = optional(bool, false) + }), {}) + subject = optional(object({ + common_name = string + organization = string + country_code = optional(string) + locality = optional(string) + organizational_unit = optional(string) + postal_code = optional(string) + province = optional(string) + street_address = optional(string) + }), { + common_name = "test.example.com" + organization = "Test Example" }) - location = string - iam = optional(map(list(string)), {}) - iam_bindings = optional(map(object({ - members = list(string) - role = string - condition = optional(object({ - expression = string - title = string - description = optional(string) - })) - })), {}) - iam_bindings_additive = optional(map(object({ - member = string - role = string - condition = optional(object({ - expression = string - title = string - description = optional(string) - })) - })), {}) - iam_by_principals = optional(map(list(string)), {}) - })), {}) - }) + subject_alt_name = optional(object({ + dns_names = optional(list(string), null) + email_addresses = optional(list(string), null) + ip_addresses = optional(list(string), null) + uris = optional(list(string), null) + }), null) + subordinate_config = optional(object({ + root_ca_id = optional(string) + pem_issuer_certificates = optional(list(string)) + }), null) + })) + ca_pool_config = object({ + ca_pool_id = optional(string, null) + name = optional(string, null) + tier = optional(string, "DEVOPS") + }) + location = string + iam = optional(map(list(string)), {}) + iam_bindings = optional(map(any), {}) + iam_bindings_additive = optional(map(any), {}) + iam_by_principals = optional(map(list(string)), {}) + })) nullable = false - default = { - dev = {} - prod = {} - } + default = {} } variable "essential_contacts" { @@ -184,18 +97,6 @@ variable "essential_contacts" { variable "kms_keys" { description = "KMS keys to create, keyed by name." type = map(object({ - rotation_period = optional(string, "7776000s") - labels = optional(map(string)) - locations = optional(list(string), [ - "europe", "europe-west1", "europe-west3", "global" - ]) - purpose = optional(string, "ENCRYPT_DECRYPT") - skip_initial_version_creation = optional(bool, false) - version_template = optional(object({ - algorithm = string - protection_level = optional(string, "SOFTWARE") - })) - iam = optional(map(list(string)), {}) iam_bindings = optional(map(object({ members = list(string) @@ -215,36 +116,48 @@ variable "kms_keys" { description = optional(string) })) })), {}) + labels = optional(map(string)) + locations = optional(list(string), [ + "europe", "europe-west1", "europe-west3", "global" + ]) + purpose = optional(string, "ENCRYPT_DECRYPT") + rotation_period = optional(string, "7776000s") + skip_initial_version_creation = optional(bool, false) + version_template = optional(object({ + algorithm = string + protection_level = optional(string, "SOFTWARE") + })) })) default = {} nullable = false } -variable "ngfw_tls_configs" { - description = "The CAS and trust configurations key names to be used for NGFW Enterprise." - type = object({ - keys = optional(object({ - dev = optional(object({ - cas = optional(list(string), ["ngfw-dev-cas-0"]) - trust_configs = optional(list(string), ["ngfw-dev-tc-0"]) - }), {}) - prod = optional(object({ - cas = optional(list(string), ["ngfw-prod-cas-0"]) - trust_configs = optional(list(string), ["ngfw-prod-tc-0"]) - }), {}) - }), {}) - tls_inspection = optional(object({ - enabled = optional(bool, false) - exclude_public_ca_set = optional(bool, false) - min_tls_version = optional(string, "TLS_1_0") - }), {}) - }) - nullable = false - default = { - dev = {} - prod = {} - } -} +# move to netsec +# variable "tls_inspection_policies" { +# description = "The CAS and trust configurations key names to be used for NGFW Enterprise." +# type = object({ +# keys = optional(object({ +# dev = optional(object({ +# cas = optional(list(string), ["ngfw-dev-cas-0"]) +# trust_configs = optional(list(string), ["ngfw-dev-tc-0"]) +# }), {}) +# prod = optional(object({ +# cas = optional(list(string), ["ngfw-prod-cas-0"]) +# trust_configs = optional(list(string), ["ngfw-prod-tc-0"]) +# }), {}) +# }), {}) +# tls_inspection = optional(object({ +# enabled = optional(bool, false) +# exclude_public_ca_set = optional(bool, false) +# min_tls_version = optional(string, "TLS_1_0") +# }), {}) +# }) +# nullable = false +# default = { +# dev = {} +# prod = {} +# } +# } variable "outputs_location" { description = "Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable." @@ -253,30 +166,17 @@ variable "outputs_location" { } variable "trust_configs" { - description = "The trust configs grouped by environment." - type = object({ - dev = optional(map(object({ - description = optional(string) - location = string - allowlisted_certificates = optional(map(string), {}) - trust_stores = optional(map(object({ - intermediate_cas = optional(map(string), {}) - trust_anchors = optional(map(string), {}) - })), {}) - }))) - prod = optional(map(object({ - description = optional(string) - location = string - allowlisted_certificates = optional(map(string), {}) - trust_stores = optional(map(object({ - intermediate_cas = optional(map(string), {}) - trust_anchors = optional(map(string), {}) - })), {}) - }))) - }) + description = "The Certificate Manager trust configs. If environments is null the trust config is created in all environments." + type = map(object({ + location = string + description = optional(string) + environments = optional(list(string)) + allowlisted_certificates = optional(map(string), {}) + trust_stores = optional(map(object({ + intermediate_cas = optional(map(string), {}) + trust_anchors = optional(map(string), {}) + })), {}) + })) nullable = false - default = { - dev = {} - prod = {} - } + default = {} } diff --git a/tests/fast/stages/s1_resman/simple.yaml b/tests/fast/stages/s1_resman/simple.yaml index 0f7d2058d3..73290e9118 100644 --- a/tests/fast/stages/s1_resman/simple.yaml +++ b/tests/fast/stages/s1_resman/simple.yaml @@ -13,81 +13,6 @@ # limitations under the License. values: - google_storage_bucket_object.providers["1-resman-folder-sandbox"]: - bucket: fast2-prod-iac-core-outputs - name: providers/1-resman-folder-sandbox-providers.tf - google_storage_bucket_object.providers["1-resman-folder-tenants"]: - bucket: fast2-prod-iac-core-outputs - name: providers/1-resman-folder-tenants-providers.tf - google_storage_bucket_object.providers["2-network-security"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-network-security-providers.tf - google_storage_bucket_object.providers["2-network-security-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-network-security-r-providers.tf - google_storage_bucket_object.providers["2-networking"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-networking-providers.tf - google_storage_bucket_object.providers["2-networking-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-networking-r-providers.tf - google_storage_bucket_object.providers["2-project-factory"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-project-factory-providers.tf - google_storage_bucket_object.providers["2-project-factory-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-project-factory-r-providers.tf - google_storage_bucket_object.providers["2-security"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-security-providers.tf - google_storage_bucket_object.providers["2-security-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/2-security-r-providers.tf - google_storage_bucket_object.providers["3-gcve-dev"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gcve-dev-providers.tf - google_storage_bucket_object.providers["3-gcve-dev-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gcve-dev-r-providers.tf - google_storage_bucket_object.providers["3-gcve-prod"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gcve-prod-providers.tf - google_storage_bucket_object.providers["3-gcve-prod-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gcve-prod-r-providers.tf - google_storage_bucket_object.providers["3-gke-dev"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gke-dev-providers.tf - google_storage_bucket_object.providers["3-gke-dev-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gke-dev-r-providers.tf - google_storage_bucket_object.providers["3-gke-prod"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gke-prod-providers.tf - google_storage_bucket_object.providers["3-gke-prod-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-gke-prod-r-providers.tf - google_storage_bucket_object.providers["3-project-factory-dev"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-project-factory-dev-providers.tf - google_storage_bucket_object.providers["3-project-factory-dev-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-project-factory-dev-r-providers.tf - google_storage_bucket_object.providers["3-project-factory-prod"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-project-factory-prod-providers.tf - google_storage_bucket_object.providers["3-project-factory-prod-r"]: - bucket: fast2-prod-iac-core-outputs - name: providers/3-project-factory-prod-r-providers.tf - google_storage_bucket_object.tfvars: - bucket: fast2-prod-iac-core-outputs - name: tfvars/1-resman.auto.tfvars.json - google_storage_bucket_object.workflows["networking"]: - bucket: fast2-prod-iac-core-outputs - name: workflows/networking-workflow.yaml - google_storage_bucket_object.workflows["security"]: - bucket: fast2-prod-iac-core-outputs - name: workflows/security-workflow.yaml module.cicd-sa-ro["networking"].google_project_iam_member.project-roles["fast2-prod-automation-roles/logging.logWriter"]: condition: [] project: fast2-prod-automation @@ -98,6 +23,8 @@ values: description: null disabled: false display_name: CI/CD 2-net prod service account (read-only). + email: fast2-prod-resman-net-1r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-net-1r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.cicd-sa-ro["networking"].google_service_account_iam_binding.authoritative["roles/iam.workloadIdentityUser"]: @@ -119,6 +46,8 @@ values: description: null disabled: false display_name: CI/CD 2-sec prod service account (read-only). + email: fast2-prod-resman-sec-1r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-sec-1r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.cicd-sa-ro["security"].google_service_account_iam_binding.authoritative["roles/iam.workloadIdentityUser"]: @@ -140,6 +69,8 @@ values: description: null disabled: false display_name: CI/CD 2-net prod service account. + email: fast2-prod-resman-net-1@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-net-1@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.cicd-sa-rw["networking"].google_service_account_iam_binding.authoritative["roles/iam.workloadIdentityUser"]: @@ -161,6 +92,8 @@ values: description: null disabled: false display_name: CI/CD 2-sec prod service account. + email: fast2-prod-resman-sec-1@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-sec-1@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.cicd-sa-rw["security"].google_service_account_iam_binding.authoritative["roles/iam.workloadIdentityUser"]: @@ -182,6 +115,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -209,21 +143,24 @@ values: members: - serviceAccount:fast2-prod-resman-net-0r@fast2-prod-automation.iam.gserviceaccount.com role: roles/storage.objectViewer - module.net-folder-dev[0].google_folder.folder[0]: + module.net-folder-envs["dev"].google_folder.folder[0]: deletion_protection: false display_name: Development + tags: null timeouts: null - module.net-folder-dev[0].google_tags_tag_binding.binding["environment"]: + module.net-folder-envs["dev"].google_tags_tag_binding.binding["environment"]: timeouts: null - module.net-folder-prod[0].google_folder.folder[0]: + module.net-folder-envs["prod"].google_folder.folder[0]: deletion_protection: false display_name: Production + tags: null timeouts: null - module.net-folder-prod[0].google_tags_tag_binding.binding["environment"]: + module.net-folder-envs["prod"].google_tags_tag_binding.binding["environment"]: timeouts: null module.net-folder[0].google_folder.folder[0]: deletion_protection: false display_name: Networking + tags: null timeouts: null ? module.net-folder[0].google_folder_iam_binding.authoritative["organizations/123456789012/roles/networkFirewallPoliciesAdmin"] : condition: [] @@ -403,6 +340,8 @@ values: description: null disabled: false display_name: Terraform resman networking service account (read-only). + email: fast2-prod-resman-net-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-net-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.net-sa-ro[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -424,6 +363,8 @@ values: description: null disabled: false display_name: Terraform resman networking service account. + email: fast2-prod-resman-net-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-net-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.net-sa-rw[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -445,6 +386,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -482,6 +424,8 @@ values: description: null disabled: false display_name: Terraform resman network security main service account (read-only). + email: fast2-resman-nsec-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-resman-nsec-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.nsec-sa-ro[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -502,6 +446,8 @@ values: description: null disabled: false display_name: Terraform resman network security main service account. + email: fast2-resman-nsec-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-resman-nsec-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.nsec-sa-rw[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -716,6 +662,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -753,6 +700,8 @@ values: description: null disabled: false display_name: Terraform resman project factory main service account (read-only). + email: fast2-resman-pf-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-resman-pf-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.pf-sa-ro[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -773,6 +722,8 @@ values: description: null disabled: false display_name: Terraform resman project factory main service account. + email: fast2-resman-pf-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-resman-pf-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.pf-sa-rw[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -793,6 +744,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -824,6 +776,7 @@ values: deletion_protection: false display_name: Security parent: organizations/123456789012 + tags: null timeouts: null module.sec-folder[0].google_folder_iam_binding.authoritative["organizations/123456789012/roles/projectIamViewer"]: condition: [] @@ -905,6 +858,8 @@ values: description: null disabled: false display_name: Terraform resman security service account (read-only). + email: fast2-prod-resman-sec-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-sec-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.sec-sa-ro[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -926,6 +881,8 @@ values: description: null disabled: false display_name: Terraform resman security service account. + email: fast2-prod-resman-sec-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-sec-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.sec-sa-rw[0].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -947,6 +904,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -984,6 +942,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1021,6 +980,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1058,6 +1018,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1095,6 +1056,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1132,6 +1094,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1162,6 +1125,7 @@ values: module.stage3-folder["gcve-dev"].google_folder.folder[0]: deletion_protection: false display_name: Development + tags: null timeouts: null module.stage3-folder["gcve-dev"].google_folder_iam_binding.authoritative["roles/compute.xpnAdmin"]: condition: [] @@ -1203,6 +1167,7 @@ values: module.stage3-folder["gcve-prod"].google_folder.folder[0]: deletion_protection: false display_name: Production + tags: null timeouts: null module.stage3-folder["gcve-prod"].google_folder_iam_binding.authoritative["roles/compute.xpnAdmin"]: condition: [] @@ -1244,6 +1209,7 @@ values: module.stage3-folder["gke-dev"].google_folder.folder[0]: deletion_protection: false display_name: Development + tags: null timeouts: null module.stage3-folder["gke-dev"].google_folder_iam_binding.authoritative["roles/compute.xpnAdmin"]: condition: [] @@ -1285,6 +1251,7 @@ values: module.stage3-folder["gke-prod"].google_folder.folder[0]: deletion_protection: false display_name: Production + tags: null timeouts: null module.stage3-folder["gke-prod"].google_folder_iam_binding.authoritative["roles/compute.xpnAdmin"]: condition: [] @@ -1333,6 +1300,8 @@ values: description: null disabled: false display_name: Terraform resman gcve-dev service account (read-only). + email: fast2-dev-resman-gcve-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-gcve-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-ro["gcve-dev"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1353,6 +1322,8 @@ values: description: null disabled: false display_name: Terraform resman gcve-prod service account (read-only). + email: fast2-prod-resman-gcve-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-gcve-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-ro["gcve-prod"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1373,6 +1344,8 @@ values: description: null disabled: false display_name: Terraform resman gke-dev service account (read-only). + email: fast2-dev-resman-gke-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-gke-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-ro["gke-dev"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1393,6 +1366,8 @@ values: description: null disabled: false display_name: Terraform resman gke-prod service account (read-only). + email: fast2-prod-resman-gke-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-gke-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-ro["gke-prod"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1413,6 +1388,8 @@ values: description: null disabled: false display_name: Terraform resman project-factory-dev service account (read-only). + email: fast2-dev-resman-pf-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-pf-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null ? module.stage3-sa-ro["project-factory-dev"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"] @@ -1433,6 +1410,8 @@ values: description: null disabled: false display_name: Terraform resman project-factory-prod service account (read-only). + email: fast2-prod-resman-pf-0r@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-pf-0r@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null ? module.stage3-sa-ro["project-factory-prod"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"] @@ -1453,6 +1432,8 @@ values: description: null disabled: false display_name: Terraform resman gcve-dev service account. + email: fast2-dev-resman-gcve-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-gcve-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-rw["gcve-dev"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1473,6 +1454,8 @@ values: description: null disabled: false display_name: Terraform resman gcve-prod service account. + email: fast2-prod-resman-gcve-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-gcve-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-rw["gcve-prod"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1493,6 +1476,8 @@ values: description: null disabled: false display_name: Terraform resman gke-dev service account. + email: fast2-dev-resman-gke-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-gke-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-rw["gke-dev"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1513,6 +1498,8 @@ values: description: null disabled: false display_name: Terraform resman gke-prod service account. + email: fast2-prod-resman-gke-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-gke-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.stage3-sa-rw["gke-prod"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1533,6 +1520,8 @@ values: description: null disabled: false display_name: Terraform resman project-factory-dev service account. + email: fast2-dev-resman-pf-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-pf-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null ? module.stage3-sa-rw["project-factory-dev"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"] @@ -1553,6 +1542,8 @@ values: description: null disabled: false display_name: Terraform resman project-factory-prod service account. + email: fast2-prod-resman-pf-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-pf-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null ? module.stage3-sa-rw["project-factory-prod"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"] @@ -1573,6 +1564,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1610,6 +1602,7 @@ values: enable_object_retention: null encryption: [] force_destroy: false + hierarchical_namespace: [] labels: null lifecycle_rule: [] location: EU @@ -1641,6 +1634,7 @@ values: deletion_protection: false display_name: GCVE parent: organizations/123456789012 + tags: null timeouts: null module.top-level-folder["gcve"].google_tags_tag_binding.binding["context"]: timeouts: null @@ -1648,6 +1642,7 @@ values: deletion_protection: false display_name: GKE parent: organizations/123456789012 + tags: null timeouts: null module.top-level-folder["gke"].google_tags_tag_binding.binding["context"]: timeouts: null @@ -1655,36 +1650,13 @@ values: deletion_protection: false display_name: Sandbox parent: organizations/123456789012 - module.top-level-folder["sandbox"].google_org_policy_policy.default["compute.vmExternalIpAccess"]: - dry_run_spec: [] - spec: - - inherit_from_parent: null - reset: null - rules: - - allow_all: 'TRUE' - condition: [] - deny_all: null - enforce: null - values: [] - timeouts: null - module.top-level-folder["sandbox"].google_org_policy_policy.default["sql.restrictPublicIp"]: - dry_run_spec: [] - spec: - - inherit_from_parent: null - reset: null - rules: - - allow_all: null - condition: [] - deny_all: null - enforce: 'TRUE' - values: [] - timeouts: null - module.top-level-folder["sandbox"].google_tags_tag_binding.binding["context"]: + tags: null timeouts: null module.top-level-folder["teams"].google_folder.folder[0]: deletion_protection: false display_name: Teams parent: organizations/123456789012 + tags: null timeouts: null ? module.top-level-folder["teams"].google_folder_iam_binding.authoritative["organizations/123456789012/roles/xpnServiceAdmin"] : condition: [] @@ -1732,6 +1704,7 @@ values: deletion_protection: false display_name: Tenants parent: organizations/123456789012 + tags: null timeouts: null module.top-level-folder["tenants"].google_tags_tag_binding.binding["context"]: timeouts: null @@ -1745,6 +1718,8 @@ values: description: null disabled: false display_name: Terraform resman sandbox folder service account. + email: fast2-dev-resman-sbox-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-dev-resman-sbox-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.top-level-sa["sandbox"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1765,6 +1740,8 @@ values: description: null disabled: false display_name: Terraform resman tenants folder service account. + email: fast2-prod-resman-tenants-0@fast2-prod-automation.iam.gserviceaccount.com + member: serviceAccount:fast2-prod-resman-tenants-0@fast2-prod-automation.iam.gserviceaccount.com project: fast2-prod-automation timeouts: null module.top-level-sa["tenants"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: @@ -1811,3 +1788,4 @@ outputs: type: gitlab folder_ids: __missing__ tfvars: __missing__ + diff --git a/tests/fast/stages/s2_security/simple.tfvars b/tests/fast/stages/s2_security/simple.tfvars index 8713d2693d..dcea9e4b1f 100644 --- a/tests/fast/stages/s2_security/simple.tfvars +++ b/tests/fast/stages/s2_security/simple.tfvars @@ -12,11 +12,13 @@ environments = { dev = { is_default = false name = "Development" + short_name = "dev" tag_name = "development" } prod = { is_default = true name = "Production" + short_name = "prod" tag_name = "production" } } diff --git a/tests/fast/stages/s2_security/simple.yaml b/tests/fast/stages/s2_security/simple.yaml index 5fbb91f0e2..23a3d6a2a8 100644 --- a/tests/fast/stages/s2_security/simple.yaml +++ b/tests/fast/stages/s2_security/simple.yaml @@ -28,7 +28,14 @@ values: source: null temporary_hold: null timeouts: null - module.dev-sec-kms["europe"].google_kms_crypto_key.default["compute"]: + module.folder.google_essential_contacts_contact.contact["gcp-security-admins@fast.example.com"]: + email: gcp-security-admins@fast.example.com + language_tag: en + notification_category_subscriptions: + - ALL + parent: folders/12345678 + timeouts: null + module.kms["dev-europe"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -42,17 +49,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.dev-sec-kms["europe"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["dev-europe"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.dev-sec-kms["europe"].google_kms_key_ring.default[0]: + module.kms["dev-europe"].google_kms_key_ring.default[0]: location: europe name: dev-europe project: fast-dev-sec-core-0 timeouts: null - module.dev-sec-kms["europe-west1"].google_kms_crypto_key.default["compute"]: + module.kms["dev-europe-west1"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -66,17 +73,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.dev-sec-kms["europe-west1"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["dev-europe-west1"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.dev-sec-kms["europe-west1"].google_kms_key_ring.default[0]: + module.kms["dev-europe-west1"].google_kms_key_ring.default[0]: location: europe-west1 name: dev-europe-west1 project: fast-dev-sec-core-0 timeouts: null - module.dev-sec-kms["europe-west3"].google_kms_crypto_key.default["compute"]: + module.kms["dev-europe-west3"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -90,17 +97,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.dev-sec-kms["europe-west3"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["dev-europe-west3"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.dev-sec-kms["europe-west3"].google_kms_key_ring.default[0]: + module.kms["dev-europe-west3"].google_kms_key_ring.default[0]: location: europe-west3 name: dev-europe-west3 project: fast-dev-sec-core-0 timeouts: null - module.dev-sec-kms["global"].google_kms_crypto_key.default["compute"]: + module.kms["dev-global"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -114,122 +121,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.dev-sec-kms["global"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["dev-global"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.dev-sec-kms["global"].google_kms_key_ring.default[0]: + module.kms["dev-global"].google_kms_key_ring.default[0]: location: global name: dev-global project: fast-dev-sec-core-0 timeouts: null - module.dev-sec-project.google_project.project[0]: - auto_create_network: false - billing_account: 000000-111111-222222 - deletion_policy: DELETE - effective_labels: - environment: dev - goog-terraform-provisioned: 'true' - folder_id: '12345678' - labels: - environment: dev - name: fast-dev-sec-core-0 - org_id: null - project_id: fast-dev-sec-core-0 - terraform_labels: - environment: dev - goog-terraform-provisioned: 'true' - timeouts: null - module.dev-sec-project.google_project_iam_member.service_agents["certificatemanager"]: - condition: [] - project: fast-dev-sec-core-0 - role: roles/certificatemanager.serviceAgent - module.dev-sec-project.google_project_iam_member.service_agents["cloudkms"]: - condition: [] - project: fast-dev-sec-core-0 - role: roles/cloudkms.serviceAgent - module.dev-sec-project.google_project_iam_member.service_agents["networkmanagement"]: - condition: [] - project: fast-dev-sec-core-0 - role: roles/networkmanagement.serviceAgent - module.dev-sec-project.google_project_service.project_services["certificatemanager.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: certificatemanager.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service.project_services["cloudkms.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: cloudkms.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service.project_services["networkmanagement.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: networkmanagement.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service.project_services["networksecurity.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: networksecurity.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service.project_services["privateca.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: privateca.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service.project_services["secretmanager.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: secretmanager.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service.project_services["stackdriver.googleapis.com"]: - disable_dependent_services: false - disable_on_destroy: false - project: fast-dev-sec-core-0 - service: stackdriver.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service_identity.default["certificatemanager.googleapis.com"]: - project: fast-dev-sec-core-0 - service: certificatemanager.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service_identity.default["cloudkms.googleapis.com"]: - project: fast-dev-sec-core-0 - service: cloudkms.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service_identity.default["networkmanagement.googleapis.com"]: - project: fast-dev-sec-core-0 - service: networkmanagement.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service_identity.default["networksecurity.googleapis.com"]: - project: fast-dev-sec-core-0 - service: networksecurity.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service_identity.default["privateca.googleapis.com"]: - project: fast-dev-sec-core-0 - service: privateca.googleapis.com - timeouts: null - module.dev-sec-project.google_project_service_identity.default["secretmanager.googleapis.com"]: - project: fast-dev-sec-core-0 - service: secretmanager.googleapis.com - timeouts: null - module.dev-sec-project.google_tags_tag_binding.binding["environment"]: - tag_value: tagValues/12345 - timeouts: null - module.folder.google_essential_contacts_contact.contact["gcp-security-admins@fast.example.com"]: - email: gcp-security-admins@fast.example.com - language_tag: en - notification_category_subscriptions: - - ALL - parent: folders/12345678 - timeouts: null - module.prod-sec-kms["europe"].google_kms_crypto_key.default["compute"]: + module.kms["prod-europe"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -243,17 +145,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.prod-sec-kms["europe"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["prod-europe"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.prod-sec-kms["europe"].google_kms_key_ring.default[0]: + module.kms["prod-europe"].google_kms_key_ring.default[0]: location: europe name: prod-europe project: fast-prod-sec-core-0 timeouts: null - module.prod-sec-kms["europe-west1"].google_kms_crypto_key.default["compute"]: + module.kms["prod-europe-west1"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -267,17 +169,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.prod-sec-kms["europe-west1"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["prod-europe-west1"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.prod-sec-kms["europe-west1"].google_kms_key_ring.default[0]: + module.kms["prod-europe-west1"].google_kms_key_ring.default[0]: location: europe-west1 name: prod-europe-west1 project: fast-prod-sec-core-0 timeouts: null - module.prod-sec-kms["europe-west3"].google_kms_crypto_key.default["compute"]: + module.kms["prod-europe-west3"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -291,17 +193,17 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.prod-sec-kms["europe-west3"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["prod-europe-west3"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.prod-sec-kms["europe-west3"].google_kms_key_ring.default[0]: + module.kms["prod-europe-west3"].google_kms_key_ring.default[0]: location: europe-west3 name: prod-europe-west3 project: fast-prod-sec-core-0 timeouts: null - module.prod-sec-kms["global"].google_kms_crypto_key.default["compute"]: + module.kms["prod-global"].google_kms_crypto_key.default["compute"]: effective_labels: goog-terraform-provisioned: 'true' service: compute @@ -315,17 +217,133 @@ values: goog-terraform-provisioned: 'true' service: compute timeouts: null - module.prod-sec-kms["global"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: + module.kms["prod-global"].google_kms_crypto_key_iam_binding.authoritative["compute.roles/cloudkms.admin"]: condition: [] members: - user:user1@example.com role: roles/cloudkms.admin - module.prod-sec-kms["global"].google_kms_key_ring.default[0]: + module.kms["prod-global"].google_kms_key_ring.default[0]: location: global name: prod-global project: fast-prod-sec-core-0 timeouts: null - module.prod-sec-project.google_project.project[0]: + module.project["dev"].google_project.project[0]: + auto_create_network: false + billing_account: 000000-111111-222222 + deletion_policy: DELETE + effective_labels: + environment: dev + goog-terraform-provisioned: 'true' + folder_id: '12345678' + labels: + environment: dev + name: fast-dev-sec-core-0 + org_id: null + project_id: fast-dev-sec-core-0 + tags: null + terraform_labels: + environment: dev + goog-terraform-provisioned: 'true' + timeouts: null + module.project["dev"].google_project_iam_binding.authoritative["organizations/123456789012/roles/bar"]: + condition: [] + members: + - serviceAccount:fast2-dev-resman-gcve-0r@fast2-prod-iac-core-0.iam.gserviceaccount.com + - serviceAccount:fast2-dev-resman-pf-0r@fast2-prod-iac-core-0.iam.gserviceaccount.com + project: fast-dev-sec-core-0 + role: organizations/123456789012/roles/bar + module.project["dev"].google_project_iam_binding.bindings["sa_delegated_grants"]: + condition: + - description: Development project delegated grants. + expression: api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/cloudkms.cryptoKeyEncrypterDecrypter']) + title: dev_stage3_sa_delegated_grants + members: + - serviceAccount:fast2-dev-resman-gcve-0@fast2-prod-iac-core-0.iam.gserviceaccount.com + - serviceAccount:fast2-dev-resman-pf-0@fast2-prod-iac-core-0.iam.gserviceaccount.com + project: fast-dev-sec-core-0 + role: roles/resourcemanager.projectIamAdmin + module.project["dev"].google_project_iam_member.service_agents["certificatemanager"]: + condition: [] + project: fast-dev-sec-core-0 + role: roles/certificatemanager.serviceAgent + module.project["dev"].google_project_iam_member.service_agents["cloudkms"]: + condition: [] + project: fast-dev-sec-core-0 + role: roles/cloudkms.serviceAgent + module.project["dev"].google_project_iam_member.service_agents["networkmanagement"]: + condition: [] + project: fast-dev-sec-core-0 + role: roles/networkmanagement.serviceAgent + module.project["dev"].google_project_service.project_services["certificatemanager.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: certificatemanager.googleapis.com + timeouts: null + module.project["dev"].google_project_service.project_services["cloudkms.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: cloudkms.googleapis.com + timeouts: null + module.project["dev"].google_project_service.project_services["networkmanagement.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: networkmanagement.googleapis.com + timeouts: null + module.project["dev"].google_project_service.project_services["networksecurity.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: networksecurity.googleapis.com + timeouts: null + module.project["dev"].google_project_service.project_services["privateca.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: privateca.googleapis.com + timeouts: null + module.project["dev"].google_project_service.project_services["secretmanager.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: secretmanager.googleapis.com + timeouts: null + module.project["dev"].google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: fast-dev-sec-core-0 + service: stackdriver.googleapis.com + timeouts: null + module.project["dev"].google_project_service_identity.default["certificatemanager.googleapis.com"]: + project: fast-dev-sec-core-0 + service: certificatemanager.googleapis.com + timeouts: null + module.project["dev"].google_project_service_identity.default["cloudkms.googleapis.com"]: + project: fast-dev-sec-core-0 + service: cloudkms.googleapis.com + timeouts: null + module.project["dev"].google_project_service_identity.default["networkmanagement.googleapis.com"]: + project: fast-dev-sec-core-0 + service: networkmanagement.googleapis.com + timeouts: null + module.project["dev"].google_project_service_identity.default["networksecurity.googleapis.com"]: + project: fast-dev-sec-core-0 + service: networksecurity.googleapis.com + timeouts: null + module.project["dev"].google_project_service_identity.default["privateca.googleapis.com"]: + project: fast-dev-sec-core-0 + service: privateca.googleapis.com + timeouts: null + module.project["dev"].google_project_service_identity.default["secretmanager.googleapis.com"]: + project: fast-dev-sec-core-0 + service: secretmanager.googleapis.com + timeouts: null + module.project["dev"].google_tags_tag_binding.binding["environment"]: + tag_value: tagValues/12345 + timeouts: null + module.project["prod"].google_project.project[0]: auto_create_network: false billing_account: 000000-111111-222222 deletion_policy: DELETE @@ -338,89 +356,107 @@ values: name: fast-prod-sec-core-0 org_id: null project_id: fast-prod-sec-core-0 + tags: null terraform_labels: environment: prod goog-terraform-provisioned: 'true' timeouts: null - module.prod-sec-project.google_project_iam_member.service_agents["certificatemanager"]: + module.project["prod"].google_project_iam_binding.authoritative["organizations/123456789012/roles/bar"]: + condition: [] + members: + - serviceAccount:fast2-prod-resman-gcve-0r@fast2-prod-iac-core-0.iam.gserviceaccount.com + - serviceAccount:fast2-prod-resman-pf-0r@fast2-prod-iac-core-0.iam.gserviceaccount.com + project: fast-prod-sec-core-0 + role: organizations/123456789012/roles/bar + module.project["prod"].google_project_iam_binding.bindings["sa_delegated_grants"]: + condition: + - description: Production project delegated grants. + expression: api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/cloudkms.cryptoKeyEncrypterDecrypter']) + title: prod_stage3_sa_delegated_grants + members: + - serviceAccount:fast2-prod-resman-gcve-0@fast2-prod-iac-core-0.iam.gserviceaccount.com + - serviceAccount:fast2-prod-resman-pf-0@fast2-prod-iac-core-0.iam.gserviceaccount.com + project: fast-prod-sec-core-0 + role: roles/resourcemanager.projectIamAdmin + module.project["prod"].google_project_iam_member.service_agents["certificatemanager"]: condition: [] project: fast-prod-sec-core-0 role: roles/certificatemanager.serviceAgent - module.prod-sec-project.google_project_iam_member.service_agents["cloudkms"]: + module.project["prod"].google_project_iam_member.service_agents["cloudkms"]: condition: [] project: fast-prod-sec-core-0 role: roles/cloudkms.serviceAgent - module.prod-sec-project.google_project_iam_member.service_agents["networkmanagement"]: + module.project["prod"].google_project_iam_member.service_agents["networkmanagement"]: condition: [] project: fast-prod-sec-core-0 role: roles/networkmanagement.serviceAgent - module.prod-sec-project.google_project_service.project_services["certificatemanager.googleapis.com"]: + module.project["prod"].google_project_service.project_services["certificatemanager.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: certificatemanager.googleapis.com timeouts: null - module.prod-sec-project.google_project_service.project_services["cloudkms.googleapis.com"]: + module.project["prod"].google_project_service.project_services["cloudkms.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: cloudkms.googleapis.com timeouts: null - module.prod-sec-project.google_project_service.project_services["networkmanagement.googleapis.com"]: + module.project["prod"].google_project_service.project_services["networkmanagement.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: networkmanagement.googleapis.com timeouts: null - module.prod-sec-project.google_project_service.project_services["networksecurity.googleapis.com"]: + module.project["prod"].google_project_service.project_services["networksecurity.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: networksecurity.googleapis.com timeouts: null - module.prod-sec-project.google_project_service.project_services["privateca.googleapis.com"]: + module.project["prod"].google_project_service.project_services["privateca.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: privateca.googleapis.com timeouts: null - module.prod-sec-project.google_project_service.project_services["secretmanager.googleapis.com"]: + module.project["prod"].google_project_service.project_services["secretmanager.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: secretmanager.googleapis.com timeouts: null - module.prod-sec-project.google_project_service.project_services["stackdriver.googleapis.com"]: + module.project["prod"].google_project_service.project_services["stackdriver.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false project: fast-prod-sec-core-0 service: stackdriver.googleapis.com timeouts: null - module.prod-sec-project.google_project_service_identity.default["certificatemanager.googleapis.com"]: + module.project["prod"].google_project_service_identity.default["certificatemanager.googleapis.com"]: project: fast-prod-sec-core-0 service: certificatemanager.googleapis.com timeouts: null - module.prod-sec-project.google_project_service_identity.default["cloudkms.googleapis.com"]: + module.project["prod"].google_project_service_identity.default["cloudkms.googleapis.com"]: project: fast-prod-sec-core-0 service: cloudkms.googleapis.com timeouts: null - module.prod-sec-project.google_project_service_identity.default["networkmanagement.googleapis.com"]: + module.project["prod"].google_project_service_identity.default["networkmanagement.googleapis.com"]: project: fast-prod-sec-core-0 service: networkmanagement.googleapis.com timeouts: null - module.prod-sec-project.google_project_service_identity.default["networksecurity.googleapis.com"]: + module.project["prod"].google_project_service_identity.default["networksecurity.googleapis.com"]: project: fast-prod-sec-core-0 service: networksecurity.googleapis.com timeouts: null - module.prod-sec-project.google_project_service_identity.default["privateca.googleapis.com"]: + module.project["prod"].google_project_service_identity.default["privateca.googleapis.com"]: project: fast-prod-sec-core-0 service: privateca.googleapis.com timeouts: null - module.prod-sec-project.google_project_service_identity.default["secretmanager.googleapis.com"]: + module.project["prod"].google_project_service_identity.default["secretmanager.googleapis.com"]: project: fast-prod-sec-core-0 service: secretmanager.googleapis.com timeouts: null - module.prod-sec-project.google_tags_tag_binding.binding["environment"]: + module.project["prod"].google_tags_tag_binding.binding["environment"]: tag_value: tagValues/12346 timeouts: null @@ -438,3 +474,10 @@ counts: google_tags_tag_binding: 2 modules: 11 resources: 66 + +outputs: + cas_configs: {} + kms_keys: __missing__ + tfvars: __missing__ + trust_config_ids: {} +