[FAST] Add basic NGFW enterprise stage (#2410)
This commit is contained in:
@@ -83,6 +83,21 @@ case $STAGE_NAME in
|
||||
tenants/$TENANT/tfvars/1-resman.auto.tfvars.json"
|
||||
fi
|
||||
;;
|
||||
"3-network-security"*)
|
||||
if [[ -z "$TENANT" ]]; then
|
||||
echo "# if this is a tenant stage, set a \$TENANT variable with the tenant shortname and run the command again"
|
||||
PROVIDER="providers/3-netsec-providers.tf"
|
||||
TFVARS="tfvars/0-bootstrap.auto.tfvars.json
|
||||
tfvars/1-resman.auto.tfvars.json
|
||||
tfvars/2-networking.auto.tfvars.json"
|
||||
else
|
||||
unset GLOBALS
|
||||
PROVIDER="tenants/$TENANT/providers/3-netsec-providers.tf"
|
||||
TFVARS="tenants/$TENANT/tfvars/0-bootstrap-tenant.auto.tfvars.json
|
||||
tenants/$TENANT/tfvars/1-resman.auto.tfvars.json
|
||||
tenants/$TENANT/tfvars/2-networking.auto.tfvars.json"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# check for a "dev" stage 3
|
||||
echo "no stage found, trying for parent stage 3..."
|
||||
|
||||
@@ -143,6 +143,7 @@ module "automation-project" {
|
||||
"essentialcontacts.googleapis.com",
|
||||
"iam.googleapis.com",
|
||||
"iamcredentials.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"orgpolicy.googleapis.com",
|
||||
"pubsub.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
name: networkFirewallPoliciesAdmin
|
||||
includedPermissions:
|
||||
- compute.networks.setFirewallPolicy
|
||||
- networksecurity.firewallEndpointAssociations.create
|
||||
- networksecurity.firewallEndpointAssociations.delete
|
||||
- networksecurity.firewallEndpointAssociations.get
|
||||
- networksecurity.firewallEndpointAssociations.list
|
||||
- networksecurity.firewallEndpointAssociations.update
|
||||
@@ -0,0 +1,40 @@
|
||||
# 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.
|
||||
|
||||
name: ngfwEnterpriseAdmin
|
||||
includedPermissions:
|
||||
- networksecurity.firewallEndpoints.create
|
||||
- networksecurity.firewallEndpoints.delete
|
||||
- networksecurity.firewallEndpoints.get
|
||||
- networksecurity.firewallEndpoints.list
|
||||
- networksecurity.firewallEndpoints.update
|
||||
- networksecurity.firewallEndpoints.use
|
||||
- networksecurity.locations.get
|
||||
- networksecurity.locations.list
|
||||
- networksecurity.operations.cancel
|
||||
- networksecurity.operations.delete
|
||||
- networksecurity.operations.get
|
||||
- networksecurity.operations.list
|
||||
- networksecurity.securityProfileGroups.create
|
||||
- networksecurity.securityProfileGroups.delete
|
||||
- networksecurity.securityProfileGroups.get
|
||||
- networksecurity.securityProfileGroups.list
|
||||
- networksecurity.securityProfileGroups.update
|
||||
- networksecurity.securityProfileGroups.use
|
||||
- networksecurity.securityProfiles.create
|
||||
- networksecurity.securityProfiles.delete
|
||||
- networksecurity.securityProfiles.get
|
||||
- networksecurity.securityProfiles.list
|
||||
- networksecurity.securityProfiles.update
|
||||
- networksecurity.securityProfiles.use
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2023 Google LLC
|
||||
* 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.
|
||||
|
||||
@@ -163,23 +163,36 @@ module "organization" {
|
||||
# delegated role grant for resource manager service account
|
||||
iam_bindings = merge(
|
||||
{
|
||||
organization_ngfw_enterprise_admin = {
|
||||
members = [local.principals.gcp-network-admins]
|
||||
role = module.organization.custom_role_id["ngfw_enterprise_admin"]
|
||||
}
|
||||
organization_iam_admin_conditional = {
|
||||
members = [module.automation-tf-resman-sa.iam_email]
|
||||
role = module.organization.custom_role_id["organization_iam_admin"]
|
||||
condition = {
|
||||
expression = format(
|
||||
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
|
||||
join(",", formatlist("'%s'", [
|
||||
"roles/accesscontextmanager.policyAdmin",
|
||||
"roles/cloudasset.viewer",
|
||||
"roles/compute.orgFirewallPolicyAdmin",
|
||||
"roles/compute.xpnAdmin",
|
||||
"roles/orgpolicy.policyAdmin",
|
||||
"roles/orgpolicy.policyViewer",
|
||||
"roles/resourcemanager.organizationViewer",
|
||||
module.organization.custom_role_id["service_project_network_admin"],
|
||||
module.organization.custom_role_id["tenant_network_admin"],
|
||||
]))
|
||||
expression = (
|
||||
format(
|
||||
<<-EOT
|
||||
api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])
|
||||
|| api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])
|
||||
EOT
|
||||
, join(",", formatlist("'%s'", [
|
||||
"roles/accesscontextmanager.policyAdmin",
|
||||
"roles/cloudasset.viewer",
|
||||
"roles/compute.orgFirewallPolicyAdmin",
|
||||
"roles/compute.xpnAdmin",
|
||||
"roles/orgpolicy.policyAdmin",
|
||||
"roles/orgpolicy.policyViewer",
|
||||
"roles/resourcemanager.organizationViewer"
|
||||
]))
|
||||
, join(",", formatlist("'%s'", [
|
||||
module.organization.custom_role_id["network_firewall_policies_admin"],
|
||||
module.organization.custom_role_id["ngfw_enterprise_admin"],
|
||||
module.organization.custom_role_id["service_project_network_admin"],
|
||||
module.organization.custom_role_id["tenant_network_admin"]
|
||||
]))
|
||||
)
|
||||
)
|
||||
title = "automation_sa_delegated_grants"
|
||||
description = "Automation service account delegated grants."
|
||||
|
||||
@@ -236,6 +236,7 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md
|
||||
| [branch-data-platform.tf](./branch-data-platform.tf) | Data Platform stages resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-gcve.tf](./branch-gcve.tf) | GCVE stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-gke.tf](./branch-gke.tf) | GKE multitenant stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-netsec.tf](./branch-netsec.tf) | Network security stage resources. | <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-networking.tf](./branch-networking.tf) | Networking stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-project-factory.tf](./branch-project-factory.tf) | Project factory stage resources. | <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-sandbox.tf](./branch-sandbox.tf) | Sandbox stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
@@ -244,6 +245,7 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md
|
||||
| [cicd-data-platform.tf](./cicd-data-platform.tf) | CI/CD resources for the data platform branch. | <code>iam-service-account</code> | |
|
||||
| [cicd-gcve.tf](./cicd-gcve.tf) | CI/CD resources for the GCVE branch. | <code>iam-service-account</code> | |
|
||||
| [cicd-gke.tf](./cicd-gke.tf) | CI/CD resources for the GKE multitenant branch. | <code>iam-service-account</code> | |
|
||||
| [cicd-netsec.tf](./cicd-netsec.tf) | CI/CD resources for the networking branch. | <code>iam-service-account</code> | |
|
||||
| [cicd-networking.tf](./cicd-networking.tf) | CI/CD resources for the networking branch. | <code>iam-service-account</code> | |
|
||||
| [cicd-project-factory.tf](./cicd-project-factory.tf) | CI/CD resources for the project factories. | <code>iam-service-account</code> | |
|
||||
| [cicd-security.tf](./cicd-security.tf) | CI/CD resources for the security branch. | <code>iam-service-account</code> | |
|
||||
@@ -265,35 +267,35 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables-fast.tf#L19) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string project_id = string project_number = string federated_identity_pool = string federated_identity_providers = map(object({ audiences = list(string) issuer = string issuer_uri = string name = string principal_branch = string principal_repo = string })) service_accounts = object({ resman-r = string }) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables-fast.tf#L42) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | <code title="object({ id = string is_org_level = optional(bool, true) no_iam = optional(bool, false) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [logging](variables-fast.tf#L93) | Logging configuration for tenants. | <code title="object({ project_id = string log_sinks = optional(map(object({ filter = string type = string })), {}) })">object({…})</code> | ✓ | | <code>1-tenant-factory</code> |
|
||||
| [organization](variables-fast.tf#L106) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables-fast.tf#L124) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [cicd_repositories](variables.tf#L20) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object({ data_platform_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) data_platform_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gke_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gke_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gcve_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gcve_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) networking = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) security = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object({ gcve_network_admin = string organization_admin_viewer = string service_project_network_admin = string storage_viewer = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [factories_config](variables.tf#L116) | Configuration for the resource factories or external data. | <code title="object({ checklist_data = optional(string) org_policies = optional(string, "data/org-policies") top_level_folders = optional(string) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L127) | Selective control for top-level FAST features. | <code title="object({ data_platform = optional(bool, false) gke = optional(bool, false) gcve = optional(bool, false) project_factory = optional(bool, false) sandbox = optional(bool, false) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [folder_iam](variables.tf#L140) | Authoritative IAM for top-level folders. | <code title="object({ data_platform = optional(map(list(string)), {}) gcve = optional(map(list(string)), {}) gke = optional(map(list(string)), {}) sandbox = optional(map(list(string)), {}) security = optional(map(list(string)), {}) network = optional(map(list(string)), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [groups](variables-fast.tf#L65) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-vpc-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [locations](variables-fast.tf#L80) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = optional(string, "EU") gcs = optional(string, "EU") logging = optional(string, "global") pubsub = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L154) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [root_node](variables-fast.tf#L130) | Root node for the hierarchy, if running in tenant mode. | <code>string</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [tag_names](variables.tf#L160) | Customized names for resource management tags. | <code title="object({ context = optional(string, "context") environment = optional(string, "environment") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [tags](variables.tf#L174) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [top_level_folders](variables.tf#L195) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | <code title="map(object({ name = string automation = optional(object({ enable = optional(bool, true) sa_impersonation_principals = optional(list(string), []) }), {}) contacts = optional(map(list(string)), {}) firewall_policy = optional(object({ name = string policy = string })) logging_data_access = optional(map(map(list(string))), {}) logging_exclusions = optional(map(string), {}) logging_settings = optional(object({ disable_default_sink = optional(bool) storage_location = optional(string) })) logging_sinks = optional(map(object({ bq_partitioned_table = optional(bool, false) description = optional(string) destination = string disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = optional(string) iam = optional(bool, true) include_children = optional(bool, true) type = 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)), {}) org_policies = optional(map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool) # for boolean policies only. condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }), {}) })), []) })), {}) tag_bindings = optional(map(string), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [logging](variables-fast.tf#L95) | Logging configuration for tenants. | <code title="object({ project_id = string log_sinks = optional(map(object({ filter = string type = string })), {}) })">object({…})</code> | ✓ | | <code>1-tenant-factory</code> |
|
||||
| [organization](variables-fast.tf#L108) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables-fast.tf#L126) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [cicd_repositories](variables.tf#L20) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object({ data_platform_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) data_platform_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gke_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gke_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gcve_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gcve_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) netsec = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) networking = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) security = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object({ gcve_network_admin = string network_firewall_policies_admin = string ngfw_enterprise_admin = string organization_admin_viewer = string service_project_network_admin = string storage_viewer = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [factories_config](variables.tf#L122) | Configuration for the resource factories or external data. | <code title="object({ checklist_data = optional(string) org_policies = optional(string, "data/org-policies") top_level_folders = optional(string) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L133) | Selective control for top-level FAST features. | <code title="object({ data_platform = optional(bool, false) gke = optional(bool, false) gcve = optional(bool, false) project_factory = optional(bool, false) sandbox = optional(bool, false) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [folder_iam](variables.tf#L146) | Authoritative IAM for top-level folders. | <code title="object({ data_platform = optional(map(list(string)), {}) gcve = optional(map(list(string)), {}) gke = optional(map(list(string)), {}) sandbox = optional(map(list(string)), {}) security = optional(map(list(string)), {}) network = optional(map(list(string)), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [groups](variables-fast.tf#L67) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-vpc-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [locations](variables-fast.tf#L82) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = optional(string, "EU") gcs = optional(string, "EU") logging = optional(string, "global") pubsub = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L160) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [root_node](variables-fast.tf#L132) | Root node for the hierarchy, if running in tenant mode. | <code>string</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [tag_names](variables.tf#L166) | Customized names for resource management tags. | <code title="object({ context = optional(string, "context") environment = optional(string, "environment") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [tags](variables.tf#L180) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [top_level_folders](variables.tf#L201) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | <code title="map(object({ name = string automation = optional(object({ enable = optional(bool, true) sa_impersonation_principals = optional(list(string), []) }), {}) contacts = optional(map(list(string)), {}) firewall_policy = optional(object({ name = string policy = string })) logging_data_access = optional(map(map(list(string))), {}) logging_exclusions = optional(map(string), {}) logging_settings = optional(object({ disable_default_sink = optional(bool) storage_location = optional(string) })) logging_sinks = optional(map(object({ bq_partitioned_table = optional(bool, false) description = optional(string) destination = string disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = optional(string) iam = optional(bool, true) include_children = optional(bool, true) type = 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)), {}) org_policies = optional(map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool) # for boolean policies only. condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }), {}) })), []) })), {}) tag_bindings = optional(map(string), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive | consumers |
|
||||
|---|---|:---:|---|
|
||||
| [cicd_repositories](outputs.tf#L377) | WIF configuration for CI/CD repositories. | | |
|
||||
| [dataplatform](outputs.tf#L391) | Data for the Data Platform stage. | | |
|
||||
| [folder_ids](outputs.tf#L407) | Folder ids. | | |
|
||||
| [gcve](outputs.tf#L412) | Data for the GCVE stage. | | <code>03-gcve</code> |
|
||||
| [gke_multitenant](outputs.tf#L433) | Data for the GKE multitenant stage. | | <code>03-gke-multitenant</code> |
|
||||
| [networking](outputs.tf#L454) | Data for the networking stage. | | |
|
||||
| [project_factories](outputs.tf#L463) | Data for the project factories stage. | | |
|
||||
| [providers](outputs.tf#L482) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>03-dataplatform</code> |
|
||||
| [sandbox](outputs.tf#L489) | Data for the sandbox stage. | | <code>xx-sandbox</code> |
|
||||
| [security](outputs.tf#L503) | Data for the networking stage. | | <code>02-security</code> |
|
||||
| [tfvars](outputs.tf#L514) | Terraform variable files for the following stages. | ✓ | |
|
||||
| [cicd_repositories](outputs.tf#L402) | WIF configuration for CI/CD repositories. | | |
|
||||
| [dataplatform](outputs.tf#L416) | Data for the Data Platform stage. | | |
|
||||
| [folder_ids](outputs.tf#L432) | Folder ids. | | |
|
||||
| [gcve](outputs.tf#L437) | Data for the GCVE stage. | | <code>03-gcve</code> |
|
||||
| [gke_multitenant](outputs.tf#L458) | Data for the GKE multitenant stage. | | <code>03-gke-multitenant</code> |
|
||||
| [networking](outputs.tf#L479) | Data for the networking stage. | | |
|
||||
| [project_factories](outputs.tf#L488) | Data for the project factories stage. | | |
|
||||
| [providers](outputs.tf#L507) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>03-dataplatform</code> · <code>03-netsec</code> |
|
||||
| [sandbox](outputs.tf#L514) | Data for the sandbox stage. | | <code>xx-sandbox</code> |
|
||||
| [security](outputs.tf#L528) | Data for the networking stage. | | <code>02-security</code> |
|
||||
| [tfvars](outputs.tf#L539) | Terraform variable files for the following stages. | ✓ | |
|
||||
<!-- END TFDOC -->
|
||||
|
||||
76
fast/stages/1-resman/branch-netsec.tf
Normal file
76
fast/stages/1-resman/branch-netsec.tf
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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 Network security stage resources.
|
||||
|
||||
# automation service account
|
||||
|
||||
module "branch-netsec-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-netsec-0"
|
||||
display_name = "Terraform resman network security service account."
|
||||
prefix = var.prefix
|
||||
service_account_create = var.root_node == null
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = compact([
|
||||
try(module.branch-netsec-sa-cicd[0].iam_email, null)
|
||||
])
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
|
||||
}
|
||||
}
|
||||
|
||||
# automation read-only service account
|
||||
|
||||
module "branch-netsec-r-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-netsec-0r"
|
||||
display_name = "Terraform resman network security service account (read-only)."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = compact([
|
||||
try(module.branch-netsec-r-sa-cicd[0].iam_email, null)
|
||||
])
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = [var.custom_roles["storage_viewer"]]
|
||||
}
|
||||
}
|
||||
|
||||
# automation bucket
|
||||
|
||||
module "branch-netsec-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-netsec-0"
|
||||
prefix = var.prefix
|
||||
location = var.locations.gcs
|
||||
storage_class = local.gcs_storage_class
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-netsec-sa.iam_email]
|
||||
"roles/storage.objectViewer" = [module.branch-netsec-r-sa.iam_email]
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,9 @@ locals {
|
||||
# read-only (plan) automation service account
|
||||
"roles/viewer" = [module.branch-network-r-sa.iam_email]
|
||||
"roles/resourcemanager.folderViewer" = [module.branch-network-r-sa.iam_email]
|
||||
# netsec service account
|
||||
"roles/serviceusage.serviceUsageAdmin" = [module.branch-netsec-sa.iam_email]
|
||||
(var.custom_roles["network_firewall_policies_admin"]) = [module.branch-netsec-sa.iam_email]
|
||||
}
|
||||
# deep-merge FAST-specific IAM with user-provided bindings in var.folder_iam
|
||||
_network_folder_iam = merge(
|
||||
|
||||
85
fast/stages/1-resman/cicd-netsec.tf
Normal file
85
fast/stages/1-resman/cicd-netsec.tf
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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 CI/CD resources for the networking branch.
|
||||
|
||||
# read-write (apply) SA used by CI/CD workflows
|
||||
# to impersonate netsec automation SA
|
||||
|
||||
module "branch-netsec-sa-cicd" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.netsec.name, null) != null
|
||||
? { 0 = local.cicd_repositories.netsec }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-netsec-1"
|
||||
display_name = "Terraform CI/CD stage 2 network security service account."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.workloadIdentityUser" = [
|
||||
each.value.branch == null
|
||||
? format(
|
||||
local.identity_providers[each.value.identity_provider].principal_repo,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name
|
||||
)
|
||||
: format(
|
||||
local.identity_providers[each.value.identity_provider].principal_branch,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name,
|
||||
each.value.branch
|
||||
)
|
||||
]
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/logging.logWriter"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
|
||||
}
|
||||
}
|
||||
|
||||
# read-only (plan) SA used by CI/CD workflows to impersonate netsec automation SA
|
||||
|
||||
module "branch-netsec-r-sa-cicd" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.netsec.name, null) != null
|
||||
? { 0 = local.cicd_repositories.netsec }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-netsec-1r"
|
||||
display_name = "Terraform CI/CD stage 2 network security service account (read-only)."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.workloadIdentityUser" = [
|
||||
format(
|
||||
local.identity_providers[each.value.identity_provider].principal_repo,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name
|
||||
)
|
||||
]
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/logging.logWriter"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,14 @@ locals {
|
||||
member = module.branch-network-sa.iam_email
|
||||
role = "roles/compute.orgFirewallPolicyAdmin"
|
||||
}
|
||||
sa_net_netsec_fw_policy_admin = {
|
||||
member = module.branch-netsec-sa.iam_email
|
||||
role = "roles/compute.orgFirewallPolicyAdmin"
|
||||
}
|
||||
sa_net_netsec_ngfw_enterprise_admin = {
|
||||
member = module.branch-netsec-sa.iam_email
|
||||
role = local.custom_roles["ngfw_enterprise_admin"],
|
||||
}
|
||||
sa_net_xpn_admin = {
|
||||
member = module.branch-network-sa.iam_email
|
||||
role = "roles/compute.xpnAdmin"
|
||||
|
||||
@@ -83,6 +83,17 @@ locals {
|
||||
}
|
||||
tf_var_files = local.cicd_workflow_var_files.stage_3
|
||||
}
|
||||
netsec = {
|
||||
service_accounts = {
|
||||
apply = try(module.branch-netsec-sa-cicd[0].email, null)
|
||||
plan = try(module.branch-netsec-r-sa-cicd[0].email, null)
|
||||
}
|
||||
tf_providers_files = {
|
||||
apply = "3-netsec-providers.tf"
|
||||
plan = "3-netsec-r-providers.tf"
|
||||
}
|
||||
tf_var_files = local.cicd_workflow_var_files.stage_3
|
||||
}
|
||||
networking = {
|
||||
service_accounts = {
|
||||
apply = try(module.branch-network-sa-cicd[0].email, null)
|
||||
@@ -198,6 +209,18 @@ locals {
|
||||
name = "security"
|
||||
sa = module.branch-security-r-sa.email
|
||||
})
|
||||
"3-netsec" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
bucket = module.branch-netsec-gcs.name
|
||||
name = "netsec"
|
||||
sa = module.branch-netsec-sa.email
|
||||
})
|
||||
"3-netsec-r" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
bucket = module.branch-network-gcs.name
|
||||
name = "netsec"
|
||||
sa = module.branch-netsec-r-sa.email
|
||||
})
|
||||
},
|
||||
{
|
||||
for k, v in module.top-level-sa :
|
||||
@@ -347,6 +370,8 @@ locals {
|
||||
gke-dev-r = try(module.branch-gke-dev-r-sa[0].email, null)
|
||||
gke-prod = try(module.branch-gke-prod-sa[0].email, null)
|
||||
gke-prod-r = try(module.branch-gke-prod-r-sa[0].email, null)
|
||||
netsec = module.branch-netsec-sa.email
|
||||
netsec-r = module.branch-netsec-r-sa.email
|
||||
networking = module.branch-network-sa.email
|
||||
networking-r = module.branch-network-r-sa.email
|
||||
project-factory = try(module.branch-pf-sa[0].email, null)
|
||||
@@ -480,7 +505,7 @@ output "project_factories" {
|
||||
|
||||
# ready to use provider configurations for subsequent stages
|
||||
output "providers" {
|
||||
# tfdoc:output:consumers 02-networking 02-security 03-dataplatform
|
||||
# tfdoc:output:consumers 02-networking 02-security 03-dataplatform 03-netsec
|
||||
description = "Terraform provider files for this stage and dependent stages."
|
||||
sensitive = true
|
||||
value = local.providers
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
* 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.
|
||||
|
||||
@@ -54,10 +54,12 @@ variable "custom_roles" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
type = object({
|
||||
gcve_network_admin = string
|
||||
organization_admin_viewer = string
|
||||
service_project_network_admin = string
|
||||
storage_viewer = string
|
||||
gcve_network_admin = string
|
||||
network_firewall_policies_admin = string
|
||||
ngfw_enterprise_admin = string
|
||||
organization_admin_viewer = string
|
||||
service_project_network_admin = string
|
||||
storage_viewer = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
@@ -56,6 +56,12 @@ variable "cicd_repositories" {
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
netsec = optional(object({
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
networking = optional(object({
|
||||
name = string
|
||||
type = string
|
||||
|
||||
@@ -309,13 +309,13 @@ gcloud storage cp gs://{prefix}-{tenant-shortname}-prod-iac-core-0/tfvars/0-boot
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables-fast.tf#L19) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string project_id = string project_number = string federated_identity_pool = string federated_identity_providers = map(object({ audiences = list(string) issuer = string issuer_uri = string name = string principal_branch = string principal_repo = string })) service_accounts = object({ resman = string resman-r = string }) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables-fast.tf#L42) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | <code title="object({ id = string is_org_level = optional(bool, true) no_iam = optional(bool, false) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [logging](variables-fast.tf#L94) | Logging resources created by the bootstrap stage. | <code title="object({ project_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [org_policy_tags](variables-fast.tf#L113) | Organization policy tags. | <code title="object({ key_id = string key_name = string values = map(string) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables-fast.tf#L103) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables-fast.tf#L130) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object({ gcve_network_admin = string organization_admin_viewer = string service_project_network_admin = string storage_viewer = string tenant_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [groups](variables-fast.tf#L66) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-vpc-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [locations](variables-fast.tf#L81) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = optional(string, "EU") gcs = optional(string, "EU") logging = optional(string, "global") pubsub = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [logging](variables-fast.tf#L96) | Logging resources created by the bootstrap stage. | <code title="object({ project_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [org_policy_tags](variables-fast.tf#L115) | Organization policy tags. | <code title="object({ key_id = string key_name = string values = map(string) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables-fast.tf#L105) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables-fast.tf#L132) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object({ gcve_network_admin = string network_firewall_policies_admin = string ngfw_enterprise_admin = string organization_admin_viewer = string service_project_network_admin = string storage_viewer = string tenant_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [groups](variables-fast.tf#L68) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-vpc-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [locations](variables-fast.tf#L83) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = optional(string, "EU") gcs = optional(string, "EU") logging = optional(string, "global") pubsub = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L17) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [root_node](variables.tf#L23) | Root folder under which tenants are created, in folders/nnnn format. Defaults to the organization if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [tag_names](variables.tf#L36) | Customized names for resource management tags. | <code title="object({ tenant = optional(string, "tenant") })">object({…})</code> | | <code>{}</code> | |
|
||||
|
||||
@@ -54,11 +54,13 @@ variable "custom_roles" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
type = object({
|
||||
gcve_network_admin = string
|
||||
organization_admin_viewer = string
|
||||
service_project_network_admin = string
|
||||
storage_viewer = string
|
||||
tenant_network_admin = string
|
||||
gcve_network_admin = string
|
||||
network_firewall_policies_admin = string
|
||||
ngfw_enterprise_admin = string
|
||||
organization_admin_viewer = string
|
||||
service_project_network_admin = string
|
||||
storage_viewer = string
|
||||
tenant_network_admin = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ module "dev-spoke-project" {
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
|
||||
@@ -29,6 +29,7 @@ module "prod-spoke-project" {
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2023 Google LLC
|
||||
* 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.
|
||||
@@ -28,6 +28,7 @@ module "dev-spoke-project" {
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2023 Google LLC
|
||||
* 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.
|
||||
@@ -28,6 +28,7 @@ module "prod-spoke-project" {
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
|
||||
@@ -28,6 +28,7 @@ module "dev-spoke-project" {
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
|
||||
@@ -28,6 +28,7 @@ module "prod-spoke-project" {
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"networksecurity.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
|
||||
172
fast/stages/3-network-security/README.md
Normal file
172
fast/stages/3-network-security/README.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Network Security
|
||||
|
||||
This stage enables NGFW Enterprise in the dev `dev` and `prod` VPCs. This includes:
|
||||
|
||||
- security profiles
|
||||
- security profile groups
|
||||
- NGFW endpoints
|
||||
- NGFW endpoint associations
|
||||
- global network firewall policies and some recommended firewall policy rules
|
||||
|
||||
The following diagram is a high level reference of the resources created and managed here (excludes projects and VPCs):
|
||||
|
||||
<p align="center">
|
||||
<img src="diagram.png" alt="Network security NGFW diagram">
|
||||
</p>
|
||||
|
||||
<!-- BEGIN TOC -->
|
||||
- [Design overview and choices](#design-overview-and-choices)
|
||||
- [How to run this stage](#how-to-run-this-stage)
|
||||
- [Provider and Terraform variables](#provider-and-terraform-variables)
|
||||
- [Impersonating the automation service account](#impersonating-the-automation-service-account)
|
||||
- [Variable configuration](#variable-configuration)
|
||||
- [Running the stage](#running-the-stage)
|
||||
- [Customizations](#customizations)
|
||||
- [Firewall policy rules factories](#firewall-policy-rules-factories)
|
||||
- [NGFW Enterprise configuration](#ngfw-enterprise-configuration)
|
||||
- [Files](#files)
|
||||
- [Variables](#variables)
|
||||
- [Outputs](#outputs)
|
||||
<!-- END TOC -->
|
||||
|
||||
## Design overview and choices
|
||||
|
||||
- We create one security profile (and security profile group) per environment in the spoke VPCs only. That's usually where inspection is needed, as it's where workloads run.
|
||||
- By default, we create NGFW Enterprise endpoints in three zones in the default, primary region (europe-west1). You can adapt this, depending on where your workloads run, using the dedicated variable.
|
||||
- We install default firewall policy rules in each spoke, so that we allow and inspect all traffic going to the Internet and we allow egress towards RFC-1918 addresses. In ingress, you'll need to add your own rules. We provided some examples that need to be adapted to your topology (number of regions, subnets).
|
||||
- We use global network firewall policies, as legacy VPC firewall rules are not compatible with NGFW Enterprise. These policies coexist with the legacy VPC firewall rules that we create in the netwroking stage.
|
||||
- For your convenience, firewall policy rules leverage factories, so that you can define firewall policy rules using yaml files. The path of these files is configurable. Look in the [Customization](#customizations) section for more details.
|
||||
- NGFW Enterprise endpoints are org-level resources that need to reference a quota project for billing purposes. By default, we create a dedicated `xxx-net-ngfw-0` quota project. Anyway, you can choose to leverage an existing project. Look in the [Customization](#customizations) section for more details.
|
||||
|
||||
## How to run this stage
|
||||
|
||||
This stage is meant to be executed after any [networking](../2-networking-a-simple) stage has run and it leverages dedicated automation service accounts and a bucket created in the [resman](../1-resman) stage.
|
||||
|
||||
It's to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the bootstrap and resman stages for the roles needed.
|
||||
|
||||
Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration.
|
||||
|
||||
### Provider and Terraform variables
|
||||
|
||||
As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here.
|
||||
|
||||
The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run.
|
||||
|
||||
```bash
|
||||
../../stage-links.sh ~/fast-config
|
||||
|
||||
# copy and paste the following commands for '3-network-security'
|
||||
|
||||
ln -s ~/fast-config/providers/3-netsec-providers.tf ./
|
||||
ln -s ~/fast-config/tfvars/0-globals.auto.tfvars.json ./
|
||||
ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./
|
||||
ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./
|
||||
ln -s ~/fast-config/tfvars/2-networking.auto.tfvars.json ./
|
||||
```
|
||||
|
||||
```bash
|
||||
../../stage-links.sh gs://xxx-prod-iac-core-outputs-0
|
||||
|
||||
# copy and paste the following commands for '3-network-security'
|
||||
|
||||
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/providers/3-netsec-providers.tf ./
|
||||
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-globals.auto.tfvars.json ./
|
||||
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./
|
||||
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./
|
||||
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-networking.auto.tfvars.json ./
|
||||
```
|
||||
|
||||
### Impersonating the automation service account
|
||||
|
||||
The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups.
|
||||
|
||||
### Variable configuration
|
||||
|
||||
Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets:
|
||||
|
||||
- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `0-globals.auto.tfvars.json` file linked or copied above
|
||||
- variables which refer to resources managed by previous stages, which are prepopulated here via the `0-bootstrap.auto.tfvars.json`, `1-resman.auto.tfvars.json` and `2-networking.auto.tfvars.json` files linked or copied above
|
||||
- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file
|
||||
|
||||
The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document.
|
||||
|
||||
Note that the `outputs_location` variable is disabled by default, you need to explicitly set it in your `terraform.tfvars` file if you want output files to be generated by this stage. This is a sample `terraform.tfvars` that configures it, refer to the [bootstrap stage documentation](../0-bootstrap/README.md#output-files-and-cross-stage-variables) for more details:
|
||||
|
||||
```tfvars
|
||||
outputs_location = "~/fast-config"
|
||||
```
|
||||
|
||||
### Running the stage
|
||||
|
||||
Once provider and variable values are in place and the correct user is configured, the stage can be run:
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Customizations
|
||||
|
||||
You can optionally customize a few options adding a `terraform.tfvars` file to this stage.
|
||||
|
||||
### Firewall policy rules factories
|
||||
|
||||
By default, firewall policy rules yaml files are contained in the `data` folder within this module. Anyway, you can customize this location.
|
||||
|
||||
### NGFW Enterprise configuration
|
||||
|
||||
You can decide the zones where to deploy the NGFW Enterprise endpoints. These are set by default to `europe-west1-b`, `europe-west1-c` and `europe-west1-d`.
|
||||
|
||||
```tfvars
|
||||
ngfw_enterprise_config = {
|
||||
endpoint_zones = [
|
||||
"us-east4-a",
|
||||
"us-east4-b",
|
||||
"australia-southeast1-b",
|
||||
"australia-southeast1-c"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Instead of creating a dedicated NGFW Enterprise billing/quota project, you can choose to leverage an existing project. These can even be one of your existing networking projects.
|
||||
You'll need to make sure your network security service account can activate the `networksecurity.googleapis.com` on that project (for example, assigning the `roles/serviceusage.serviceUsageAdmin` role).
|
||||
|
||||
```tfvars
|
||||
ngfw_enterprise_config = {
|
||||
quota_project_id = "your-quota-project-id"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- TFDOC OPTS files:1 show_extra:1 -->
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Files
|
||||
|
||||
| name | description | modules | resources |
|
||||
|---|---|---|---|
|
||||
| [main.tf](./main.tf) | Next-Generation Firewall Enterprise configuration. | <code>project</code> | <code>google_network_security_firewall_endpoint</code> |
|
||||
| [net-dev.tf](./net-dev.tf) | Security components for dev spoke VPC. | <code>net-firewall-policy</code> | <code>google_network_security_firewall_endpoint_association</code> · <code>google_network_security_security_profile</code> · <code>google_network_security_security_profile_group</code> |
|
||||
| [net-prod.tf](./net-prod.tf) | Security components for prod spoke VPC. | <code>net-firewall-policy</code> | <code>google_network_security_firewall_endpoint_association</code> · <code>google_network_security_security_profile</code> · <code>google_network_security_security_profile_group</code> |
|
||||
| [outputs.tf](./outputs.tf) | Module outputs. | | |
|
||||
| [variables-fast.tf](./variables-fast.tf) | None | | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default | producer |
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [billing_account](variables-fast.tf#L17) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables-fast.tf#L30) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables-fast.tf#L52) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-globals</code> |
|
||||
| [prefix](variables-fast.tf#L62) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [vpc_self_links](variables-fast.tf#L72) | Self link for the shared VPC. | <code title="object({ dev-spoke-0 = string prod-spoke-0 = string })">object({…})</code> | ✓ | | <code>2-networking</code> |
|
||||
| [factories_config](variables.tf#L17) | Configuration for network resource factories. | <code title="object({ cidrs = optional(string, "data/cidrs.yaml") firewall_policy_rules = optional(object({ dev = string prod = string })) })">object({…})</code> | | <code title="{ firewall_policy_rules = { dev = "data/firewall-policy-rules/dev" prod = "data/firewall-policy-rules/prod" } }">{…}</code> | |
|
||||
| [host_project_ids](variables-fast.tf#L41) | Host project for the shared VPC. | <code title="object({ dev-spoke-0 = optional(string) prod-spoke-0 = optional(string) })">object({…})</code> | | <code>{}</code> | <code>2-networking</code> |
|
||||
| [ngfw_enterprise_config](variables.tf#L35) | NGFW Enterprise configuration. | <code title="object({ endpoint_zones = list(string) quota_project_id = optional(string, null) })">object({…})</code> | | <code title="{ endpoint_zones = [ "europe-west1-b", "europe-west1-c", "europe-west1-d" ] }">{…}</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive | consumers |
|
||||
|---|---|:---:|---|
|
||||
| [ngfw_enterprise_endpoint_ids](outputs.tf#L17) | The NGFW Enterprise endpoint ids. | | |
|
||||
| [ngfw_enterprise_endpoints_quota_project](outputs.tf#L25) | The NGFW Enterprise endpoints quota project. | | |
|
||||
<!-- END TFDOC -->
|
||||
18
fast/stages/3-network-security/data/cidrs.yaml
Normal file
18
fast/stages/3-network-security/data/cidrs.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# skip boilerplate check
|
||||
---
|
||||
# Terraform will be unable to decode this file if it does not contain valid YAML
|
||||
# You can retain `---` (start of the document) to indicate an empty document.
|
||||
|
||||
healthchecks:
|
||||
- 35.191.0.0/16
|
||||
- 130.211.0.0/22
|
||||
- 209.85.152.0/22
|
||||
- 209.85.204.0/22
|
||||
|
||||
rfc1918:
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
|
||||
onprem_probes:
|
||||
- 10.255.255.254/32
|
||||
@@ -0,0 +1,18 @@
|
||||
# skip boilerplate check
|
||||
---
|
||||
egress-allow-rfc1918:
|
||||
description: "Allow all hosts to RFC-1918"
|
||||
priority: 2147483546
|
||||
match:
|
||||
destination_ranges:
|
||||
- rfc1918
|
||||
action: "allow"
|
||||
|
||||
egress-inspect-internet:
|
||||
description: "Inspect egress traffic from all dev hosts to Internet"
|
||||
priority: 2147483547
|
||||
match:
|
||||
destination_ranges:
|
||||
- "0.0.0.0/0"
|
||||
action: "apply_security_profile_group"
|
||||
security_profile_group: "dev"
|
||||
@@ -0,0 +1,21 @@
|
||||
# skip boilerplate check
|
||||
---
|
||||
# Following are some NGFW Enterprise ingress rules examples
|
||||
|
||||
# ingress-allow-inspect-cross:
|
||||
# description: "Allow and inspect cross-env traffic from prod."
|
||||
# priority: 1
|
||||
# match:
|
||||
# source_ranges:
|
||||
# - prod (to be defined)
|
||||
# action: "apply_security_profile_group"
|
||||
# security_profile_group: "dev"
|
||||
|
||||
# ingress-allow-inspect-intra:
|
||||
# description: "Allow and inspect same-env (intra-vpc) traffic."
|
||||
# priority: 2
|
||||
# match:
|
||||
# source_ranges:
|
||||
# - dev (to be defined)
|
||||
# action: "apply_security_profile_group"
|
||||
# security_profile_group: "dev"
|
||||
@@ -0,0 +1,18 @@
|
||||
# skip boilerplate check
|
||||
---
|
||||
egress-allow-rfc1918:
|
||||
description: "Allow all hosts to RFC-1918"
|
||||
priority: 2147483546
|
||||
match:
|
||||
destination_ranges:
|
||||
- rfc1918
|
||||
action: "allow"
|
||||
|
||||
egress-inspect-internet:
|
||||
description: "Inspect egress traffic from all prod hosts to Internet"
|
||||
priority: 2147483547
|
||||
match:
|
||||
destination_ranges:
|
||||
- "0.0.0.0/0"
|
||||
action: "apply_security_profile_group"
|
||||
security_profile_group: "prod"
|
||||
@@ -0,0 +1,21 @@
|
||||
# skip boilerplate check
|
||||
---
|
||||
# Following are some NGFW Enterprise ingress rules examples
|
||||
|
||||
# ingress-allow-inspect-cross:
|
||||
# description: "Allow and inspect cross-env traffic."
|
||||
# priority: 1
|
||||
# match:
|
||||
# source_ranges:
|
||||
# - dev (to be defined)
|
||||
# action: "apply_security_profile_group"
|
||||
# security_profile_group: "prod"
|
||||
|
||||
# ingress-allow-inspect-intra:
|
||||
# description: "Allow and inspect intra-VPC traffic."
|
||||
# priority: 2
|
||||
# match:
|
||||
# source_ranges:
|
||||
# - prod (to be defined)
|
||||
# action: "apply_security_profile_group"
|
||||
# security_profile_group: "prod"
|
||||
BIN
fast/stages/3-network-security/diagram.png
Normal file
BIN
fast/stages/3-network-security/diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
1
fast/stages/3-network-security/diagram.svg
Normal file
1
fast/stages/3-network-security/diagram.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 473 KiB |
68
fast/stages/3-network-security/main.tf
Normal file
68
fast/stages/3-network-security/main.tf
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 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 Next-Generation Firewall Enterprise configuration.
|
||||
|
||||
locals {
|
||||
create_quota_project = (
|
||||
var.ngfw_enterprise_config.quota_project_id == null
|
||||
? true
|
||||
: false
|
||||
)
|
||||
vpc_ids = {
|
||||
for k, v in var.vpc_self_links
|
||||
: k => replace(v, "https://www.googleapis.com/compute/v1/", "")
|
||||
}
|
||||
}
|
||||
|
||||
# Dedicated quota project for ngfw enterprise endpoints
|
||||
module "ngfw-quota-project" {
|
||||
source = "../../../modules/project"
|
||||
name = (
|
||||
local.create_quota_project
|
||||
? "net-ngfw-0"
|
||||
: var.ngfw_enterprise_config.quota_project_id
|
||||
)
|
||||
billing_account = (
|
||||
local.create_quota_project
|
||||
? var.billing_account.id
|
||||
: null
|
||||
)
|
||||
parent = (
|
||||
local.create_quota_project
|
||||
? var.folder_ids.networking
|
||||
: null
|
||||
)
|
||||
prefix = (
|
||||
local.create_quota_project
|
||||
? var.prefix
|
||||
: null
|
||||
)
|
||||
project_create = (
|
||||
local.create_quota_project
|
||||
? true
|
||||
: false
|
||||
)
|
||||
services = ["networksecurity.googleapis.com"]
|
||||
}
|
||||
|
||||
resource "google_network_security_firewall_endpoint" "firewall_endpoint" {
|
||||
for_each = toset(var.ngfw_enterprise_config.endpoint_zones)
|
||||
name = "${var.prefix}-ngfw-endpoint-${each.key}"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
location = each.value
|
||||
billing_project_id = module.ngfw-quota-project.id
|
||||
}
|
||||
59
fast/stages/3-network-security/net-dev.tf
Normal file
59
fast/stages/3-network-security/net-dev.tf
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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 Security components for dev spoke VPC.
|
||||
|
||||
resource "google_network_security_security_profile" "dev_sec_profile" {
|
||||
name = "${var.prefix}-dev-sp-0"
|
||||
type = "THREAT_PREVENTION"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
location = "global"
|
||||
}
|
||||
|
||||
resource "google_network_security_security_profile_group" "dev_sec_profile_group" {
|
||||
name = "${var.prefix}-dev-spg-0"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
location = "global"
|
||||
description = "Dev security profile group."
|
||||
threat_prevention_profile = try(google_network_security_security_profile.dev_sec_profile.id, null)
|
||||
}
|
||||
|
||||
resource "google_network_security_firewall_endpoint_association" "dev_fw_ep_association" {
|
||||
for_each = toset(var.ngfw_enterprise_config.endpoint_zones)
|
||||
name = "${var.prefix}-dev-epa-${each.key}"
|
||||
parent = "projects/${try(var.host_project_ids.dev-spoke-0, null)}"
|
||||
location = each.value
|
||||
firewall_endpoint = google_network_security_firewall_endpoint.firewall_endpoint[each.key].id
|
||||
network = try(local.vpc_ids.dev-spoke-0, null)
|
||||
}
|
||||
|
||||
module "dev-spoke-firewall-policy" {
|
||||
source = "../../../modules/net-firewall-policy"
|
||||
name = "${var.prefix}-dev-fw-policy"
|
||||
parent_id = try(var.host_project_ids.dev-spoke-0, null)
|
||||
region = "global"
|
||||
security_profile_group_ids = {
|
||||
dev = "//networksecurity.googleapis.com/${try(google_network_security_security_profile_group.dev_sec_profile_group.id, "")}"
|
||||
}
|
||||
attachments = {
|
||||
dev-spoke = try(var.vpc_self_links.dev-spoke-0, null)
|
||||
}
|
||||
factories_config = {
|
||||
cidr_file_path = var.factories_config.cidrs
|
||||
egress_rules_file_path = "${var.factories_config.firewall_policy_rules.dev}/egress.yaml"
|
||||
ingress_rules_file_path = "${var.factories_config.firewall_policy_rules.dev}/ingress.yaml"
|
||||
}
|
||||
}
|
||||
59
fast/stages/3-network-security/net-prod.tf
Normal file
59
fast/stages/3-network-security/net-prod.tf
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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 Security components for prod spoke VPC.
|
||||
|
||||
resource "google_network_security_security_profile" "prod_sec_profile" {
|
||||
name = "${var.prefix}-prod-sp-0"
|
||||
type = "THREAT_PREVENTION"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
location = "global"
|
||||
}
|
||||
|
||||
resource "google_network_security_security_profile_group" "prod_sec_profile_group" {
|
||||
name = "${var.prefix}-prod-spg-0"
|
||||
parent = "organizations/${var.organization.id}"
|
||||
location = "global"
|
||||
description = "prod security profile group."
|
||||
threat_prevention_profile = try(google_network_security_security_profile.prod_sec_profile.id, null)
|
||||
}
|
||||
|
||||
resource "google_network_security_firewall_endpoint_association" "prod_fw_ep_association" {
|
||||
for_each = toset(var.ngfw_enterprise_config.endpoint_zones)
|
||||
name = "${var.prefix}-prod-epa-${each.key}"
|
||||
parent = "projects/${try(var.host_project_ids.prod-spoke-0, null)}"
|
||||
location = each.value
|
||||
firewall_endpoint = google_network_security_firewall_endpoint.firewall_endpoint[each.key].id
|
||||
network = try(local.vpc_ids.prod-spoke-0, null)
|
||||
}
|
||||
|
||||
module "prod-spoke-firewall-policy" {
|
||||
source = "../../../modules/net-firewall-policy"
|
||||
name = "${var.prefix}-prod-fw-policy"
|
||||
parent_id = try(var.host_project_ids.prod-spoke-0, null)
|
||||
region = "global"
|
||||
security_profile_group_ids = {
|
||||
prod = "//networksecurity.googleapis.com/${try(google_network_security_security_profile_group.prod_sec_profile_group.id, "")}"
|
||||
}
|
||||
attachments = {
|
||||
prod-spoke = try(var.vpc_self_links.prod-spoke-0, null)
|
||||
}
|
||||
factories_config = {
|
||||
cidr_file_path = var.factories_config.cidrs
|
||||
egress_rules_file_path = "${var.factories_config.firewall_policy_rules.prod}/egress.yaml"
|
||||
ingress_rules_file_path = "${var.factories_config.firewall_policy_rules.prod}/ingress.yaml"
|
||||
}
|
||||
}
|
||||
28
fast/stages/3-network-security/outputs.tf
Normal file
28
fast/stages/3-network-security/outputs.tf
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
output "ngfw_enterprise_endpoint_ids" {
|
||||
description = "The NGFW Enterprise endpoint ids."
|
||||
value = {
|
||||
for _, v in google_network_security_firewall_endpoint.firewall_endpoint
|
||||
: v.location => v.id
|
||||
}
|
||||
}
|
||||
|
||||
output "ngfw_enterprise_endpoints_quota_project" {
|
||||
description = "The NGFW Enterprise endpoints quota project."
|
||||
value = module.ngfw-quota-project.id
|
||||
}
|
||||
80
fast/stages/3-network-security/variables-fast.tf
Normal file
80
fast/stages/3-network-security/variables-fast.tf
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
variable "billing_account" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Billing account id. If billing account is not part of the same org set `is_org_level` to false."
|
||||
type = object({
|
||||
id = string
|
||||
is_org_level = optional(bool, true)
|
||||
})
|
||||
validation {
|
||||
condition = var.billing_account.is_org_level != null
|
||||
error_message = "Invalid `null` value for `billing_account.is_org_level`."
|
||||
}
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
type = object({
|
||||
networking = string
|
||||
networking-dev = string
|
||||
networking-prod = string
|
||||
})
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "host_project_ids" {
|
||||
# tfdoc:variable:source 2-networking
|
||||
description = "Host project for the shared VPC."
|
||||
type = object({
|
||||
dev-spoke-0 = optional(string)
|
||||
prod-spoke-0 = optional(string)
|
||||
})
|
||||
nullable = false
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
# tfdoc:variable:source 00-globals
|
||||
description = "Organization details."
|
||||
type = object({
|
||||
domain = string
|
||||
id = number
|
||||
customer_id = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants."
|
||||
type = string
|
||||
validation {
|
||||
condition = try(length(var.prefix), 0) < 12
|
||||
error_message = "Use a maximum of 9 chars for organizations, and 11 chars for tenants."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vpc_self_links" {
|
||||
# tfdoc:variable:source 2-networking
|
||||
description = "Self link for the shared VPC."
|
||||
type = object({
|
||||
dev-spoke-0 = string
|
||||
prod-spoke-0 = string
|
||||
})
|
||||
nullable = false
|
||||
}
|
||||
49
fast/stages/3-network-security/variables.tf
Normal file
49
fast/stages/3-network-security/variables.tf
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
variable "factories_config" {
|
||||
description = "Configuration for network resource factories."
|
||||
type = object({
|
||||
cidrs = optional(string, "data/cidrs.yaml")
|
||||
firewall_policy_rules = optional(object({
|
||||
dev = string
|
||||
prod = string
|
||||
}))
|
||||
})
|
||||
nullable = false
|
||||
default = {
|
||||
firewall_policy_rules = {
|
||||
dev = "data/firewall-policy-rules/dev"
|
||||
prod = "data/firewall-policy-rules/prod"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "ngfw_enterprise_config" {
|
||||
description = "NGFW Enterprise configuration."
|
||||
type = object({
|
||||
endpoint_zones = list(string)
|
||||
quota_project_id = optional(string, null)
|
||||
})
|
||||
nullable = false
|
||||
default = {
|
||||
endpoint_zones = [
|
||||
"europe-west1-b",
|
||||
"europe-west1-c",
|
||||
"europe-west1-d"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -201,7 +201,10 @@ values:
|
||||
module.organization.google_organization_iam_binding.bindings["organization_iam_admin_conditional"]:
|
||||
condition:
|
||||
- description: Automation service account delegated grants.
|
||||
expression: api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/accesscontextmanager.policyAdmin','roles/cloudasset.viewer','roles/compute.orgFirewallPolicyAdmin','roles/compute.xpnAdmin','roles/orgpolicy.policyAdmin','roles/orgpolicy.policyViewer','roles/resourcemanager.organizationViewer','organizations/123456789012/roles/serviceProjectNetworkAdmin','organizations/123456789012/roles/tenantNetworkAdmin'])
|
||||
expression: |
|
||||
api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/accesscontextmanager.policyAdmin','roles/cloudasset.viewer','roles/compute.orgFirewallPolicyAdmin','roles/compute.xpnAdmin','roles/orgpolicy.policyAdmin','roles/orgpolicy.policyViewer','roles/resourcemanager.organizationViewer'])
|
||||
|| api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['organizations/123456789012/roles/networkFirewallPoliciesAdmin','organizations/123456789012/roles/ngfwEnterpriseAdmin','organizations/123456789012/roles/serviceProjectNetworkAdmin','organizations/123456789012/roles/tenantNetworkAdmin'])
|
||||
|
||||
title: automation_sa_delegated_grants
|
||||
members:
|
||||
- serviceAccount:fast-prod-resman-0@fast-prod-iac-core-0.iam.gserviceaccount.com
|
||||
@@ -376,15 +379,15 @@ counts:
|
||||
google_logging_organization_sink: 4
|
||||
google_logging_project_bucket_config: 4
|
||||
google_org_policy_policy: 22
|
||||
google_organization_iam_binding: 28
|
||||
google_organization_iam_custom_role: 7
|
||||
google_organization_iam_binding: 29
|
||||
google_organization_iam_custom_role: 9
|
||||
google_organization_iam_member: 41
|
||||
google_project: 3
|
||||
google_project_iam_audit_config: 1
|
||||
google_project_iam_binding: 19
|
||||
google_project_iam_member: 16
|
||||
google_project_service: 30
|
||||
google_project_service_identity: 6
|
||||
google_project_service: 31
|
||||
google_project_service_identity: 7
|
||||
google_service_account: 6
|
||||
google_service_account_iam_binding: 2
|
||||
google_service_account_iam_member: 1
|
||||
@@ -396,4 +399,4 @@ counts:
|
||||
google_tags_tag_key: 1
|
||||
google_tags_tag_value: 1
|
||||
modules: 21
|
||||
resources: 230
|
||||
resources: 235
|
||||
|
||||
@@ -20,15 +20,15 @@ counts:
|
||||
google_logging_organization_sink: 4
|
||||
google_logging_project_bucket_config: 4
|
||||
google_org_policy_policy: 22
|
||||
google_organization_iam_binding: 28
|
||||
google_organization_iam_custom_role: 7
|
||||
google_organization_iam_binding: 29
|
||||
google_organization_iam_custom_role: 9
|
||||
google_organization_iam_member: 28
|
||||
google_project: 3
|
||||
google_project_iam_audit_config: 1
|
||||
google_project_iam_binding: 19
|
||||
google_project_iam_member: 16
|
||||
google_project_service: 30
|
||||
google_project_service_identity: 6
|
||||
google_project_service: 31
|
||||
google_project_service_identity: 7
|
||||
google_service_account: 6
|
||||
google_service_account_iam_binding: 2
|
||||
google_service_account_iam_member: 1
|
||||
@@ -41,11 +41,16 @@ counts:
|
||||
google_tags_tag_value: 1
|
||||
local_file: 10
|
||||
modules: 20
|
||||
resources: 224
|
||||
resources: 229
|
||||
|
||||
outputs:
|
||||
automation: __missing__
|
||||
billing_dataset: __missing__
|
||||
cicd_repositories: {}
|
||||
custom_roles:
|
||||
gcve_network_admin: organizations/123456789012/roles/gcveNetworkAdmin
|
||||
network_firewall_policies_admin: organizations/123456789012/roles/networkFirewallPoliciesAdmin
|
||||
ngfw_enterprise_admin: organizations/123456789012/roles/ngfwEnterpriseAdmin
|
||||
organization_admin_viewer: organizations/123456789012/roles/organizationAdminViewer
|
||||
organization_iam_admin: organizations/123456789012/roles/organizationIamAdmin
|
||||
service_project_network_admin: organizations/123456789012/roles/serviceProjectNetworkAdmin
|
||||
@@ -66,4 +71,3 @@ outputs:
|
||||
workload_identity_pool:
|
||||
pool: null
|
||||
providers: {}
|
||||
|
||||
|
||||
@@ -13,10 +13,12 @@ billing_account = {
|
||||
}
|
||||
custom_roles = {
|
||||
# organization_iam_admin = "organizations/123456789012/roles/organizationIamAdmin",
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
organization_admin_viewer = "organizations/123456789012/roles/organizationAdminViewer"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
network_firewall_policies_admin = "organizations/123456789012/roles/networkFirewallPoliciesAdmin"
|
||||
ngfw_enterprise_admin = "organizations/123456789012/roles/ngfwEnterpriseAdmin"
|
||||
organization_admin_viewer = "organizations/123456789012/roles/organizationAdminViewer"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
}
|
||||
factories_config = {
|
||||
checklist_data = "checklist-data.json"
|
||||
|
||||
@@ -416,17 +416,17 @@ values:
|
||||
|
||||
counts:
|
||||
google_folder: 56
|
||||
google_folder_iam_binding: 69
|
||||
google_organization_iam_member: 6
|
||||
google_project_iam_member: 4
|
||||
google_service_account: 4
|
||||
google_service_account_iam_binding: 4
|
||||
google_storage_bucket: 2
|
||||
google_storage_bucket_iam_binding: 4
|
||||
google_storage_bucket_iam_member: 4
|
||||
google_storage_bucket_object: 5
|
||||
google_folder_iam_binding: 71
|
||||
google_organization_iam_member: 8
|
||||
google_project_iam_member: 6
|
||||
google_service_account: 6
|
||||
google_service_account_iam_binding: 6
|
||||
google_storage_bucket: 3
|
||||
google_storage_bucket_iam_binding: 6
|
||||
google_storage_bucket_iam_member: 6
|
||||
google_storage_bucket_object: 7
|
||||
google_tags_tag_binding: 4
|
||||
google_tags_tag_key: 2
|
||||
google_tags_tag_value: 9
|
||||
modules: 63
|
||||
resources: 173
|
||||
modules: 66
|
||||
resources: 190
|
||||
|
||||
@@ -13,10 +13,12 @@ billing_account = {
|
||||
}
|
||||
custom_roles = {
|
||||
# organization_iam_admin = "organizations/123456789012/roles/organizationIamAdmin",
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
organization_admin_viewer = "organizations/123456789012/roles/organizationAdminViewer"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
network_firewall_policies_admin = "organizations/123456789012/roles/networkFirewallPoliciesAdmin"
|
||||
ngfw_enterprise_admin = "organizations/123456789012/roles/ngfwEnterpriseAdmin"
|
||||
organization_admin_viewer = "organizations/123456789012/roles/organizationAdminViewer"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
}
|
||||
groups = {
|
||||
gcp-billing-admins = "gcp-billing-admins",
|
||||
|
||||
@@ -14,17 +14,17 @@
|
||||
|
||||
counts:
|
||||
google_folder: 4
|
||||
google_folder_iam_binding: 23
|
||||
google_organization_iam_member: 6
|
||||
google_project_iam_member: 4
|
||||
google_service_account: 4
|
||||
google_service_account_iam_binding: 4
|
||||
google_storage_bucket: 2
|
||||
google_storage_bucket_iam_binding: 4
|
||||
google_storage_bucket_iam_member: 4
|
||||
google_storage_bucket_object: 5
|
||||
google_folder_iam_binding: 25
|
||||
google_organization_iam_member: 8
|
||||
google_project_iam_member: 6
|
||||
google_service_account: 6
|
||||
google_service_account_iam_binding: 6
|
||||
google_storage_bucket: 3
|
||||
google_storage_bucket_iam_binding: 6
|
||||
google_storage_bucket_iam_member: 6
|
||||
google_storage_bucket_object: 7
|
||||
google_tags_tag_binding: 4
|
||||
google_tags_tag_key: 2
|
||||
google_tags_tag_value: 9
|
||||
modules: 11
|
||||
resources: 75
|
||||
modules: 14
|
||||
resources: 92
|
||||
|
||||
@@ -14,11 +14,13 @@ billing_account = {
|
||||
}
|
||||
custom_roles = {
|
||||
# organization_iam_admin = "organizations/123456789012/roles/organizationIamAdmin",
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
organization_admin_viewer = "organizations/123456789012/roles/organizationAdminViewer"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
tenant_network_admin = "organizations/123456789012/roles/tenantNetworkAdmin"
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
network_firewall_policies_admin = "organizations/123456789012/roles/networkFirewallPoliciesAdmin"
|
||||
ngfw_enterprise_admin = "organizations/123456789012/roles/ngfwEnterpriseAdmin"
|
||||
organization_admin_viewer = "organizations/123456789012/roles/organizationAdminViewer"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
tenant_network_admin = "organizations/123456789012/roles/tenantNetworkAdmin"
|
||||
}
|
||||
groups = {
|
||||
gcp-billing-admins = "gcp-billing-admins",
|
||||
|
||||
@@ -38,8 +38,9 @@ counts:
|
||||
google_project: 3
|
||||
google_project_iam_binding: 4
|
||||
google_project_iam_member: 18
|
||||
google_project_service: 22
|
||||
google_project_service_identity: 16
|
||||
google_project_service: 24
|
||||
google_project_service_identity: 18
|
||||
google_storage_bucket_object: 2
|
||||
google_vpc_access_connector: 2
|
||||
modules: 24
|
||||
resources: 169
|
||||
resources: 173
|
||||
|
||||
@@ -42,10 +42,10 @@ counts:
|
||||
google_project: 3
|
||||
google_project_iam_binding: 4
|
||||
google_project_iam_member: 17
|
||||
google_project_service: 21
|
||||
google_project_service_identity: 15
|
||||
google_project_service: 23
|
||||
google_project_service_identity: 17
|
||||
google_storage_bucket_object: 2
|
||||
google_vpc_access_connector: 2
|
||||
modules: 29
|
||||
random_id: 1
|
||||
resources: 181
|
||||
resources: 185
|
||||
|
||||
@@ -40,10 +40,10 @@ counts:
|
||||
google_project: 3
|
||||
google_project_iam_binding: 4
|
||||
google_project_iam_member: 17
|
||||
google_project_service: 21
|
||||
google_project_service_identity: 15
|
||||
google_project_service: 23
|
||||
google_project_service_identity: 17
|
||||
google_storage_bucket_object: 2
|
||||
google_vpc_access_connector: 2
|
||||
modules: 31
|
||||
random_id: 5
|
||||
resources: 218
|
||||
resources: 222
|
||||
|
||||
@@ -45,10 +45,10 @@ counts:
|
||||
google_project: 3
|
||||
google_project_iam_binding: 4
|
||||
google_project_iam_member: 18
|
||||
google_project_service: 22
|
||||
google_project_service_identity: 16
|
||||
google_project_service: 24
|
||||
google_project_service_identity: 18
|
||||
google_storage_bucket_object: 2
|
||||
google_vpc_access_connector: 2
|
||||
modules: 39
|
||||
random_id: 2
|
||||
resources: 249
|
||||
resources: 253
|
||||
|
||||
@@ -47,10 +47,10 @@ counts:
|
||||
google_project: 3
|
||||
google_project_iam_binding: 4
|
||||
google_project_iam_member: 17
|
||||
google_project_service: 21
|
||||
google_project_service_identity: 15
|
||||
google_project_service: 23
|
||||
google_project_service_identity: 17
|
||||
google_storage_bucket_object: 2
|
||||
google_vpc_access_connector: 2
|
||||
modules: 43
|
||||
random_id: 2
|
||||
resources: 232
|
||||
resources: 236
|
||||
|
||||
@@ -40,10 +40,10 @@ counts:
|
||||
google_project: 2
|
||||
google_project_iam_binding: 4
|
||||
google_project_iam_member: 14
|
||||
google_project_service: 16
|
||||
google_project_service_identity: 12
|
||||
google_project_service: 18
|
||||
google_project_service_identity: 14
|
||||
google_storage_bucket_object: 2
|
||||
google_vpc_access_connector: 2
|
||||
modules: 22
|
||||
random_id: 2
|
||||
resources: 200
|
||||
resources: 204
|
||||
|
||||
13
tests/fast/stages/s3_network_security/__init__.py
Normal file
13
tests/fast/stages/s3_network_security/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# 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.
|
||||
22
tests/fast/stages/s3_network_security/simple.tfvars
Normal file
22
tests/fast/stages/s3_network_security/simple.tfvars
Normal file
@@ -0,0 +1,22 @@
|
||||
billing_account = {
|
||||
id = "000000-111111-222222"
|
||||
}
|
||||
folder_ids = {
|
||||
networking = "folders/12345678900"
|
||||
networking-dev = "folders/12345678901"
|
||||
networking-prod = "folders/12345678902"
|
||||
}
|
||||
host_project_ids = {
|
||||
dev-spoke-0 = "dev-project"
|
||||
prod-spoke-0 = "prod-project"
|
||||
}
|
||||
organization = {
|
||||
domain = "fast.example.com"
|
||||
id = 123456789012
|
||||
customer_id = "C00000000"
|
||||
}
|
||||
prefix = "fast2"
|
||||
vpc_self_links = {
|
||||
dev-spoke-0 = "https://www.googleapis.com/compute/v1/projects/123456789/networks/vpc-1"
|
||||
prod-spoke-0 = "https://www.googleapis.com/compute/v1/projects/123456789/networks/vpc-2"
|
||||
}
|
||||
27
tests/fast/stages/s3_network_security/simple.yaml
Normal file
27
tests/fast/stages/s3_network_security/simple.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
counts:
|
||||
google_compute_network_firewall_policy: 2
|
||||
google_compute_network_firewall_policy_association: 2
|
||||
google_compute_network_firewall_policy_rule: 4
|
||||
google_network_security_firewall_endpoint: 3
|
||||
google_network_security_firewall_endpoint_association: 6
|
||||
google_network_security_security_profile: 2
|
||||
google_network_security_security_profile_group: 2
|
||||
google_project: 1
|
||||
google_project_service: 1
|
||||
google_project_service_identity: 1
|
||||
modules: 3
|
||||
resources: 24
|
||||
Reference in New Issue
Block a user