diff --git a/0-bootstrap/README-GitHub.md b/0-bootstrap/README-GitHub.md
index 8b03f0040..37918ec61 100644
--- a/0-bootstrap/README-GitHub.md
+++ b/0-bootstrap/README-GitHub.md
@@ -565,12 +565,11 @@ or go to [Deploying step 3-networks-hub-and-spoke](#deploying-step-3-networks-hu
chmod 755 ./tf-wrapper.sh
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv production.auto.example.tfvars production.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update the file `production.auto.tfvars` with the values for the `target_name_server_addresses`.
@@ -665,7 +664,7 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th
1. Push your production branch since development and nonproduction depends it.
-*Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments.
+*Note:** The Production environment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments.
```bash
git add .
@@ -762,12 +761,11 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th
chmod 755 ./tf-wrapper.sh
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv shared.auto.example.tfvars shared.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update `common.auto.tfvars` file with values from your GCP environment.
diff --git a/0-bootstrap/README-GitLab.md b/0-bootstrap/README-GitLab.md
index 56adbb6c0..8035648b9 100644
--- a/0-bootstrap/README-GitLab.md
+++ b/0-bootstrap/README-GitLab.md
@@ -568,12 +568,11 @@ or go to [Deploying step 3-networks-hub-and-spoke](#deploying-step-3-networks-hu
chmod 755 ./*.sh
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv production.auto.example.tfvars production.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update the file `production.auto.tfvars` with the values for the `target_name_server_addresses`.
@@ -668,7 +667,7 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th
1. Push your production branch since development and nonproduction depends it.
-*Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments.
+*Note:** The Production environment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments.
```bash
git add .
@@ -742,12 +741,11 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th
chmod 755 ./*.sh
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv shared.auto.example.tfvars shared.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update `common.auto.tfvars` file with values from your GCP environment.
diff --git a/0-bootstrap/README-Jenkins.md b/0-bootstrap/README-Jenkins.md
index 7d880bb68..8d4cc9cb1 100644
--- a/0-bootstrap/README-Jenkins.md
+++ b/0-bootstrap/README-Jenkins.md
@@ -599,12 +599,11 @@ Here you will configure a VPN Network tunnel to enable connectivity between the
sed -i'' -e "s/CICD_PROJECT_ID/${CICD_PROJECT_ID}/" ./Jenkinsfile
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv production.auto.example.tfvars production.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](../3-networks-svpc/envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file.
@@ -752,12 +751,11 @@ Here you will configure a VPN Network tunnel to enable connectivity between the
sed -i'' -e "s/CICD_PROJECT_ID/${CICD_PROJECT_ID}/" ./Jenkinsfile
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv shared.auto.example.tfvars shared.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](../3-networks-hub-and-spoke/envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file.
diff --git a/0-bootstrap/README-Terraform-Cloud.md b/0-bootstrap/README-Terraform-Cloud.md
index 81bc4bf05..8ef4cc932 100644
--- a/0-bootstrap/README-Terraform-Cloud.md
+++ b/0-bootstrap/README-Terraform-Cloud.md
@@ -476,12 +476,11 @@ or go to [Deploying step 3-networks-hub-and-spoke](#deploying-step-3-networks-hu
chmod 755 ./tf-wrapper.sh
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv production.auto.example.tfvars production.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update the file `production.auto.tfvars` with the values for the `target_name_server_addresses`.
@@ -639,12 +638,11 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th
chmod 755 ./tf-wrapper.sh
```
-1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`.
+1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`.
```bash
mv common.auto.example.tfvars common.auto.tfvars
mv shared.auto.example.tfvars shared.auto.tfvars
- mv access_context.auto.example.tfvars access_context.auto.tfvars
```
1. Update `common.auto.tfvars` file with values from your GCP environment.
diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md
index 15a339411..87baa2a0b 100644
--- a/0-bootstrap/README.md
+++ b/0-bootstrap/README.md
@@ -546,6 +546,7 @@ The following steps will guide you through deploying without using Cloud Build.
| cloud\_build\_worker\_range\_id | The Cloud Build private worker IP range ID. |
| cloud\_builder\_artifact\_repo | Artifact Registry (AR) Repository created to store TF Cloud Builder images. |
| cloudbuild\_project\_id | Project where Cloud Build configuration and terraform container image will reside. |
+| cloudbuild\_project\_number | The cloudbuild project number. |
| common\_config | Common configuration data to be used in other steps. |
| csr\_repos | List of Cloud Source Repos created by the module, linked to Cloud Build triggers. |
| environment\_step\_terraform\_service\_account\_email | Environment Step Terraform Account |
@@ -555,9 +556,11 @@ The following steps will guide you through deploying without using Cloud Build.
| networks\_step\_terraform\_service\_account\_email | Networks Step Terraform Account |
| optional\_groups | List of Google Groups created that are optional to the Example Foundation steps. |
| organization\_step\_terraform\_service\_account\_email | Organization Step Terraform Account |
+| parent\_id | Parent ID service account. |
| projects\_gcs\_bucket\_tfstate | Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. |
| projects\_step\_terraform\_service\_account\_email | Projects Step Terraform Account |
| required\_groups | List of Google Groups created that are required by the Example Foundation steps. |
| seed\_project\_id | Project where service accounts and core APIs will be enabled. |
+| seed\_project\_number | The seed project number. |
diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf
index eae95b617..fa77b4ea0 100644
--- a/0-bootstrap/cb.tf
+++ b/0-bootstrap/cb.tf
@@ -280,3 +280,8 @@ resource "google_sourcerepo_repository_iam_member" "member" {
depends_on = [module.tf_source]
}
+
+data "google_project" "cloudbuild_project" {
+ project_id = module.tf_source.cloudbuild_project_id
+ depends_on = [module.tf_source]
+}
diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf
index 44ca2faf0..81d7e634f 100644
--- a/0-bootstrap/main.tf
+++ b/0-bootstrap/main.tf
@@ -106,3 +106,8 @@ module "seed_bootstrap" {
depends_on = [module.required_group]
}
+
+data "google_project" "seed_project" {
+ project_id = module.seed_bootstrap.seed_project_id
+ depends_on = [module.seed_bootstrap]
+}
diff --git a/0-bootstrap/modules/cb-private-pool/README.md b/0-bootstrap/modules/cb-private-pool/README.md
index 1e6969997..cac726f5c 100644
--- a/0-bootstrap/modules/cb-private-pool/README.md
+++ b/0-bootstrap/modules/cb-private-pool/README.md
@@ -3,8 +3,9 @@
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
-| private\_worker\_pool | name: Name of the worker pool. A name with a random suffix is generated if not set.
region: The private worker pool region. See https://cloud.google.com/build/docs/locations for available locations.
disk\_size\_gb: Size of the disk attached to the worker, in GB.
machine\_type: Machine type of a worker.
no\_external\_ip: If true, workers are created without any public address, which prevents network egress to public IPs.
enable\_network\_peering: Set to true to enable configuration of networking peering for the private worker pool.
create\_peered\_network: If true a network will be created to stablish the network peering.
peered\_network\_id: The ID of the existing network to configure peering for the private worker pool if create\_peered\_network false. The project containing the network must have Service Networking API (`servicenetworking.googleapis.com`) enabled.
peered\_network\_subnet\_ip: The IP range to be used for the subnet that a will created in the peered network if create\_peered\_network true.
peering\_address: The IP address or beginning of the peering address range. This can be supplied as an input to reserve a specific address or omitted to allow GCP to choose a valid one.
peering\_prefix\_length: The prefix length of the IP peering range. If not present, it means the address field is a single IP address. |
object({| `{}` | no | +| private\_worker\_pool | name: Name of the worker pool. A name with a random suffix is generated if not set.
name = optional(string, "")
region = optional(string, "us-central1")
disk_size_gb = optional(number, 100)
machine_type = optional(string, "e2-medium")
no_external_ip = optional(bool, false)
enable_network_peering = optional(bool, false)
create_peered_network = optional(bool, false)
peered_network_id = optional(string, "")
peered_network_subnet_ip = optional(string, "")
peering_address = optional(string, null)
peering_prefix_length = optional(number, 24)
})
object({| `{}` | no | | project\_id | ID of the project where the private pool will be created | `string` | n/a | yes | +| subnet\_region | Region where a subnet will be created in the sigle project network. | `string` | `"us-central1"` | no | | vpc\_flow\_logs | aggregation\_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL\_5\_SEC, INTERVAL\_30\_SEC, INTERVAL\_1\_MIN, INTERVAL\_5\_MIN, INTERVAL\_10\_MIN, INTERVAL\_15\_MIN.
name = optional(string, "")
region = optional(string, "us-central1")
disk_size_gb = optional(number, 100)
machine_type = optional(string, "e2-medium")
no_external_ip = optional(bool, true)
enable_network_peering = optional(bool, true)
create_peered_network = optional(bool, true)
peered_network_id = optional(string, "")
peered_network_subnet_ip = optional(string, "")
peering_address = optional(string, null)
peering_prefix_length = optional(number, 24)
})
object({| `{}` | no | | vpn\_configuration | enable\_vpn: set to true to create VPN connection to on prem. If true, the following values must be valid.
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(string, "0.5")
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(list(string), [])
filter_expr = optional(string, "true")
})
object({| `{}` | no | diff --git a/0-bootstrap/modules/cb-private-pool/network.tf b/0-bootstrap/modules/cb-private-pool/network.tf index ea5546675..f513ab74e 100644 --- a/0-bootstrap/modules/cb-private-pool/network.tf +++ b/0-bootstrap/modules/cb-private-pool/network.tf @@ -16,6 +16,26 @@ locals { peered_ip_range = var.private_worker_pool.enable_network_peering ? "${google_compute_global_address.worker_pool_range[0].address}/${google_compute_global_address.worker_pool_range[0].prefix_length}" : "" + + nat_proxy_vm_ip_range = "10.1.1.0/24" + + single_project_network = { + subnet_name = "eab-develop-us-central1" + subnet_ip = "10.1.20.0/24" + subnet_region = var.subnet_region + subnet_private_access = true + } + single_project_secondary = { + "eab-develop-us-central1" = [ + { + range_name = "eab-develop-us-central1-secondary-01" + ip_cidr_range = "192.168.0.0/18" + }, + { + range_name = "eab-develop-us-central1-secondary-02" + ip_cidr_range = "192.168.64.0/18" + }, + ] } } module "peered_network" { @@ -96,27 +116,208 @@ module "firewall_rules" { project_id = var.project_id network_name = local.peered_network_id - rules = [{ - name = "fw-b-cbpools-100-i-a-all-all-all-service-networking" - description = "allow ingres from the IPs configured for service networking" - direction = "INGRESS" - priority = 100 - source_tags = null - source_service_accounts = null - target_tags = null - target_service_accounts = null + rules = [ + { + name = "fw-b-cbpools-100-i-a-all-all-all-service-networking" + description = "Allow ingress from the IPs configured for service networking" + direction = "INGRESS" + priority = 100 + source_tags = null + source_service_accounts = null + target_tags = null + target_service_accounts = null + + ranges = [local.peered_ip_range] + + allow = [{ + protocol = "all" + ports = null + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + }, + { + name = "allow-pool-to-nat" + description = "Allow all from worker pool to NAT gateway" + direction = "INGRESS" + priority = 1000 + source_tags = null + source_service_accounts = null + target_tags = ["nat-gateway"] + target_service_accounts = null + + ranges = ["${google_compute_global_address.worker_pool_range[0].address}/${google_compute_global_address.worker_pool_range[0].prefix_length}"] + + allow = [{ + protocol = "all" + ports = null + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + }, + { + name = "allow-icmp" + description = "Allow ICMP from anywhere" + direction = "INGRESS" + priority = 65534 + source_tags = null + source_service_accounts = null + target_tags = null + target_service_accounts = null + + ranges = ["0.0.0.0/1"] + + allow = [{ + protocol = "icmp" + ports = null + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + }, + { + name = "allow-ssh-ingress" + description = "Allow SSH from anywhere (0.0.0.0/1)" + direction = "INGRESS" + priority = 1000 + source_tags = null + source_service_accounts = null + target_tags = null + target_service_accounts = null + + ranges = ["0.0.0.0/1"] + + allow = [{ + protocol = "tcp" + ports = ["22"] + }] - ranges = [local.peered_ip_range] + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + } + ] +} + +resource "google_compute_address" "cloud_build_nat" { + project = var.project_id + address_type = "EXTERNAL" + name = "cloud-build-nat" + network_tier = "PREMIUM" + region = "us-central1" + + depends_on = [module.peered_network] +} - allow = [{ - protocol = "all" - ports = null - }] +resource "google_compute_instance" "vm-proxy" { + project = var.project_id + name = "cloud-build-nat-vm" + machine_type = "e2-medium" + zone = "us-central1-a" - deny = [] + tags = ["direct-gateway-access", "nat-gateway"] - log_config = { - metadata = "INCLUDE_ALL_METADATA" + boot_disk { + initialize_params { + image = "debian-cloud/debian-12" } - }] + } + + network_interface { + network = local.peered_network_name + subnetwork = "sb-b-cbpools-${var.private_worker_pool.region}" + subnetwork_project = var.project_id + + } + + can_ip_forward = true + + // This script configures the VM to do IP Forwarding + metadata_startup_script = "sysctl -w net.ipv4.ip_forward=1 && iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE" + + service_account { + scopes = ["cloud-platform"] + } + + depends_on = [ + resource.google_compute_router_nat.cb-nat, + module.peered_network + ] +} + +# This route will route packets to the NAT VM +resource "google_compute_route" "through-nat" { + name = "through-nat-range1" + project = var.project_id + dest_range = "0.0.0.0/1" + network = local.peered_network_name + next_hop_instance = google_compute_instance.vm-proxy.id + priority = 10 +} + +resource "google_compute_route" "through-nat2" { + name = "through-nat-range2" + project = var.project_id + dest_range = "128.0.0.0/1" + network = local.peered_network_name + next_hop_instance = google_compute_instance.vm-proxy.id + priority = 10 +} + +# This route allow the NAT VM to reach the internet with it's external IP address + +resource "google_compute_route" "direct-to-gateway" { + name = "direct-to-gateway-range1" + project = var.project_id + dest_range = "0.0.0.0/1" + network = local.peered_network_name + next_hop_gateway = "default-internet-gateway" + tags = ["direct-gateway-access"] + priority = 5 +} + +resource "google_compute_route" "direct-to-gateway2" { + name = "direct-to-gateway-range2" + project = var.project_id + dest_range = "128.0.0.0/1" + network = local.peered_network_name + next_hop_gateway = "default-internet-gateway" + tags = ["direct-gateway-access"] + priority = 5 +} + +# Cloud Router +resource "google_compute_router" "cb-router" { + name = "cb-cloud-router" + network = local.peered_network_name + region = "us-central1" + project = var.project_id +} + +# Cloud NAT +resource "google_compute_router_nat" "cb-nat" { + project = var.project_id + name = "cb-cloud-nat" + router = google_compute_router.cb-router.name + region = google_compute_router.cb-router.region + nat_ip_allocate_option = "AUTO_ONLY" + source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" + + log_config { + enable = true + filter = "ALL" + } } diff --git a/0-bootstrap/modules/cb-private-pool/variables.tf b/0-bootstrap/modules/cb-private-pool/variables.tf index 5dfcbb6a0..38ec91c41 100644 --- a/0-bootstrap/modules/cb-private-pool/variables.tf +++ b/0-bootstrap/modules/cb-private-pool/variables.tf @@ -38,9 +38,9 @@ variable "private_worker_pool" { region = optional(string, "us-central1") disk_size_gb = optional(number, 100) machine_type = optional(string, "e2-medium") - no_external_ip = optional(bool, false) - enable_network_peering = optional(bool, false) - create_peered_network = optional(bool, false) + no_external_ip = optional(bool, true) + enable_network_peering = optional(bool, true) + create_peered_network = optional(bool, true) peered_network_id = optional(string, "") peered_network_subnet_ip = optional(string, "") peering_address = optional(string, null) @@ -124,3 +124,9 @@ EOT }) default = {} } + +variable "subnet_region" { + description = "Region where a subnet will be created in the sigle project network." + type = string + default = "us-central1" +} diff --git a/0-bootstrap/outputs.tf b/0-bootstrap/outputs.tf index 01e6fe09b..0dd7b7239 100644 --- a/0-bootstrap/outputs.tf +++ b/0-bootstrap/outputs.tf @@ -71,6 +71,11 @@ output "common_config" { } } +output "parent_id" { + description = "Parent ID service account." + value = var.parent_folder != "" ? "folder-${local.parent_id}" : "org-${var.org_id}" +} + output "required_groups" { description = "List of Google Groups created that are required by the Example Foundation steps." value = var.groups.create_required_groups == false ? tomap(var.groups.required_groups) : tomap({ for key, value in module.required_group : key => value.id }) @@ -81,6 +86,16 @@ output "optional_groups" { value = var.groups.create_optional_groups == false ? tomap(var.groups.optional_groups) : tomap({ for key, value in module.optional_group : key => value.id }) } +output "seed_project_number" { + description = "The seed project number." + value = data.google_project.seed_project.number +} + +output "cloudbuild_project_number" { + description = "The cloudbuild project number." + value = data.google_project.cloudbuild_project.number +} + /* ---------------------------------------- Specific to cloudbuild_module ---------------------------------------- */ diff --git a/0-bootstrap/sa.tf b/0-bootstrap/sa.tf index 0802d507f..e35b73cae 100644 --- a/0-bootstrap/sa.tf +++ b/0-bootstrap/sa.tf @@ -49,14 +49,18 @@ locals { "roles/resourcemanager.tagUser", "roles/cloudasset.owner", "roles/securitycenter.sourcesEditor", + "roles/serviceusage.serviceUsageConsumer", ], local.common_roles)), "env" = distinct(concat([ + "roles/accesscontextmanager.policyAdmin", "roles/resourcemanager.tagUser", "roles/assuredworkloads.admin", + "roles/serviceusage.serviceUsageConsumer", ], local.common_roles)), "net" = distinct(concat([ "roles/accesscontextmanager.policyAdmin", "roles/compute.xpnAdmin", + "roles/serviceusage.serviceUsageConsumer", ], local.common_roles)), "proj" = distinct(concat([ "roles/accesscontextmanager.policyAdmin", @@ -89,6 +93,7 @@ locals { "roles/artifactregistry.admin", "roles/compute.networkAdmin", "roles/compute.xpnAdmin", + "roles/iam.serviceAccountAdmin" ], } diff --git a/1-org/README.md b/1-org/README.md index 63d140e8a..d2ea2b0e0 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -55,7 +55,8 @@ For an overview of the architecture and the parts, see the ## Purpose -The purpose of this step is to set up top-level shared folders, networking projects, organization-level logging, and baseline security settings through organizational policies. +- Set up top-level shared folders, networking projects, organization-level logging, and baseline security settings through organizational policies. +- Set up VPC Service Controls. ## Prerequisites @@ -155,6 +156,12 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" ``` +1. Update `envs/shared/terraform.tfvars` file with the `access_context_manager_policy_id`. + + ```bash + sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars + ``` + 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and 0-bootstrap step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash @@ -166,6 +173,14 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f if [ ! -z "${ACCESS_CONTEXT_MANAGER_ID}" ]; then sed -i'' -e "s=//create_access_context_manager_access_policy=create_access_context_manager_access_policy=" ./envs/shared/terraform.tfvars; fi ``` +1. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. + + ```bash + cd envs/shared + terraform init + cd ../.. + ``` + 1. Commit changes. ```bash @@ -238,7 +253,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu 1. Check if a Security Command Center notification with the default name, **scc-notify**, already exists. If it exists, choose a different value for the `scc_notification_name` variable in the `./envs/shared/terraform.tfvars` file. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/" output -json common_config | jq '.org_id' --raw-output) + export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared" output -json common_config | jq '.org_id' --raw-output) gcloud scc notifications describe "scc-notify" --organization=${ORGANIZATION_ID} --location=global ``` @@ -249,10 +264,16 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" ``` +1. Update `envs/shared/terraform.tfvars` file with the `access_context_manager_policy_id`. + + ```bash + sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars + ``` + 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export backend_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./envs/shared/terraform.tfvars @@ -267,10 +288,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, follow the [instruct 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from gcp-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw organization_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw organization_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` @@ -310,3 +331,11 @@ Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` + +### (Optional) Enforce VPC Service Controls + +Because enabling VPC Service Controls can be a disruptive process, this repo configures VPC Service Controls perimeters in dry run mode by default. This configuration will service traffic that crosses the security perimeter (API requests that originate from inside your perimeter communicating with external resources, or API requests from external resources communicating with resources inside your perimeter) but still allow service traffic normally. + +When you are ready to enforce VPC Service Controls, we recommend that you review the guidance at [Best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable). After you have added the necessary exceptions and are confident that VPC Service Controls will not disrupt your intended operations, set the variable `enforce_vpcsc` under the module `service_control` to `true` and re-apply this stage. Then re-apply the 2-environments and 4-projects stage, which will inherit the new setting and include those projects inside the enforced perimeter. + +When you need to make changes to an existing enforced perimeter, you can test safely by modifying the configuration of the [dry run perimeter](https://cloud.google.com/vpc-service-controls/docs/dry-run-mode). This will log traffic denied by the dry run perimeter without impacting whether the enforced perimeter allows or denies traffic. diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 0bb97740d..5a5d3126e 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -3,25 +3,45 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | `""` | no | | billing\_export\_dataset\_location | The location of the dataset for billing data export. | `string` | `null` | no | | create\_access\_context\_manager\_access\_policy | Whether to create access context manager access policy. | `bool` | `true` | no | | create\_unique\_tag\_key | Creates unique organization-wide tag keys by adding a random suffix to each key. | `bool` | `false` | no | +| custom\_restricted\_services | List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | +| custom\_restricted\_services\_dry\_run | List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | domains\_to\_allow | The list of domains to allow users from in IAM. Used by Domain Restricted Sharing Organization Policy. Must include the domain of the organization you are deploying the foundation. To add other domains you must also grant access to these domains to the Terraform Service Account used in the deploy. | `list(string)` | n/a | yes | +| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
enable_vpn = optional(bool, false)
on_prem_public_ip_address0 = optional(string, "")
on_prem_public_ip_address1 = optional(string, "")
router_asn = optional(number, 64515)
bgp_peer_asn = optional(number, 64513)
psk_secret_project_id = optional(string, "")
psk_secret_name = optional(string, "")
tunnel0_bgp_peer_address = optional(string, "")
tunnel0_bgp_session_range = optional(string, "")
tunnel1_bgp_peer_address = optional(string, "")
tunnel1_bgp_session_range = optional(string, "")
})
list(object({| `[]` | no | +| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
list(object({| `[]` | no | +| egress\_policies\_keys | A list of keys to use for the Terraform state. The order should correspond to var.egress\_policies and the keys must not be dynamically computed. If `null`, var.egress\_policies will be used as keys. | `list(string)` | `[]` | no | +| egress\_policies\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.egress\_policies\_dry\_run and the keys must not be dynamically computed. If `null`, var.egress\_policies\_dry\_run will be used as keys. | `list(string)` | `[]` | no | | enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_kms\_key\_usage\_tracking | Enable KMS centralized key usage tracking system. | `bool` | `true` | no | | enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. Security Command Center must be activated before the creation of the resources. See [Overview of activating Security Command Center](https://cloud.google.com/security-command-center/docs/activate-scc-overview) before enabling this feature. | `bool` | `false` | no | | enforce\_allowed\_worker\_pools | Whether to enforce the organization policy restriction on allowed worker pools for Cloud Build. | `bool` | `false` | no | +| envs | n/a | `map(bool)` |
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
{| no | | essential\_contacts\_domains\_to\_allow | The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | | essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no | | folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no | | gcp\_groups | Groups to grant specific roles in the Organization.
"development": true,
"nonproduction": true,
"production": true
}
object({| `{}` | no | +| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
audit_viewer = optional(string, null)
security_reviewer = optional(string, null)
network_viewer = optional(string, null)
scc_admin = optional(string, null)
global_secrets_admin = optional(string, null)
kms_admin = optional(string, null)
})
list(object({| `[]` | no | +| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
})
}))
list(object({| `[]` | no | +| ingress\_policies\_keys | A list of keys to use for the Terraform state. The order should correspond to var.ingress\_policies and the keys must not be dynamically computed. If `null`, var.ingress\_policies will be used as keys. | `list(string)` | `[]` | no | +| ingress\_policies\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.ingress\_policies\_dry\_run and the keys must not be dynamically computed. If `null`, var.ingress\_policies\_dry\_run will be used as keys. | `list(string)` | `[]` | no | | log\_export\_storage\_force\_destroy | (Optional) If set to true, delete all contents when destroying the resource; otherwise, destroying the resource will fail if contents are present. | `bool` | `false` | no | | log\_export\_storage\_location | The location of the storage bucket used to export logs. | `string` | `null` | no | | log\_export\_storage\_retention\_policy | Configuration of the bucket's data retention policy for how long objects in the bucket should be retained. |
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
})
}))
object({| `null` | no | | log\_export\_storage\_versioning | (Optional) Toggles bucket versioning, ability to retain a non-current object version when the live object version gets replaced or deleted. | `bool` | `false` | no | +| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | +| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | project\_budget | Budget configuration for projects.
is_locked = bool
retention_period_days = number
})
object({| `{}` | no | | project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | +| required\_egress\_rules\_app\_infra | Required egress rule app infra enforced mode. | `bool` | `false` | no | +| required\_egress\_rules\_app\_infra\_dry\_run | Required egress rule app infra dry run mode. | `bool` | `false` | no | +| required\_ingress\_rules\_app\_infra | Required ingress rule app infra enforced mode. | `bool` | `false` | no | +| required\_ingress\_rules\_app\_infra\_dry\_run | Required ingress rule app infra dry run mode. | `bool` | `false` | no | +| resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no | +| resources\_dry\_run | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no | | scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no | | scc\_notification\_name | Name of the Security Command Center Notification. It must be unique in the organization. Run `gcloud scc notifications describe
net_hub_budget_amount = optional(number, 1000)
net_hub_alert_spent_percents = optional(list(number), [1.2])
net_hub_alert_pubsub_topic = optional(string, null)
net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
shared_network_budget_amount = optional(number, 1000)
shared_network_alert_spent_percents = optional(list(number), [1.2])
shared_network_alert_pubsub_topic = optional(string, null)
shared_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
interconnect_budget_amount = optional(number, 1000)
interconnect_alert_spent_percents = optional(list(number), [1.2])
interconnect_alert_pubsub_topic = optional(string, null)
interconnect_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_secrets_budget_amount = optional(number, 1000)
org_secrets_alert_spent_percents = optional(list(number), [1.2])
org_secrets_alert_pubsub_topic = optional(string, null)
org_secrets_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_billing_export_budget_amount = optional(number, 1000)
org_billing_export_alert_spent_percents = optional(list(number), [1.2])
org_billing_export_alert_pubsub_topic = optional(string, null)
org_billing_export_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
common_kms_budget_amount = optional(number, 1000)
common_kms_alert_spent_percents = optional(list(number), [1.2])
common_kms_alert_pubsub_topic = optional(string, null)
common_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
})
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -31,13 +24,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-hub-and-spoke/envs/development/main.tf b/3-networks-hub-and-spoke/envs/development/main.tf index 1b5b2c35f..081b76d86 100644 --- a/3-networks-hub-and-spoke/envs/development/main.tf +++ b/3-networks-hub-and-spoke/envs/development/main.tf @@ -46,13 +46,9 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - ingress_policies = var.ingress_policies - egress_policies = var.egress_policies enable_partner_interconnect = false enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity private_service_cidr = local.private_service_cidr diff --git a/3-networks-hub-and-spoke/envs/development/outputs.tf b/3-networks-hub-and-spoke/envs/development/outputs.tf index 7dacea96e..adc89e11e 100644 --- a/3-networks-hub-and-spoke/envs/development/outputs.tf +++ b/3-networks-hub-and-spoke/envs/development/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The host project ID" @@ -54,22 +49,3 @@ output "subnets_secondary_ranges" { description = "The secondary ranges associated with these subnets" } -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-hub-and-spoke/envs/development/variables.tf b/3-networks-hub-and-spoke/envs/development/variables.tf index cf3061211..c86550386 100644 --- a/3-networks-hub-and-spoke/envs/development/variables.tf +++ b/3-networks-hub-and-spoke/envs/development/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." @@ -35,54 +30,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/envs/nonproduction/README.md b/3-networks-hub-and-spoke/envs/nonproduction/README.md index 3447d2f68..f14b1c741 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/README.md +++ b/3-networks-hub-and-spoke/envs/nonproduction/README.md @@ -15,15 +15,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -31,13 +24,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-hub-and-spoke/envs/nonproduction/main.tf b/3-networks-hub-and-spoke/envs/nonproduction/main.tf index 954060efc..2a7287538 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/main.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/main.tf @@ -44,25 +44,18 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.7" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.7" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf b/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf index 700e37837..0a8733624 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" @@ -53,23 +48,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-hub-and-spoke/envs/nonproduction/variables.tf b/3-networks-hub-and-spoke/envs/nonproduction/variables.tf index cf3061211..c86550386 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/variables.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." @@ -35,54 +30,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/envs/production/README.md b/3-networks-hub-and-spoke/envs/production/README.md index e1e62e277..4652741e7 100644 --- a/3-networks-hub-and-spoke/envs/production/README.md +++ b/3-networks-hub-and-spoke/envs/production/README.md @@ -15,15 +15,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -31,13 +24,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-hub-and-spoke/envs/production/main.tf b/3-networks-hub-and-spoke/envs/production/main.tf index 9cf7ffdb3..bfbbf627f 100644 --- a/3-networks-hub-and-spoke/envs/production/main.tf +++ b/3-networks-hub-and-spoke/envs/production/main.tf @@ -44,25 +44,18 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.8" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.8" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-hub-and-spoke/envs/production/outputs.tf b/3-networks-hub-and-spoke/envs/production/outputs.tf index 700e37837..0a8733624 100644 --- a/3-networks-hub-and-spoke/envs/production/outputs.tf +++ b/3-networks-hub-and-spoke/envs/production/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" @@ -53,23 +48,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-hub-and-spoke/envs/production/variables.tf b/3-networks-hub-and-spoke/envs/production/variables.tf index cf3061211..c86550386 100644 --- a/3-networks-hub-and-spoke/envs/production/variables.tf +++ b/3-networks-hub-and-spoke/envs/production/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." @@ -35,54 +30,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/envs/shared/README.md b/3-networks-hub-and-spoke/envs/shared/README.md index 4dce69797..0c47a3896 100644 --- a/3-networks-hub-and-spoke/envs/shared/README.md +++ b/3-networks-hub-and-spoke/envs/shared/README.md @@ -12,13 +12,10 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_dns | BGP Autonomous System Number (ASN). | `number` | `64667` | no | -| custom\_restricted\_services | List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | dns\_vpc\_flow\_logs | enable\_logging: set to true to enable VPC flow logging for the subnetworks.
from = any
to = any
}))
object({| `{}` | no | | domain | The DNS name of forwarding managed zone, for instance 'example.com'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference), each list object has a `from` and `to` value that describes egress\_from and egress\_to.
enable_logging = optional(string, "true")
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(string, "0.5")
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(list(string), [])
filter_expr = optional(string, "true")
})
list(object({| `[]` | no | | enable\_dedicated\_interconnect | Enable Dedicated Interconnect in the environment. | `bool` | `false` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | @@ -31,8 +28,6 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. | hub\_nat\_num\_addresses\_region1 | Number of external IPs to reserve for first Cloud NAT in Shared Hub. | `number` | `2` | no | | hub\_nat\_num\_addresses\_region2 | Number of external IPs to reserve for second Cloud NAT in Shared Hub. | `number` | `2` | no | | hub\_windows\_activation\_enabled | Enable Windows license activation for Windows workloads in Shared Hub. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference), each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the Shared perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | n/a | yes | | preactivate\_partner\_interconnect | Preactivate Partner Interconnect VLAN attachment in the environment. | `bool` | `false` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | n/a | yes | diff --git a/3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-hub-and-spoke/envs/shared/main.tf b/3-networks-hub-and-spoke/envs/shared/main.tf index 891fa4eba..be349ba3f 100644 --- a/3-networks-hub-and-spoke/envs/shared/main.tf +++ b/3-networks-hub-and-spoke/envs/shared/main.tf @@ -19,21 +19,4 @@ locals { environment_code = "c" bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" dns_bgp_asn_number = var.enable_partner_interconnect ? "16550" : var.bgp_asn_dns - - dedicated_interconnect_egress_policy = var.enable_dedicated_interconnect ? [ - { - "from" = { - "identity_type" = "" - "identities" = ["serviceAccount:${local.networks_service_account}"] - }, - "to" = { - "resources" = ["projects/${local.interconnect_project_number}"] - "operations" = { - "compute.googleapis.com" = { - "methods" = ["*"] - } - } - } - }, - ] : [] } diff --git a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf index bdff242df..f906aa75b 100644 --- a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf +++ b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf @@ -25,132 +25,6 @@ locals { (local.default_region2) = "10.27.0.0/23" } - supported_restricted_service = [ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - ] - - restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service - restricted_services_dry_run = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service } /****************************************** @@ -160,23 +34,10 @@ locals { module "shared_vpc" { source = "../../modules/shared_vpc" - project_id = local.net_hub_project_id - project_number = local.net_hub_project_number - environment_code = local.environment_code - private_service_connect_ip = "10.17.0.5" - access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = local.restricted_services - restricted_services_dry_run = local.restricted_services_dry_run - members = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - members_dry_run = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) + project_id = local.net_hub_project_id + project_number = local.net_hub_project_number + environment_code = local.environment_code + private_service_connect_ip = "10.17.0.5" bgp_asn_subnet = local.bgp_asn_number default_region1 = local.default_region1 default_region2 = local.default_region2 @@ -239,12 +100,4 @@ module "shared_vpc" { } ] secondary_ranges = {} - - egress_policies = distinct(concat( - local.dedicated_interconnect_egress_policy, - var.egress_policies - )) - - ingress_policies = var.ingress_policies - } diff --git a/3-networks-hub-and-spoke/envs/shared/variables.tf b/3-networks-hub-and-spoke/envs/shared/variables.tf index 42bcc7530..8ce694951 100644 --- a/3-networks-hub-and-spoke/envs/shared/variables.tf +++ b/3-networks-hub-and-spoke/envs/shared/variables.tf @@ -19,16 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the Shared perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) -} - -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "dns_enable_logging" { type = bool description = "Toggle DNS logging for VPC DNS." @@ -169,30 +159,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "custom_restricted_services" { - description = "List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference), each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference), each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/modules/base_env/README.md b/3-networks-hub-and-spoke/modules/base_env/README.md index 908261758..d72e7f773 100644 --- a/3-networks-hub-and-spoke/modules/base_env/README.md +++ b/3-networks-hub-and-spoke/modules/base_env/README.md @@ -3,23 +3,14 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | -| custom\_restricted\_services | List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | -| custom\_restricted\_services\_dry\_run | List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_dedicated\_interconnect | Enable Dedicated Interconnect in the environment. | `bool` | `false` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | | env | The environment to prepare (ex. development) | `string` | n/a | yes | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization (ex. d). | `string` | n/a | yes | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Shared Vpc. | `string` | n/a | yes | | private\_service\_connect\_ip | The subnet internal IP to be used as the private service connect endpoint in the Shared VPC | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -34,12 +25,8 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | shared\_vpc\_host\_project\_id | The host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/modules/base_env/main.tf b/3-networks-hub-and-spoke/modules/base_env/main.tf index ab7521696..67ed708db 100644 --- a/3-networks-hub-and-spoke/modules/base_env/main.tf +++ b/3-networks-hub-and-spoke/modules/base_env/main.tf @@ -20,164 +20,22 @@ locals { subnet_aggregates = ["10.8.0.0/18", "10.9.0.0/18", "100.72.0.0/18", "100.73.0.0/18"] hub_subnet_ranges = ["10.8.0.0/24", "10.9.0.0/24"] - - supported_restricted_service = [ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "confidentialcomputing.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - ] - - restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service - restricted_services_dry_run = length(var.custom_restricted_services_dry_run) != 0 ? var.custom_restricted_services : local.supported_restricted_service } /****************************************** Shared VPC *****************************************/ + module "shared_vpc" { source = "../shared_vpc" - project_id = local.shared_vpc_project_id - project_number = local.shared_vpc_project_number - net_hub_project_id = local.net_hub_project_id - net_hub_project_number = local.net_hub_project_number - environment_code = var.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = local.restricted_services - restricted_services_dry_run = local.restricted_services_dry_run - members = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - members_dry_run = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) + project_id = local.shared_vpc_project_id + project_number = local.shared_vpc_project_number + net_hub_project_id = local.net_hub_project_id + net_hub_project_number = local.net_hub_project_number + environment_code = var.environment_code private_service_cidr = var.private_service_cidr private_service_connect_ip = var.private_service_connect_ip - ingress_policies = var.ingress_policies - egress_policies = var.egress_policies bgp_asn_subnet = local.bgp_asn_number default_region1 = var.default_region1 default_region2 = var.default_region2 diff --git a/3-networks-hub-and-spoke/modules/base_env/outputs.tf b/3-networks-hub-and-spoke/modules/base_env/outputs.tf index e4e7217d9..ec03126b9 100644 --- a/3-networks-hub-and-spoke/modules/base_env/outputs.tf +++ b/3-networks-hub-and-spoke/modules/base_env/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.shared_vpc.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.shared_vpc.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = module.shared_vpc.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.shared_vpc.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.shared_vpc.service_perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} diff --git a/3-networks-hub-and-spoke/modules/base_env/variables.tf b/3-networks-hub-and-spoke/modules/base_env/variables.tf index 3c9ce405c..cb2d319b9 100644 --- a/3-networks-hub-and-spoke/modules/base_env/variables.tf +++ b/3-networks-hub-and-spoke/modules/base_env/variables.tf @@ -35,11 +35,6 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "default_region1" { type = string description = "First subnet region. The shared vpc modules only configures two regions." @@ -116,67 +111,6 @@ EOT default = {} } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - - -variable "custom_restricted_services" { - description = "List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - -variable "custom_restricted_services_dry_run" { - description = "List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/README.md b/3-networks-hub-and-spoke/modules/shared_vpc/README.md index 74c4627d9..43979002e 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/README.md +++ b/3-networks-hub-and-spoke/modules/shared_vpc/README.md @@ -3,24 +3,16 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_subnet | BGP ASN for Subnets cloud routers. | `number` | n/a | yes | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | dns\_enable\_inbound\_forwarding | Toggle inbound query forwarding for VPC DNS. | `bool` | `true` | no | | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_all\_vpc\_internal\_traffic | Enable firewall policy rule to allow internal traffic (ingress and egress). | `bool` | `false` | no | | enable\_transitivity\_traffic | Enable a firewall policy rule to allow traffic between Hub and Spokes (ingress only). | `bool` | `true` | no | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | `bool` | `false` | no | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization. | `string` | n/a | yes | | firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls. | `bool` | `true` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| members | An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | -| members\_dry\_run | An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | | mode | Network deployment mode, should be set to `hub` or `spoke` when `enable_hub_and_spoke` architecture chosen, keep as `null` otherwise. | `string` | `null` | no | | nat\_bgp\_asn | BGP ASN for NAT cloud routes. If NAT is enabled this variable value must be a value in ranges [64512..65534] or [4200000000..4294967294]. | `number` | `64512` | no | | nat\_enabled | Toggle creation of NAT cloud router. | `bool` | `false` | no | @@ -32,8 +24,6 @@ | private\_service\_connect\_ip | Internal IP to be used as the private service connect endpoint. | `string` | n/a | yes | | project\_id | Project ID for Shared VPC. | `string` | n/a | yes | | project\_number | Project number for Shared VPC. | `number` | n/a | yes | -| restricted\_services | List of services to restrict in an enforced perimeter. | `list(string)` | n/a | yes | -| restricted\_services\_dry\_run | List of services to restrict in a dry-run perimeter. | `list(string)` | n/a | yes | | secondary\_ranges | Secondary ranges that will be used in some of the subnets | `map(list(object({ range_name = string, ip_cidr_range = string })))` | `{}` | no | | subnets | The list of subnets being created |
from = any
to = any
}))
list(object({| `[]` | no | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | n/a | yes | @@ -43,10 +33,7 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | | dns\_policy | The name of the DNS policy being created | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | firewall\_policy | Policy created for firewall policy rules. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | @@ -54,7 +41,6 @@ | region1\_router2 | Router 2 for Region 1 | | region2\_router1 | Router 1 for Region 2 | | region2\_router2 | Router 2 for Region 2 | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | | subnets\_regions | The region where the subnets will be created | diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf b/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf index 617c987fd..7ff41daca 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf +++ b/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf @@ -78,23 +78,3 @@ output "firewall_policy" { value = module.firewall_rules.fw_policy[0].name description = "Policy created for firewall policy rules." } - -output "access_level_name" { - value = local.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = local.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = var.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = local.perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf b/3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf deleted file mode 100644 index 42921e0f5..000000000 --- a/3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -locals { - prefix = "${var.environment_code}_shared_vpc" - access_level_name = "alp_${local.prefix}_members_${random_id.random_access_level_suffix.hex}" - access_level_name_dry_run = "alp_${local.prefix}_members_dry_run_${random_id.random_access_level_suffix.hex}" - perimeter_name = "sp_${local.prefix}_default_perimeter_${random_id.random_access_level_suffix.hex}" - bridge_name = "spb_c_to_${local.prefix}_bridge_${random_id.random_access_level_suffix.hex}" -} - -resource "random_id" "random_access_level_suffix" { - byte_length = 2 -} - -module "access_level" { - source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 6.0" - - description = "${local.prefix} Access Level" - policy = var.access_context_manager_policy_id - name = local.access_level_name - members = var.members -} - -module "access_level_dry_run" { - source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 6.0" - - description = "${local.prefix} Access Level for testing with a dry run perimeter" - policy = var.access_context_manager_policy_id - name = local.access_level_name_dry_run - members = var.members_dry_run -} - -resource "time_sleep" "wait_vpc_sc_propagation" { - create_duration = "60s" - destroy_duration = "60s" - - depends_on = [ - module.main, - module.peering, - google_compute_global_address.private_service_access_address, - google_service_networking_connection.private_vpc_connection, - module.region1_router1, - module.region1_router2, - module.region2_router1, - module.region2_router2, - module.private_service_connect, - google_dns_policy.default_policy, - module.peering_zone, - module.firewall_rules, - google_compute_router.nat_router_region1, - google_compute_address.nat_external_addresses1, - google_compute_router_nat.nat_external_addresses_region1, - google_compute_router.nat_router_region2, - google_compute_address.nat_external_addresses_region2, - google_compute_router_nat.egress_nat_region2, - ] -} - -module "regular_service_perimeter" { - source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" - version = "~> 6.0" - - policy = var.access_context_manager_policy_id - perimeter_name = local.perimeter_name - description = "Default VPC Service Controls perimeter" - - # configurations for a perimeter in enforced mode. - resources = var.enforce_vpcsc ? [var.project_number] : [] - access_levels = var.enforce_vpcsc ? [module.access_level.name] : [] - restricted_services = var.enforce_vpcsc ? var.restricted_services : [] - vpc_accessible_services = var.enforce_vpcsc ? ["RESTRICTED-SERVICES"] : [] - ingress_policies = var.enforce_vpcsc ? var.ingress_policies : [] - egress_policies = var.enforce_vpcsc ? var.egress_policies : [] - - # configurations for a perimeter in dry run mode. - resources_dry_run = [var.project_number] - access_levels_dry_run = [module.access_level_dry_run.name] - restricted_services_dry_run = var.restricted_services_dry_run - vpc_accessible_services_dry_run = ["RESTRICTED-SERVICES"] - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies_dry_run = var.egress_policies_dry_run - - depends_on = [ - time_sleep.wait_vpc_sc_propagation - ] -} - -resource "google_access_context_manager_service_perimeter" "bridge_to_network_hub_perimeter" { - count = var.mode == "spoke" ? 1 : 0 - - perimeter_type = "PERIMETER_TYPE_BRIDGE" - parent = "accessPolicies/${var.access_context_manager_policy_id}" - name = "accessPolicies/${var.access_context_manager_policy_id}/servicePerimeters/${local.bridge_name}" - title = local.bridge_name - - use_explicit_dry_run_spec = var.enforce_vpcsc ? false : true - - status { - resources = var.enforce_vpcsc ? formatlist("projects/%s", [var.project_number, var.net_hub_project_number]) : [] - } - - depends_on = [module.regular_service_perimeter] -} diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf b/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf index b61d41451..9cfc19e96 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf +++ b/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf @@ -19,11 +19,6 @@ variable "target_name_server_addresses" { type = list(map(any)) } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "project_id" { type = string description = "Project ID for Shared VPC." @@ -165,26 +160,6 @@ variable "windows_activation_enabled" { default = false } -variable "members" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "members_dry_run" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "restricted_services" { - type = list(string) - description = "List of services to restrict in an enforced perimeter." -} - -variable "restricted_services_dry_run" { - type = list(string) - description = "List of services to restrict in a dry-run perimeter." -} - variable "enable_all_vpc_internal_traffic" { type = bool description = "Enable firewall policy rule to allow internal traffic (ingress and egress)." @@ -196,45 +171,3 @@ variable "enable_transitivity_traffic" { description = "Enable a firewall policy rule to allow traffic between Hub and Spokes (ingress only)." default = true } - -variable "enforce_vpcsc" { - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." - type = bool - default = false -} - -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} diff --git a/3-networks-svpc/README.md b/3-networks-svpc/README.md index b8e3a29f2..519f017ed 100644 --- a/3-networks-svpc/README.md +++ b/3-networks-svpc/README.md @@ -65,14 +65,6 @@ The purpose of this step is to: 1. 0-bootstrap executed successfully. 1. 1-org executed successfully. 1. 2-environments executed successfully. -1. Obtain the value for the access_context_manager_policy_id variable. It can be obtained by running the following commands. We assume you are at the same level as directory `terraform-example-foundation`, If you run them from another directory, adjust your paths accordingly. - - ```bash - export ORGANIZATION_ID=$(terraform -chdir="terraform-example-foundation/0-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - ``` - 1. For the manual step described in this document, you need to use the same [Terraform](https://www.terraform.io/downloads.html) version used on the build pipeline. Otherwise, you might experience Terraform state snapshot lock errors. @@ -163,44 +155,34 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +2. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` -1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. +3. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. Update `production.auto.tfvars` file with the `target_name_server_addresses`. - Update `access_context.auto.tfvars` file with the `access_context_manager_policy_id`. Use `terraform output` to get the backend bucket value from 0-bootstrap output. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - - sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./access_context.auto.tfvars - export backend_bucket=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` - **Note:** Make sure that you update the `perimeter_additional_members` variable with your user identity in order to be able to view/access resources in the project protected by the VPC Service Controls. - -1. Commit changes +4. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +5. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +6. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +7. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -210,48 +192,48 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -1. Run `init` and `plan` and review output for environment shared. +8. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -1. Run `validate` and check for violations. +9. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -1. Run `apply` shared. +10. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -1. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. +11. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. ```bash git checkout -b production ``` -1. Run `init` and `plan` and review output for environment production. +12. Run `init` and `plan` and review output for environment production. ```bash ./tf-wrapper.sh init production ./tf-wrapper.sh plan production ``` -1. Run `apply` production. +13. Run `apply` production. ```bash ./tf-wrapper.sh apply production ``` - 1. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), - pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID +14. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID -*Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. +*Note:** The Production environment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. ```bash git push --set-upstream origin production @@ -332,27 +314,19 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. 1. Update `production.auto.tfvars` file with the `target_name_server_addresses`. -1. Update `access_context.auto.tfvars` file with the `access_context_manager_policy_id`. -1. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. +2. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - - sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./access_context.auto.tfvars - - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export backend_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars @@ -367,10 +341,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, please follow the [i 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw networks_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw networks_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` @@ -479,11 +453,3 @@ Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` - -### (Optional) Enforce VPC Service Controls - -Because enabling VPC Service Controls can be a disruptive process, this repo configures VPC Service Controls perimeters in dry run mode by default. This configuration will service traffic that crosses the security perimeter (API requests that originate from inside your perimeter communicating with external resources, or API requests from external resources communicating with resources inside your perimeter) but still allow service traffic normally. - -When you are ready to enforce VPC Service Controls, we recommend that you review the guidance at [Best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable). After you have added the necessary exceptions and are confident that VPC Service Controls will not disrupt your intended operations, set the variable `enforce_vpcsc` under the module `shared_vpc` to `true` and re-apply this stage. Then re-apply the 4-projects stage, which will inherit the new setting and include those projects inside the enforced perimeter. - -When you need to make changes to an existing enforced perimeter, you can test safely by modifying the configuration of the [dry run perimeter](https://cloud.google.com/vpc-service-controls/docs/dry-run-mode). This will log traffic denied by the dry run perimeter without impacting whether the enforced perimeter allows or denies traffic. diff --git a/3-networks-svpc/access_context.auto.example.tfvars b/3-networks-svpc/access_context.auto.example.tfvars deleted file mode 100644 index 8f8871530..000000000 --- a/3-networks-svpc/access_context.auto.example.tfvars +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2021 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. - */ - -access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID diff --git a/3-networks-svpc/common.auto.example.tfvars b/3-networks-svpc/common.auto.example.tfvars index 441314aae..c39ec48dd 100644 --- a/3-networks-svpc/common.auto.example.tfvars +++ b/3-networks-svpc/common.auto.example.tfvars @@ -17,9 +17,4 @@ // The DNS name of peering managed zone. Must end with a period. domain = "example.com." -// Update the following line and add you email in the perimeter_additional_members list. -// You must be in this list to be able to view/access resources in the project protected by the VPC service controls. - -perimeter_additional_members = ["user:YOUR-USER-EMAIL@example.com"] - remote_state_bucket = "REMOTE_STATE_BUCKET" diff --git a/3-networks-svpc/envs/development/README.md b/3-networks-svpc/envs/development/README.md index 92774e3cb..65abc730b 100644 --- a/3-networks-svpc/envs/development/README.md +++ b/3-networks-svpc/envs/development/README.md @@ -15,14 +15,7 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
subnet_name = string
subnet_ip = string
subnet_region = string
subnet_private_access = optional(string, "false")
subnet_private_ipv6_access = optional(string)
subnet_flow_logs = optional(string, "false")
subnet_flow_logs_interval = optional(string, "INTERVAL_5_SEC")
subnet_flow_logs_sampling = optional(string, "0.5")
subnet_flow_logs_metadata = optional(string, "INCLUDE_ALL_METADATA")
subnet_flow_logs_filter = optional(string, "true")
subnet_flow_logs_metadata_fields = optional(list(string), [])
description = optional(string)
purpose = optional(string)
role = optional(string)
stack_type = optional(string)
ipv6_access_type = optional(string)
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -30,13 +23,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/envs/development/access_context.auto.tfvars b/3-networks-svpc/envs/development/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/development/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/development/main.tf b/3-networks-svpc/envs/development/main.tf index d948f1043..53713b601 100644 --- a/3-networks-svpc/envs/development/main.tf +++ b/3-networks-svpc/envs/development/main.tf @@ -46,24 +46,17 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.6" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.6" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-svpc/envs/development/outputs.tf b/3-networks-svpc/envs/development/outputs.tf index c104444fd..997e266de 100644 --- a/3-networks-svpc/envs/development/outputs.tf +++ b/3-networks-svpc/envs/development/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" @@ -53,23 +48,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-svpc/envs/development/variables.tf b/3-networks-svpc/envs/development/variables.tf index 02448e5a9..a974988da 100644 --- a/3-networks-svpc/envs/development/variables.tf +++ b/3-networks-svpc/envs/development/variables.tf @@ -19,64 +19,11 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/envs/nonproduction/README.md b/3-networks-svpc/envs/nonproduction/README.md index 33377827e..41fe8a615 100644 --- a/3-networks-svpc/envs/nonproduction/README.md +++ b/3-networks-svpc/envs/nonproduction/README.md @@ -15,14 +15,7 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -30,13 +23,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/envs/nonproduction/access_context.auto.tfvars b/3-networks-svpc/envs/nonproduction/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/nonproduction/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/nonproduction/main.tf b/3-networks-svpc/envs/nonproduction/main.tf index 2686cf532..8dcc6afa4 100644 --- a/3-networks-svpc/envs/nonproduction/main.tf +++ b/3-networks-svpc/envs/nonproduction/main.tf @@ -44,24 +44,17 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_primary_ranges = local.subnet_primary_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.7" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_primary_ranges = local.subnet_primary_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.7" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-svpc/envs/nonproduction/outputs.tf b/3-networks-svpc/envs/nonproduction/outputs.tf index c104444fd..997e266de 100644 --- a/3-networks-svpc/envs/nonproduction/outputs.tf +++ b/3-networks-svpc/envs/nonproduction/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" @@ -53,23 +48,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-svpc/envs/nonproduction/variables.tf b/3-networks-svpc/envs/nonproduction/variables.tf index 02448e5a9..a974988da 100644 --- a/3-networks-svpc/envs/nonproduction/variables.tf +++ b/3-networks-svpc/envs/nonproduction/variables.tf @@ -19,64 +19,11 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/envs/production/README.md b/3-networks-svpc/envs/production/README.md index 01a596fbd..b17c783f1 100644 --- a/3-networks-svpc/envs/production/README.md +++ b/3-networks-svpc/envs/production/README.md @@ -15,14 +15,7 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | `[]` | no | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -31,13 +24,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/envs/production/access_context.auto.tfvars b/3-networks-svpc/envs/production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/production/main.tf b/3-networks-svpc/envs/production/main.tf index 07e043eb1..57b04b5c0 100644 --- a/3-networks-svpc/envs/production/main.tf +++ b/3-networks-svpc/envs/production/main.tf @@ -44,25 +44,18 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.8" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name - target_name_server_addresses = var.target_name_server_addresses + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.8" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name + target_name_server_addresses = var.target_name_server_addresses } diff --git a/3-networks-svpc/envs/production/outputs.tf b/3-networks-svpc/envs/production/outputs.tf index c104444fd..997e266de 100644 --- a/3-networks-svpc/envs/production/outputs.tf +++ b/3-networks-svpc/envs/production/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" @@ -53,23 +48,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-svpc/envs/production/variables.tf b/3-networks-svpc/envs/production/variables.tf index 588a9e69d..cbcd38e28 100644 --- a/3-networks-svpc/envs/production/variables.tf +++ b/3-networks-svpc/envs/production/variables.tf @@ -25,64 +25,11 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/envs/shared/access_context.auto.tfvars b/3-networks-svpc/envs/shared/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/shared/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/modules/base_env/README.md b/3-networks-svpc/modules/base_env/README.md index 928e11794..518f0821d 100644 --- a/3-networks-svpc/modules/base_env/README.md +++ b/3-networks-svpc/modules/base_env/README.md @@ -3,22 +3,13 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | -| custom\_restricted\_services | List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | -| custom\_restricted\_services\_dry\_run | List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_dedicated\_interconnect | Enable Dedicated Interconnect in the environment. | `bool` | `false` | no | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | | env | The environment to prepare (ex. development) | `string` | n/a | yes | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization (ex. d). | `string` | n/a | yes | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Shared Vpc. | `string` | n/a | yes | | private\_service\_connect\_ip | The base subnet internal IP to be used as the private service connect endpoint in the Shared VPC | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -33,12 +24,8 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/modules/base_env/main.tf b/3-networks-svpc/modules/base_env/main.tf index e94e5893e..93b1d2c97 100644 --- a/3-networks-svpc/modules/base_env/main.tf +++ b/3-networks-svpc/modules/base_env/main.tf @@ -15,153 +15,7 @@ */ locals { - dedicated_interconnect_egress_policy = var.enable_dedicated_interconnect ? [ - { - "from" = { - "identity_type" = "" - "identities" = ["serviceAccount:${local.networks_service_account}"] - }, - "to" = { - "resources" = ["projects/${local.interconnect_project_number}"] - "operations" = { - "compute.googleapis.com" = { - "methods" = ["*"] - } - } - } - }, - ] : [] - bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" - - supported_restricted_service = [ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "documentai.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "confidentialcomputing.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - ] - - restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service - restricted_services_dry_run = length(var.custom_restricted_services_dry_run) != 0 ? var.custom_restricted_services : local.supported_restricted_service } /****************************************** @@ -170,39 +24,16 @@ locals { module "shared_vpc" { source = "../shared_vpc" - project_id = local.shared_vpc_project_id - project_number = local.shared_vpc_project_number - dns_project_id = local.dns_project_id - environment_code = var.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = local.restricted_services - restricted_services_dry_run = local.restricted_services_dry_run - members = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - members_dry_run = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - private_service_cidr = var.private_service_cidr - private_service_connect_ip = var.private_service_connect_ip - bgp_asn_subnet = local.bgp_asn_number - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = distinct(concat( - local.dedicated_interconnect_egress_policy, - var.egress_policies - )) - egress_policies_dry_run = distinct(concat( - local.dedicated_interconnect_egress_policy, - var.egress_policies_dry_run - )) + project_id = local.shared_vpc_project_id + project_number = local.shared_vpc_project_number + dns_project_id = local.dns_project_id + environment_code = var.environment_code + private_service_cidr = var.private_service_cidr + private_service_connect_ip = var.private_service_connect_ip + bgp_asn_subnet = local.bgp_asn_number + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain target_name_server_addresses = var.target_name_server_addresses @@ -257,4 +88,3 @@ module "shared_vpc" { "sb-${var.environment_code}-svpc-${var.default_region1}" = var.subnet_secondary_ranges[var.default_region1] } } - diff --git a/3-networks-svpc/modules/base_env/outputs.tf b/3-networks-svpc/modules/base_env/outputs.tf index c55a4771c..49b75b865 100644 --- a/3-networks-svpc/modules/base_env/outputs.tf +++ b/3-networks-svpc/modules/base_env/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.shared_vpc.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.shared_vpc.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = module.shared_vpc.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.shared_vpc.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.shared_vpc.service_perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} diff --git a/3-networks-svpc/modules/base_env/variables.tf b/3-networks-svpc/modules/base_env/variables.tf index 378bf1788..0c1b65b6d 100644 --- a/3-networks-svpc/modules/base_env/variables.tf +++ b/3-networks-svpc/modules/base_env/variables.tf @@ -35,11 +35,6 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "default_region1" { type = string description = "First subnet region. The shared vpc modules only configures two regions." @@ -110,67 +105,6 @@ EOT default = {} } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - - -variable "custom_restricted_services" { - description = "List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - -variable "custom_restricted_services_dry_run" { - description = "List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/modules/shared_vpc/README.md b/3-networks-svpc/modules/shared_vpc/README.md index cfec1feae..76c8a30ee 100644 --- a/3-networks-svpc/modules/shared_vpc/README.md +++ b/3-networks-svpc/modules/shared_vpc/README.md @@ -3,7 +3,6 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_subnet | BGP ASN for Subnets cloud routers. | `number` | n/a | yes | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | @@ -11,16 +10,9 @@ | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | dns\_project\_id | Project ID for DNS Restricted Shared. | `string` | `""` | no | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.
from = any
to = any
}))
list(object({| `[]` | no | | enable\_all\_vpc\_internal\_traffic | Enable firewall policy rule to allow internal traffic (ingress and egress). | `bool` | `false` | no | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | `bool` | `false` | no | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization. | `string` | n/a | yes | | firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls. | `bool` | `true` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.
from = any
to = any
}))
list(object({| `[]` | no | -| members | An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | -| members\_dry\_run | An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | | nat\_bgp\_asn | BGP ASN for NAT cloud routes. If NAT is enabled this variable value must be a value in ranges [64512..65534] or [4200000000..4294967294]. | `number` | `64512` | no | | nat\_enabled | Toggle creation of NAT cloud router. | `bool` | `false` | no | | nat\_num\_addresses\_region1 | Number of external IPs to reserve for region 1 Cloud NAT. | `number` | `2` | no | @@ -29,8 +21,6 @@ | private\_service\_connect\_ip | Internal IP to be used as the private service connect endpoint. | `string` | n/a | yes | | project\_id | Project ID for Shared VPC. | `string` | n/a | yes | | project\_number | Project number for Shared VPC. | `number` | n/a | yes | -| restricted\_services | List of services to restrict in an enforced perimeter. | `list(string)` | n/a | yes | -| restricted\_services\_dry\_run | List of services to restrict in a dry-run perimeter. | `list(string)` | n/a | yes | | secondary\_ranges | Secondary ranges that will be used in some of the subnets | `map(list(object({ range_name = string, ip_cidr_range = string })))` | `{}` | no | | subnets | The list of subnets being created |
from = any
to = any
}))
list(object({| `[]` | no | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | n/a | yes | @@ -40,16 +30,12 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | region1\_router1 | Router 1 for Region 1 | | region1\_router2 | Router 2 for Region 1 | | region2\_router1 | Router 1 for Region 2 | | region2\_router2 | Router 2 for Region 2 | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | | subnets\_regions | The region where the subnets will be created | diff --git a/3-networks-svpc/modules/shared_vpc/outputs.tf b/3-networks-svpc/modules/shared_vpc/outputs.tf index 748ec4ca3..fd1622a7f 100644 --- a/3-networks-svpc/modules/shared_vpc/outputs.tf +++ b/3-networks-svpc/modules/shared_vpc/outputs.tf @@ -68,24 +68,3 @@ output "region2_router2" { value = module.region2_router2 description = "Router 2 for Region 2" } - -output "access_level_name" { - value = local.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = local.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = var.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = local.perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} - diff --git a/3-networks-svpc/modules/shared_vpc/variables.tf b/3-networks-svpc/modules/shared_vpc/variables.tf index 6342467f2..a5f6a2b69 100644 --- a/3-networks-svpc/modules/shared_vpc/variables.tf +++ b/3-networks-svpc/modules/shared_vpc/variables.tf @@ -25,11 +25,6 @@ variable "target_name_server_addresses" { type = list(map(any)) } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "project_id" { type = string description = "Project ID for Shared VPC." @@ -153,71 +148,8 @@ variable "windows_activation_enabled" { default = false } -variable "members" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "members_dry_run" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "restricted_services" { - type = list(string) - description = "List of services to restrict in an enforced perimeter." -} - -variable "restricted_services_dry_run" { - type = list(string) - description = "List of services to restrict in a dry-run perimeter." -} - variable "enable_all_vpc_internal_traffic" { type = bool description = "Enable firewall policy rule to allow internal traffic (ingress and egress)." default = false } - -variable "enforce_vpcsc" { - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." - type = bool - default = false -} - -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - diff --git a/4-projects/README.md b/4-projects/README.md index 51e7af1e1..b9af1b3db 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -219,12 +219,93 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' git push origin nonproduction ``` -1. Before executing the next step, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +1. Unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` +1. Before move to the next step, configure directional policies for your perimeter. + +1. Navigate to `gcp-org`. +1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. + + ```bash + cd ../gcp-org/ + + export cloudbuild_project_number=$(terraform -chdir="../gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_number) + echo "cloud build project number = $cloudbuild_project_number" + export cloudbuild_project_id=$(terraform -chdir="../gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_id) + echo "cloud build project id = $cloudbuild_project_id" + sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" /envs/shared/service_control.tf + sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf + ``` + +1. Use `terraform output` to get the Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. +1. Use `gsutil cat` to get the project numbers of the SVPC and Peering projects in each environment (production, nonproduction, and development) for configuring the directional app infra policies. + + ```bash + export projects_gcs_bucket_tfstate=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw projects_gcs_bucket_tfstate) + echo "projects_gcs_bucket_tfstate = ${projects_gcs_bucket_tfstate}" + + export peering_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_dev = ${peering_project_number_dev}" + sed -i'' -e "s/PRJS_DEV_SAMPLE_PEERING_NUMBER/${peering_project_number_dev}/" envs/shared/service_control.tf + + export peering_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_prod = ${peering_project_number_prod}" + sed -i'' -e "s/PRJS_PROD_SAMPLE_PEERING_NUMBER/${peering_project_number_prod}/" envs/shared/service_control.tf + + export peering_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_nonprod = ${peering_project_number_nonprod}" + sed -i'' -e "s/PRJS_NONPROD_SAMPLE_PEERING_NUMBER/${peering_project_number_nonprod}/" envs/shared/service_control.tf + + export shared_vpc_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_dev = ${shared_vpc_project_number_dev}" + sed -i'' -e "s/PRJS_DEV_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_dev}/" /envs/shared/service_control.tf + + export shared_vpc_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_prod = ${shared_vpc_project_number_prod}" + sed -i'' -e "s/PRJS_PROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_prod}/" /envs/shared/service_control.tf + + export shared_vpc_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_nonprod = ${shared_vpc_project_number_nonprod}" + sed -i'' -e "s/PRJS_NONPROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_nonprod}/" /envs/shared/service_control.tf + ``` + +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` and `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. + + ```bash + export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ + echo "enforce_vpcsc" = $enforce_vpcsc + if [[ "$enforce_vpcsc" == "false" ]]; then \ + sed -i -E '/^[[:space:]]*\/\/required_ingress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + else \ + sed -i -E '/^[[:space:]]*\/\/required_ingress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + fi + if [[ "$enforce_vpcsc" == "false" ]]; then \ + sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + else \ + sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + fi + ``` + +1. Commit and push the changes. + + ```bash + git add . + git commit -m "Add infra pipeline directional policies" + git push + + cd .. + ``` + 1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. ### Deploying with Jenkins @@ -274,7 +355,7 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s Use `terraform output` to get the remote state bucket (the backend bucket used by previous steps) value from `gcp-bootstrap` output. ```bash - export remote_state_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export remote_state_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${remote_state_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${remote_state_bucket}/" ./common.auto.tfvars @@ -287,10 +368,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, please follow the [i 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from gcp-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw projects_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw projects_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` @@ -377,7 +458,7 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' git commit -m "Initial nonproduction commit." ``` -1. Checkout shared `production`. Run `init` and `plan` and review output for environment development. +1. Checkout shared `production`. Run `init` and `plan` and review output for production development. ```bash git checkout production @@ -403,8 +484,113 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' If you received any errors or made any changes to the Terraform config or any `.tfvars`, you must re-run `./tf-wrapper.sh plan
subnet_name = string
subnet_ip = string
subnet_region = string
subnet_private_access = optional(string, "false")
subnet_private_ipv6_access = optional(string)
subnet_flow_logs = optional(string, "false")
subnet_flow_logs_interval = optional(string, "INTERVAL_5_SEC")
subnet_flow_logs_sampling = optional(string, "0.5")
subnet_flow_logs_metadata = optional(string, "INCLUDE_ALL_METADATA")
subnet_flow_logs_filter = optional(string, "true")
subnet_flow_logs_metadata_fields = optional(list(string), [])
description = optional(string)
purpose = optional(string)
role = optional(string)
stack_type = optional(string)
ipv6_access_type = optional(string)
}))
SecurityPolicyViolated