diff --git a/README.md b/README.md index bae85ce4..f4487ca6 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ The current list of modules supports most of the core foundational and networkin Currently available modules: - **foundational** - [billing budget](./modules/billing-budget), [Cloud Identity group](./modules/cloud-identity-group/), [folder](./modules/folder), [service accounts](./modules/iam-service-account), [logging bucket](./modules/logging-bucket), [organization](./modules/organization), [project](./modules/project), [projects-data-source](./modules/projects-data-source) -- **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [VLAN Attachment](./modules/net-vlan-attachment/), [External Application LB](./modules/net-lb-app-ext/), [External Passthrough Network LB](./modules/net-lb-ext), [Internal Application LB](./modules/net-lb-app-int), [Internal Passthrough Network LB](./modules/net-lb-int), [Internal Proxy Network LB](./modules/net-lb-proxy-int), [IPSec over Interconnect](./modules/net-ipsec-over-interconnect), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC firewall policy](./modules/net-vpc-firewall-policy), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory), [Secure Web Proxy](./modules/net-swp) +- **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [VLAN Attachment](./modules/net-vlan-attachment/), [External Application LB](./modules/net-lb-app-ext/), [External Passthrough Network LB](./modules/net-lb-ext), [Firewall policy](./modules/net-firewall-policy), [Internal Application LB](./modules/net-lb-app-int), [Internal Passthrough Network LB](./modules/net-lb-int), [Internal Proxy Network LB](./modules/net-lb-proxy-int), [IPSec over Interconnect](./modules/net-ipsec-over-interconnect), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory), [Secure Web Proxy](./modules/net-swp) - **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster-standard), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool) - **data** - [AlloyDB instance](./modules/alloydb-instance), [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Dataplex](./modules/dataplex), [Dataplex DataScan](./modules/dataplex-datascan/), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub) - **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository) diff --git a/blueprints/data-solutions/shielded-folder/README.md b/blueprints/data-solutions/shielded-folder/README.md index 86d3c62c..83e9589d 100644 --- a/blueprints/data-solutions/shielded-folder/README.md +++ b/blueprints/data-solutions/shielded-folder/README.md @@ -209,5 +209,5 @@ module "test" { billing_account_id = "123456-123456-123456" } } -# tftest modules=6 resources=38 inventory=simple.yaml +# tftest modules=7 resources=38 ``` diff --git a/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-ingress-rules.yaml b/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-ingress-rules.yaml new file mode 100644 index 00000000..a267527d --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-ingress-rules.yaml @@ -0,0 +1,37 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + priority: 1000 + match: + source_ranges: + - rfc1918 + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + priority: 1001 + match: + source_ranges: + - healthchecks + layer4_configs: + - protocol: tcp + ports: ["80", "443"] + +allow-ssh-from-iap: + description: Enable SSH from IAP + priority: 1002 + match: + source_ranges: + - 35.235.240.0/20 + layer4_configs: + - protocol: tcp + ports: ["22"] + +allow-icmp: + description: Enable ICMP + priority: 1003 + match: + source_ranges: + - 0.0.0.0/0 + layer4_configs: + - protocol: icmp diff --git a/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml b/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml deleted file mode 100644 index 6a3b3133..00000000 --- a/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml +++ /dev/null @@ -1,50 +0,0 @@ -# skip boilerplate check - -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-healthchecks: - description: Enable HTTP and HTTPS healthchecks - direction: INGRESS - action: allow - priority: 1001 - ranges: - - $healthchecks - ports: - tcp: ["80", "443"] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false - -allow-icmp: - description: Enable ICMP - direction: INGRESS - action: allow - priority: 1003 - ranges: - - 0.0.0.0/0 - ports: - icmp: [] - target_resources: null - enable_logging: false - \ No newline at end of file diff --git a/blueprints/data-solutions/shielded-folder/main.tf b/blueprints/data-solutions/shielded-folder/main.tf index 3868ec96..5d1145cd 100644 --- a/blueprints/data-solutions/shielded-folder/main.tf +++ b/blueprints/data-solutions/shielded-folder/main.tf @@ -78,11 +78,6 @@ module "folder" { id = var.folder_config.folder_create != null ? null : var.folder_config.folder_id group_iam = local.group_iam org_policies_data_path = var.data_dir != null ? "${var.data_dir}/org-policies" : null - firewall_policy_factory = var.data_dir != null ? { - cidr_file = "${var.data_dir}/firewall-policies/cidrs.yaml" - policy_name = "${var.prefix}-fw-policy" - rules_file = "${var.data_dir}/firewall-policies/hierarchical-policy-rules.yaml" - } : null logging_sinks = var.enable_features.log_sink ? { for name, attrs in var.log_sinks : name => { bq_partitioned_table = attrs.type == "bigquery" @@ -93,14 +88,24 @@ module "folder" { } : null } +module "firewall-policy" { + source = "../../../modules/net-firewall-policy" + name = "default" + parent_id = module.folder.id + rules_factory_config = var.data_dir == null ? {} : { + cidr_file_path = "${var.data_dir}/firewall-policies/cidrs.yaml" + ingress_rules_file_path = "${var.data_dir}/firewall-policies/hierarchical-ingress-rules.yaml" + } +} + module "folder-workload" { source = "../../../modules/folder" parent = module.folder.id name = "${var.prefix}-workload" } +#TODO VPCSC: Access levels -#TODO VPCSC: Access levels data "google_projects" "folder-projects" { filter = "parent.id:${split("/", module.folder.id)[1]}" diff --git a/fast/stages/2-networking-a-peering/README.md b/fast/stages/2-networking-a-peering/README.md index 1dcb29f5..69ab7788 100644 --- a/fast/stages/2-networking-a-peering/README.md +++ b/fast/stages/2-networking-a-peering/README.md @@ -172,7 +172,7 @@ Static routes are defined in `vpc-*.tf` files, in the `routes` section of each ` **VPC firewall rules** ([`net-vpc-firewall`](../../../modules/net-vpc-firewall)) are defined per-vpc on each `vpc-*.tf` file and leverage a resource factory to massively create rules. To add a new firewall rule, create a new file or edit an existing one in the `data_folder` directory defined in the module `net-vpc-firewall`, following the examples of the "[Rules factory](../../../modules/net-vpc-firewall#rules-factory)" section of the module documentation. Sample firewall rules are shipped in [data/firewall-rules/landing](./data/firewall-rules/landing) and can be easily customised. -**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf`, and managed through a policy factory implemented by the `folder` module, which applies the defined hierarchical to the `Networking` folder, which contains all the core networking infrastructure. Policies are defined in the `rules_file` file - to define a new one simply use the instructions found on "[Firewall policy factory](../../../modules/organization#firewall-policy-factory)". Sample hierarchical firewall policies are shipped in [data/hierarchical-policy-rules.yaml](./data/hierarchical-policy-rules.yaml) and can be easily customised. +**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf` and managed through a policy factory implemented by the `net-firewall-policy` module, which is then applied to the `Networking` folder containing all the core networking infrastructure. Policies are defined in the `rules_file` file, to define a new one simply use the [firewall policy module documentation](../../../modules/net-firewall-policy/README.md#factory)". Sample hierarchical firewall rules are shipped in [data/hierarchical-ingress-rules.yaml](./data/hierarchical-ingress-rules.yaml) and can be easily customised. ### DNS architecture @@ -378,7 +378,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | | | [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | | | [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | | -| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | | +| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder · net-firewall-policy | | | [monitoring-vpn-onprem.tf](./monitoring-vpn-onprem.tf) | VPN monitoring alerts. | | google_monitoring_alert_policy | | [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard | | [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object · local_file | diff --git a/fast/stages/2-networking-a-peering/data/hierarchical-ingress-rules.yaml b/fast/stages/2-networking-a-peering/data/hierarchical-ingress-rules.yaml new file mode 100644 index 00000000..a267527d --- /dev/null +++ b/fast/stages/2-networking-a-peering/data/hierarchical-ingress-rules.yaml @@ -0,0 +1,37 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + priority: 1000 + match: + source_ranges: + - rfc1918 + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + priority: 1001 + match: + source_ranges: + - healthchecks + layer4_configs: + - protocol: tcp + ports: ["80", "443"] + +allow-ssh-from-iap: + description: Enable SSH from IAP + priority: 1002 + match: + source_ranges: + - 35.235.240.0/20 + layer4_configs: + - protocol: tcp + ports: ["22"] + +allow-icmp: + description: Enable ICMP + priority: 1003 + match: + source_ranges: + - 0.0.0.0/0 + layer4_configs: + - protocol: icmp diff --git a/fast/stages/2-networking-a-peering/data/hierarchical-policy-rules.yaml b/fast/stages/2-networking-a-peering/data/hierarchical-policy-rules.yaml deleted file mode 100644 index 0172a309..00000000 --- a/fast/stages/2-networking-a-peering/data/hierarchical-policy-rules.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# skip boilerplate check - -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-healthchecks: - description: Enable HTTP and HTTPS healthchecks - direction: INGRESS - action: allow - priority: 1001 - ranges: - - $healthchecks - ports: - tcp: ["80", "443"] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false - -allow-icmp: - description: Enable ICMP - direction: INGRESS - action: allow - priority: 1003 - ranges: - - 0.0.0.0/0 - ports: - icmp: [] - target_resources: null - enable_logging: false diff --git a/fast/stages/2-networking-a-peering/main.tf b/fast/stages/2-networking-a-peering/main.tf index 5888752d..8a47a0d5 100644 --- a/fast/stages/2-networking-a-peering/main.tf +++ b/fast/stages/2-networking-a-peering/main.tf @@ -45,13 +45,18 @@ module "folder" { name = "Networking" folder_create = var.folder_ids.networking == null id = var.folder_ids.networking - firewall_policy_factory = { - cidr_file = "${var.factories_config.data_dir}/cidrs.yaml" - policy_name = var.factories_config.firewall_policy_name - rules_file = "${var.factories_config.data_dir}/hierarchical-policy-rules.yaml" - } - firewall_policy_association = { - factory-policy = "factory" + firewall_policy_associations = { + default = module.firewall-policy-default.id + } +} + +module "firewall-policy-default" { + source = "../../../modules/net-firewall-policy" + name = "net-default" + parent_id = module.folder.id + rules_factory_config = { + cidr_file_path = "${var.factories_config.data_dir}/cidrs.yaml" + ingress_rules_file_path = "${var.factories_config.data_dir}/hierarchical-ingress-rules.yaml" } } diff --git a/fast/stages/2-networking-b-vpn/README.md b/fast/stages/2-networking-b-vpn/README.md index 75d8d91a..1f43b180 100644 --- a/fast/stages/2-networking-b-vpn/README.md +++ b/fast/stages/2-networking-b-vpn/README.md @@ -186,7 +186,7 @@ BGP sessions for landing-spoke are configured through variable `vpn_spoke_config **VPC firewall rules** ([`net-vpc-firewall`](../../../modules/net-vpc-firewall)) are defined per-vpc on each `vpc-*.tf` file and leverage a resource factory to massively create rules. To add a new firewall rule, create a new file or edit an existing one in the `data_folder` directory defined in the module `net-vpc-firewall`, following the examples of the "[Rules factory](../../../modules/net-vpc-firewall#rules-factory)" section of the module documentation. Sample firewall rules are shipped in [data/firewall-rules/landing](./data/firewall-rules/landing) and can be easily customised. -**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf`, and managed through a policy factory implemented by the `folder` module, which applies the defined hierarchical to the `Networking` folder, which contains all the core networking infrastructure. Policies are defined in the `rules_file` file - to define a new one simply use the instructions found on "[Firewall policy factory](../../../modules/organization#firewall-policy-factory)". Sample hierarchical firewall policies are shipped in [data/hierarchical-policy-rules.yaml](./data/hierarchical-policy-rules.yaml) and can be easily customised. +**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf` and managed through a policy factory implemented by the `net-firewall-policy` module, which is then applied to the `Networking` folder containing all the core networking infrastructure. Policies are defined in the `rules_file` file, to define a new one simply use the [firewall policy module documentation](../../../modules/net-firewall-policy/README.md#factory)". Sample hierarchical firewall rules are shipped in [data/hierarchical-ingress-rules.yaml](./data/hierarchical-ingress-rules.yaml) and can be easily customised. ### DNS architecture @@ -393,7 +393,6 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS - ## Files | name | description | modules | resources | @@ -402,7 +401,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | | | [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | | | [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | | -| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | | +| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder · net-firewall-policy | | | [monitoring-vpn.tf](./monitoring-vpn.tf) | VPN monitoring alerts. | | google_monitoring_alert_policy | | [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard | | [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object · local_file | @@ -447,5 +446,4 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [shared_vpc_self_links](outputs.tf#L78) | Shared VPC host projects. | | | | [tfvars](outputs.tf#L83) | Terraform variables file for the following stages. | ✓ | | | [vpn_gateway_endpoints](outputs.tf#L89) | External IP Addresses for the GCP VPN gateways. | | | - diff --git a/fast/stages/2-networking-b-vpn/data/hierarchical-ingress-rules.yaml b/fast/stages/2-networking-b-vpn/data/hierarchical-ingress-rules.yaml new file mode 100644 index 00000000..a267527d --- /dev/null +++ b/fast/stages/2-networking-b-vpn/data/hierarchical-ingress-rules.yaml @@ -0,0 +1,37 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + priority: 1000 + match: + source_ranges: + - rfc1918 + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + priority: 1001 + match: + source_ranges: + - healthchecks + layer4_configs: + - protocol: tcp + ports: ["80", "443"] + +allow-ssh-from-iap: + description: Enable SSH from IAP + priority: 1002 + match: + source_ranges: + - 35.235.240.0/20 + layer4_configs: + - protocol: tcp + ports: ["22"] + +allow-icmp: + description: Enable ICMP + priority: 1003 + match: + source_ranges: + - 0.0.0.0/0 + layer4_configs: + - protocol: icmp diff --git a/fast/stages/2-networking-b-vpn/data/hierarchical-policy-rules.yaml b/fast/stages/2-networking-b-vpn/data/hierarchical-policy-rules.yaml deleted file mode 100644 index 0172a309..00000000 --- a/fast/stages/2-networking-b-vpn/data/hierarchical-policy-rules.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# skip boilerplate check - -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-healthchecks: - description: Enable HTTP and HTTPS healthchecks - direction: INGRESS - action: allow - priority: 1001 - ranges: - - $healthchecks - ports: - tcp: ["80", "443"] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false - -allow-icmp: - description: Enable ICMP - direction: INGRESS - action: allow - priority: 1003 - ranges: - - 0.0.0.0/0 - ports: - icmp: [] - target_resources: null - enable_logging: false diff --git a/fast/stages/2-networking-b-vpn/main.tf b/fast/stages/2-networking-b-vpn/main.tf index 5888752d..8a47a0d5 100644 --- a/fast/stages/2-networking-b-vpn/main.tf +++ b/fast/stages/2-networking-b-vpn/main.tf @@ -45,13 +45,18 @@ module "folder" { name = "Networking" folder_create = var.folder_ids.networking == null id = var.folder_ids.networking - firewall_policy_factory = { - cidr_file = "${var.factories_config.data_dir}/cidrs.yaml" - policy_name = var.factories_config.firewall_policy_name - rules_file = "${var.factories_config.data_dir}/hierarchical-policy-rules.yaml" - } - firewall_policy_association = { - factory-policy = "factory" + firewall_policy_associations = { + default = module.firewall-policy-default.id + } +} + +module "firewall-policy-default" { + source = "../../../modules/net-firewall-policy" + name = "net-default" + parent_id = module.folder.id + rules_factory_config = { + cidr_file_path = "${var.factories_config.data_dir}/cidrs.yaml" + ingress_rules_file_path = "${var.factories_config.data_dir}/hierarchical-ingress-rules.yaml" } } diff --git a/fast/stages/2-networking-c-nva/README.md b/fast/stages/2-networking-c-nva/README.md index a0f918a0..a587d68c 100644 --- a/fast/stages/2-networking-c-nva/README.md +++ b/fast/stages/2-networking-c-nva/README.md @@ -254,7 +254,7 @@ BGP sessions for trusted landing to on-premises are configured through the varia **VPC firewall rules** ([`net-vpc-firewall`](../../../modules/net-vpc-firewall)) are defined per-vpc on each `vpc-*.tf` file and leverage a resource factory to massively create rules. To add a new firewall rule, create a new file or edit an existing one in the `data_folder` directory defined in the module `net-vpc-firewall`, following the examples of the "[Rules factory](../../../modules/net-vpc-firewall#rules-factory)" section of the module documentation. Sample firewall rules are shipped in [data/firewall-rules/landing-untrusted](./data/firewall-rules/landing-untrusted) and in [data/firewall-rules/landing-trusted](./data/firewall-rules/landing-trusted), and can be easily customized. -**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf`, and managed through a policy factory implemented by the `folder` module, which applies the defined hierarchical to the `Networking` folder, which contains all the core networking infrastructure. Policies are defined in the `rules_file` file - to define a new one simply use the instructions found on "[Firewall policy factory](../../../modules/organization#firewall-policy-factory)". Sample hierarchical firewall policies are shipped in [data/hierarchical-policy-rules.yaml](./data/hierarchical-policy-rules.yaml) and can be easily customized. +**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf` and managed through a policy factory implemented by the `net-firewall-policy` module, which is then applied to the `Networking` folder containing all the core networking infrastructure. Policies are defined in the `rules_file` file, to define a new one simply use the [firewall policy module documentation](../../../modules/net-firewall-policy/README.md#factory)". Sample hierarchical firewall rules are shipped in [data/hierarchical-ingress-rules.yaml](./data/hierarchical-ingress-rules.yaml) and can be easily customised. ### DNS architecture @@ -452,7 +452,6 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS - ## Files | name | description | modules | resources | @@ -461,7 +460,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | | | [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | | | [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | | -| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | | +| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder · net-firewall-policy | | | [monitoring-vpn-onprem.tf](./monitoring-vpn-onprem.tf) | VPN monitoring alerts. | | google_monitoring_alert_policy | | [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard | | [nva.tf](./nva.tf) | None | compute-mig · compute-vm · simple-nva | | @@ -504,5 +503,4 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [shared_vpc_self_links](outputs.tf#L68) | Shared VPC host projects. | | | | [tfvars](outputs.tf#L73) | Terraform variables file for the following stages. | ✓ | | | [vpn_gateway_endpoints](outputs.tf#L79) | External IP Addresses for the GCP VPN gateways. | | | - diff --git a/fast/stages/2-networking-c-nva/data/hierarchical-ingress-rules.yaml b/fast/stages/2-networking-c-nva/data/hierarchical-ingress-rules.yaml new file mode 100644 index 00000000..a267527d --- /dev/null +++ b/fast/stages/2-networking-c-nva/data/hierarchical-ingress-rules.yaml @@ -0,0 +1,37 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + priority: 1000 + match: + source_ranges: + - rfc1918 + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + priority: 1001 + match: + source_ranges: + - healthchecks + layer4_configs: + - protocol: tcp + ports: ["80", "443"] + +allow-ssh-from-iap: + description: Enable SSH from IAP + priority: 1002 + match: + source_ranges: + - 35.235.240.0/20 + layer4_configs: + - protocol: tcp + ports: ["22"] + +allow-icmp: + description: Enable ICMP + priority: 1003 + match: + source_ranges: + - 0.0.0.0/0 + layer4_configs: + - protocol: icmp diff --git a/fast/stages/2-networking-c-nva/data/hierarchical-policy-rules.yaml b/fast/stages/2-networking-c-nva/data/hierarchical-policy-rules.yaml deleted file mode 100644 index 0172a309..00000000 --- a/fast/stages/2-networking-c-nva/data/hierarchical-policy-rules.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# skip boilerplate check - -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-healthchecks: - description: Enable HTTP and HTTPS healthchecks - direction: INGRESS - action: allow - priority: 1001 - ranges: - - $healthchecks - ports: - tcp: ["80", "443"] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false - -allow-icmp: - description: Enable ICMP - direction: INGRESS - action: allow - priority: 1003 - ranges: - - 0.0.0.0/0 - ports: - icmp: [] - target_resources: null - enable_logging: false diff --git a/fast/stages/2-networking-c-nva/main.tf b/fast/stages/2-networking-c-nva/main.tf index 0a56396e..aff2eaf5 100644 --- a/fast/stages/2-networking-c-nva/main.tf +++ b/fast/stages/2-networking-c-nva/main.tf @@ -46,12 +46,17 @@ module "folder" { name = "Networking" folder_create = var.folder_ids.networking == null id = var.folder_ids.networking - firewall_policy_factory = { - cidr_file = "${var.factories_config.data_dir}/cidrs.yaml" - policy_name = var.factories_config.firewall_policy_name - rules_file = "${var.factories_config.data_dir}/hierarchical-policy-rules.yaml" - } - firewall_policy_association = { - factory-policy = var.factories_config.firewall_policy_name + firewall_policy_associations = { + default = module.firewall-policy-default.id + } +} + +module "firewall-policy-default" { + source = "../../../modules/net-firewall-policy" + name = "net-default" + parent_id = module.folder.id + rules_factory_config = { + cidr_file_path = "${var.factories_config.data_dir}/cidrs.yaml" + ingress_rules_file_path = "${var.factories_config.data_dir}/hierarchical-ingress-rules.yaml" } } diff --git a/fast/stages/2-networking-d-separate-envs/README.md b/fast/stages/2-networking-d-separate-envs/README.md index 1276799b..eae0eaf4 100644 --- a/fast/stages/2-networking-d-separate-envs/README.md +++ b/fast/stages/2-networking-d-separate-envs/README.md @@ -137,7 +137,7 @@ Static routes are defined in `net-*.tf` files, in the `routes` section of each ` **VPC firewall rules** ([`net-vpc-firewall`](../../../modules/net-vpc-firewall)) are defined per-vpc on each `net-*.tf` file and leverage a resource factory to massively create rules. To add a new firewall rule, create a new file or edit an existing one in the `data_folder` directory defined in the module `net-vpc-firewall`, following the examples of the "[Rules factory](../../../modules/net-vpc-firewall#rules-factory)" section of the module documentation. Sample firewall rules are shipped in [data/firewall-rules/dev](./data/firewall-rules/dev) and can be easily customised. -**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf`, and managed through a policy factory implemented by the `folder` module, which applies the defined hierarchical to the `Networking` folder, which contains all the core networking infrastructure. Policies are defined in the `rules_file` file - to define a new one simply use the instructions found on "[Firewall policy factory](../../../modules/organization#firewall-policy-factory)". Sample hierarchical firewall policies are shipped in [data/hierarchical-policy-rules.yaml](./data/hierarchical-policy-rules.yaml) and can be easily customised. +**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf` and managed through a policy factory implemented by the `net-firewall-policy` module, which is then applied to the `Networking` folder containing all the core networking infrastructure. Policies are defined in the `rules_file` file, to define a new one simply use the [firewall policy module documentation](../../../modules/net-firewall-policy/README.md#factory)". Sample hierarchical firewall rules are shipped in [data/hierarchical-ingress-rules.yaml](./data/hierarchical-ingress-rules.yaml) and can be easily customised. ### DNS architecture @@ -317,14 +317,13 @@ Regions are defined via the `regions` variable which sets up a mapping between t - ## Files | name | description | modules | resources | |---|---|---|---| | [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns · dns-response-policy | | | [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns · dns-response-policy | | -| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | | +| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder · net-firewall-policy | | | [monitoring-vpn-onprem.tf](./monitoring-vpn-onprem.tf) | VPN monitoring alerts. | | google_monitoring_alert_policy | | [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard | | [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object · local_file | @@ -366,5 +365,4 @@ Regions are defined via the `regions` variable which sets up a mapping between t | [shared_vpc_self_links](outputs.tf#L79) | Shared VPC host projects. | | | | [tfvars](outputs.tf#L84) | Terraform variables file for the following stages. | ✓ | | | [vpn_gateway_endpoints](outputs.tf#L90) | External IP Addresses for the GCP VPN gateways. | | | - diff --git a/fast/stages/2-networking-d-separate-envs/data/hierarchical-ingress-rules.yaml b/fast/stages/2-networking-d-separate-envs/data/hierarchical-ingress-rules.yaml new file mode 100644 index 00000000..a267527d --- /dev/null +++ b/fast/stages/2-networking-d-separate-envs/data/hierarchical-ingress-rules.yaml @@ -0,0 +1,37 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + priority: 1000 + match: + source_ranges: + - rfc1918 + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + priority: 1001 + match: + source_ranges: + - healthchecks + layer4_configs: + - protocol: tcp + ports: ["80", "443"] + +allow-ssh-from-iap: + description: Enable SSH from IAP + priority: 1002 + match: + source_ranges: + - 35.235.240.0/20 + layer4_configs: + - protocol: tcp + ports: ["22"] + +allow-icmp: + description: Enable ICMP + priority: 1003 + match: + source_ranges: + - 0.0.0.0/0 + layer4_configs: + - protocol: icmp diff --git a/fast/stages/2-networking-d-separate-envs/data/hierarchical-policy-rules.yaml b/fast/stages/2-networking-d-separate-envs/data/hierarchical-policy-rules.yaml deleted file mode 100644 index 0172a309..00000000 --- a/fast/stages/2-networking-d-separate-envs/data/hierarchical-policy-rules.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# skip boilerplate check - -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-healthchecks: - description: Enable HTTP and HTTPS healthchecks - direction: INGRESS - action: allow - priority: 1001 - ranges: - - $healthchecks - ports: - tcp: ["80", "443"] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false - -allow-icmp: - description: Enable ICMP - direction: INGRESS - action: allow - priority: 1003 - ranges: - - 0.0.0.0/0 - ports: - icmp: [] - target_resources: null - enable_logging: false diff --git a/fast/stages/2-networking-d-separate-envs/main.tf b/fast/stages/2-networking-d-separate-envs/main.tf index 7e9ddc26..5145e186 100644 --- a/fast/stages/2-networking-d-separate-envs/main.tf +++ b/fast/stages/2-networking-d-separate-envs/main.tf @@ -41,13 +41,17 @@ module "folder" { name = "Networking" folder_create = var.folder_ids.networking == null id = var.folder_ids.networking - firewall_policy_factory = { - cidr_file = "${var.factories_config.data_dir}/cidrs.yaml" - policy_name = var.factories_config.firewall_policy_name - rules_file = "${var.factories_config.data_dir}/hierarchical-policy-rules.yaml" - } - firewall_policy_association = { - factory-policy = var.factories_config.firewall_policy_name + firewall_policy_associations = { + default = module.firewall-policy-default.id } } +module "firewall-policy-default" { + source = "../../../modules/net-firewall-policy" + name = "net-default" + parent_id = module.folder.id + rules_factory_config = { + cidr_file_path = "${var.factories_config.data_dir}/cidrs.yaml" + ingress_rules_file_path = "${var.factories_config.data_dir}/hierarchical-ingress-rules.yaml" + } +} diff --git a/fast/stages/2-networking-e-nva-bgp/README.md b/fast/stages/2-networking-e-nva-bgp/README.md index c5117b5d..a9f444e1 100644 --- a/fast/stages/2-networking-e-nva-bgp/README.md +++ b/fast/stages/2-networking-e-nva-bgp/README.md @@ -276,7 +276,7 @@ BGP sessions for trusted landing to on-premises are configured through the varia **VPC firewall rules** ([`net-vpc-firewall`](../../../modules/net-vpc-firewall)) are defined per-vpc on each `vpc-*.tf` file and leverage a resource factory to massively create rules. To add a new firewall rule, create a new file or edit an existing one in the `data_folder` directory defined in the module `net-vpc-firewall`, following the examples of the "[Rules factory](../../../modules/net-vpc-firewall#rules-factory)" section of the module documentation. Sample firewall rules are shipped in [data/firewall-rules/landing-untrusted](./data/firewall-rules/landing-untrusted) and in [data/firewall-rules/landing-trusted](./data/firewall-rules/landing-trusted), and can be easily customized. -**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf`, and managed through a policy factory implemented by the `folder` module, which applies the defined hierarchical to the `Networking` folder, which contains all the core networking infrastructure. Policies are defined in the `rules_file` file - to define a new one simply use the instructions found on "[Firewall policy factory](../../../modules/organization#firewall-policy-factory)". Sample hierarchical firewall policies are shipped in [data/hierarchical-policy-rules.yaml](./data/hierarchical-policy-rules.yaml) and can be easily customized. +**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf` and managed through a policy factory implemented by the `net-firewall-policy` module, which is then applied to the `Networking` folder containing all the core networking infrastructure. Policies are defined in the `rules_file` file, to define a new one simply use the [firewall policy module documentation](../../../modules/net-firewall-policy/README.md#factory)". Sample hierarchical firewall rules are shipped in [data/hierarchical-ingress-rules.yaml](./data/hierarchical-ingress-rules.yaml) and can be easily customised. ### DNS architecture @@ -476,7 +476,6 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS - ## Files | name | description | modules | resources | @@ -485,7 +484,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | | | [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | | | [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | | -| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | | +| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder · net-firewall-policy | | | [monitoring-vpn-onprem.tf](./monitoring-vpn-onprem.tf) | VPN monitoring alerts. | | google_monitoring_alert_policy | | [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard | | [ncc.tf](./ncc.tf) | None | ncc-spoke-ra | | @@ -531,5 +530,4 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [shared_vpc_self_links](outputs.tf#L68) | Shared VPC host projects. | | | | [tfvars](outputs.tf#L73) | Terraform variables file for the following stages. | ✓ | | | [vpn_gateway_endpoints](outputs.tf#L79) | External IP Addresses for the GCP VPN gateways. | | | - diff --git a/fast/stages/2-networking-e-nva-bgp/data/hierarchical-ingress-rules.yaml b/fast/stages/2-networking-e-nva-bgp/data/hierarchical-ingress-rules.yaml new file mode 100644 index 00000000..a267527d --- /dev/null +++ b/fast/stages/2-networking-e-nva-bgp/data/hierarchical-ingress-rules.yaml @@ -0,0 +1,37 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + priority: 1000 + match: + source_ranges: + - rfc1918 + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + priority: 1001 + match: + source_ranges: + - healthchecks + layer4_configs: + - protocol: tcp + ports: ["80", "443"] + +allow-ssh-from-iap: + description: Enable SSH from IAP + priority: 1002 + match: + source_ranges: + - 35.235.240.0/20 + layer4_configs: + - protocol: tcp + ports: ["22"] + +allow-icmp: + description: Enable ICMP + priority: 1003 + match: + source_ranges: + - 0.0.0.0/0 + layer4_configs: + - protocol: icmp diff --git a/fast/stages/2-networking-e-nva-bgp/data/hierarchical-policy-rules.yaml b/fast/stages/2-networking-e-nva-bgp/data/hierarchical-policy-rules.yaml deleted file mode 100644 index 0172a309..00000000 --- a/fast/stages/2-networking-e-nva-bgp/data/hierarchical-policy-rules.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# skip boilerplate check - -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-healthchecks: - description: Enable HTTP and HTTPS healthchecks - direction: INGRESS - action: allow - priority: 1001 - ranges: - - $healthchecks - ports: - tcp: ["80", "443"] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false - -allow-icmp: - description: Enable ICMP - direction: INGRESS - action: allow - priority: 1003 - ranges: - - 0.0.0.0/0 - ports: - icmp: [] - target_resources: null - enable_logging: false diff --git a/fast/stages/2-networking-e-nva-bgp/main.tf b/fast/stages/2-networking-e-nva-bgp/main.tf index 0a56396e..aff2eaf5 100644 --- a/fast/stages/2-networking-e-nva-bgp/main.tf +++ b/fast/stages/2-networking-e-nva-bgp/main.tf @@ -46,12 +46,17 @@ module "folder" { name = "Networking" folder_create = var.folder_ids.networking == null id = var.folder_ids.networking - firewall_policy_factory = { - cidr_file = "${var.factories_config.data_dir}/cidrs.yaml" - policy_name = var.factories_config.firewall_policy_name - rules_file = "${var.factories_config.data_dir}/hierarchical-policy-rules.yaml" - } - firewall_policy_association = { - factory-policy = var.factories_config.firewall_policy_name + firewall_policy_associations = { + default = module.firewall-policy-default.id + } +} + +module "firewall-policy-default" { + source = "../../../modules/net-firewall-policy" + name = "net-default" + parent_id = module.folder.id + rules_factory_config = { + cidr_file_path = "${var.factories_config.data_dir}/cidrs.yaml" + ingress_rules_file_path = "${var.factories_config.data_dir}/hierarchical-ingress-rules.yaml" } } diff --git a/modules/README.md b/modules/README.md index 653c25e8..c100fcc5 100644 --- a/modules/README.md +++ b/modules/README.md @@ -45,6 +45,7 @@ These modules are used in the examples included in this repository. If you are u - [Cloud Endpoints](./endpoints) - [DNS](./dns) - [DNS Response Policy](./dns-response-policy/) +- [Firewall policy](./net-firewall-policy) - [External Application Load Balancer](./net-lb-app-ext/) - [External Passthrough Network Load Balancer](./net-lb-ext) - [Internal Application Load Balancer](./net-lb-app-int) @@ -55,7 +56,6 @@ These modules are used in the examples included in this repository. If you are u - [Service Directory](./service-directory) - [VPC](./net-vpc) - [VPC firewall](./net-vpc-firewall) -- [VPC firewall policy](./net-vpc-firewall-policy) - [VPN dynamic](./net-vpn-dynamic) - [VPC peering](./net-vpc-peering) - [VPN HA](./net-vpn-ha) diff --git a/modules/folder/README.md b/modules/folder/README.md index 04e5b8d2..85f00c3e 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -2,15 +2,12 @@ This module allows the creation and management of folders, including support for IAM bindings, organization policies, and hierarchical firewall rules. - - [Basic example with IAM bindings](#basic-example-with-iam-bindings) - [IAM](#iam) - [Organization policies](#organization-policies) - [Organization Policy Factory](#organization-policy-factory) -- [Hierarchical Firewall Policies](#hierarchical-firewall-policies) - - [Directly Defined Firewall Policies](#directly-defined-firewall-policies) - - [Firewall Policy Factory](#firewall-policy-factory) +- [Hierarchical Firewall Policy Attachments](#hierarchical-firewall-policy-attachments) - [Log Sinks](#log-sinks) - [Data Access Logs](#data-access-logs) - [Tags](#tags) @@ -121,128 +118,31 @@ module "folder" { See the [organization policy factory in the project module](../project#organization-policy-factory). -## Hierarchical Firewall Policies +## Hierarchical Firewall Policy Attachments -Hierarchical firewall policies can be managed in two ways: - -- via the `firewall_policies` variable, to directly define policies and rules in Terraform -- via the `firewall_policy_factory` variable, to leverage external YaML files via a simple "factory" embedded in the module ([see here](../../blueprints/factories) for more context on factories) - -Once you have policies (either created via the module or externally), you can associate them using the `firewall_policy_association` variable. - -### Directly Defined Firewall Policies +Hierarchical firewall policies can be managed via the [`net-firewall-policy`](../net-firewall-policy/) module, including support for factories. Once a policy is available, attaching it to the organization can be done either in the firewall policy module itself, or here: ```hcl -module "folder1" { - source = "./fabric/modules/folder" - parent = var.organization_id - name = "policy-container" - - firewall_policies = { - iap-policy = { - allow-admins = { - description = "Access from the admin subnet to all subnets" - direction = "INGRESS" - action = "allow" - priority = 1000 - ranges = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] - ports = { all = [] } - target_service_accounts = null - target_resources = null - logging = false - } - allow-iap-ssh = { - description = "Always allow ssh from IAP" - direction = "INGRESS" - action = "allow" - priority = 100 - ranges = ["35.235.240.0/20"] - ports = { tcp = ["22"] } - target_service_accounts = null - target_resources = null - logging = false - } - } - } - firewall_policy_association = { - iap-policy = "iap-policy" - } +module "firewall-policy" { + source = "./fabric/modules/net-firewall-policy" + name = "test-1" + parent_id = module.folder.id + # attachment via the firewall policy module + # attachments = { + # folder-1 = module.folder.id + # } } -module "folder2" { +module "folder" { source = "./fabric/modules/folder" - parent = var.organization_id - name = "hf2" - firewall_policy_association = { - iap-policy = module.folder1.firewall_policy_id["iap-policy"] + parent = "organizations/1234567890" + name = "Folder name" + # attachment via the organization module + firewall_policy_associations = { + test-1 = module.firewall-policy.id } } -# tftest modules=2 resources=7 inventory=hfw.yaml -``` - -### Firewall Policy Factory - -The in-built factory allows you to define a single policy, using one file for rules, and an optional file for CIDR range substitution variables. Remember that non-absolute paths are relative to the root module (the folder where you run `terraform`). - -```hcl -module "folder1" { - source = "./fabric/modules/folder" - parent = var.organization_id - name = "policy-container" - firewall_policy_factory = { - cidr_file = "configs/firewall-policies/cidrs.yaml" - policy_name = "iap-policy" - rules_file = "configs/firewall-policies/rules.yaml" - } - firewall_policy_association = { - iap-policy = "iap-policy" - } -} - -module "folder2" { - source = "./fabric/modules/folder" - parent = var.organization_id - name = "hf2" - firewall_policy_association = { - iap-policy = module.folder1.firewall_policy_id["iap-policy"] - } -} -# tftest modules=2 resources=7 files=cidrs,rules inventory=hfw.yaml -``` - -```yaml -# tftest-file id=cidrs path=configs/firewall-policies/cidrs.yaml -rfc1918: - - 10.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 -``` - -```yaml -# tftest-file id=rules path=configs/firewall-policies/rules.yaml -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - logging: false - -allow-iap-ssh: - description: "Always allow ssh from IAP" - direction: INGRESS - action: allow - priority: 100 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - logging: false +# tftest modules=2 resources=3 ``` ## Log Sinks @@ -395,15 +295,13 @@ module "folder" { - ## Files | name | description | resources | |---|---|---| -| [firewall-policies.tf](./firewall-policies.tf) | None | google_compute_firewall_policy · google_compute_firewall_policy_association · google_compute_firewall_policy_rule | | [iam.tf](./iam.tf) | IAM bindings, roles and audit logging resources. | google_folder_iam_binding · google_folder_iam_member · google_folder_iam_policy | | [logging.tf](./logging.tf) | Log sinks and supporting resources. | google_bigquery_dataset_iam_member · google_folder_iam_audit_config · google_logging_folder_exclusion · google_logging_folder_sink · google_project_iam_member · google_pubsub_topic_iam_member · google_storage_bucket_iam_member | -| [main.tf](./main.tf) | Module-level locals and resources. | google_essential_contacts_contact · google_folder | +| [main.tf](./main.tf) | Module-level locals and resources. | google_compute_firewall_policy_association · google_essential_contacts_contact · google_folder | | [organization-policies.tf](./organization-policies.tf) | Folder-level organization policies. | google_org_policy_policy | | [outputs.tf](./outputs.tf) | Module outputs. | | | [tags.tf](./tags.tf) | None | google_tags_tag_binding | @@ -415,34 +313,29 @@ module "folder" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| | [contacts](variables.tf#L17) | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES. | map(list(string)) | | {} | -| [firewall_policies](variables.tf#L24) | Hierarchical firewall policies created in this folder. | map(map(object({…}))) | | {} | -| [firewall_policy_association](variables.tf#L41) | The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else. | map(string) | | {} | -| [firewall_policy_factory](variables.tf#L48) | Configuration for the firewall policy factory. | object({…}) | | null | -| [folder_create](variables.tf#L58) | Create folder. When set to false, uses id to reference an existing folder. | bool | | true | -| [group_iam](variables.tf#L64) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | map(list(string)) | | {} | -| [iam](variables.tf#L71) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [iam_additive](variables.tf#L78) | Non authoritative IAM bindings, in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [iam_additive_members](variables.tf#L85) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string)) | | {} | -| [iam_policy](variables.tf#L92) | IAM authoritative policy in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared, use with extreme caution. | map(list(string)) | | null | -| [id](variables.tf#L98) | Folder ID in case you use folder_create=false. | string | | null | -| [logging_data_access](variables.tf#L104) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | map(map(list(string))) | | {} | -| [logging_exclusions](variables.tf#L119) | Logging exclusions for this folder in the form {NAME -> FILTER}. | map(string) | | {} | -| [logging_sinks](variables.tf#L126) | Logging sinks to create for the organization. | map(object({…})) | | {} | -| [name](variables.tf#L156) | Folder name. | string | | null | -| [org_policies](variables.tf#L162) | Organization policies applied to this folder keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L189) | Path containing org policies in YAML format. | string | | null | -| [parent](variables.tf#L195) | Parent in folders/folder_id or organizations/org_id format. | string | | null | -| [tag_bindings](variables.tf#L205) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null | +| [firewall_policy_associations](variables.tf#L24) | Hierarchical firewall policies to associate to this folder, in association name => policy id format. | map(string) | | {} | +| [folder_create](variables.tf#L31) | Create folder. When set to false, uses id to reference an existing folder. | bool | | true | +| [group_iam](variables.tf#L37) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | map(list(string)) | | {} | +| [iam](variables.tf#L44) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [iam_additive](variables.tf#L51) | Non authoritative IAM bindings, in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [iam_additive_members](variables.tf#L58) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string)) | | {} | +| [iam_policy](variables.tf#L65) | IAM authoritative policy in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared, use with extreme caution. | map(list(string)) | | null | +| [id](variables.tf#L71) | Folder ID in case you use folder_create=false. | string | | null | +| [logging_data_access](variables.tf#L77) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | map(map(list(string))) | | {} | +| [logging_exclusions](variables.tf#L92) | Logging exclusions for this folder in the form {NAME -> FILTER}. | map(string) | | {} | +| [logging_sinks](variables.tf#L99) | Logging sinks to create for the organization. | map(object({…})) | | {} | +| [name](variables.tf#L129) | Folder name. | string | | null | +| [org_policies](variables.tf#L135) | Organization policies applied to this folder keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L162) | Path containing org policies in YAML format. | string | | null | +| [parent](variables.tf#L168) | Parent in folders/folder_id or organizations/org_id format. | string | | null | +| [tag_bindings](variables.tf#L178) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null | ## Outputs | name | description | sensitive | |---|---|:---:| -| [firewall_policies](outputs.tf#L16) | Map of firewall policy resources created in this folder. | | -| [firewall_policy_id](outputs.tf#L21) | Map of firewall policy ids created in this folder. | | -| [folder](outputs.tf#L26) | Folder resource. | | -| [id](outputs.tf#L31) | Fully qualified folder id. | | -| [name](outputs.tf#L41) | Folder name. | | -| [sink_writer_identities](outputs.tf#L46) | Writer identities created for each sink. | | - +| [folder](outputs.tf#L17) | Folder resource. | | +| [id](outputs.tf#L22) | Fully qualified folder id. | | +| [name](outputs.tf#L32) | Folder name. | | +| [sink_writer_identities](outputs.tf#L37) | Writer identities created for each sink. | | diff --git a/modules/folder/firewall-policies.tf b/modules/folder/firewall-policies.tf deleted file mode 100644 index 96224c56..00000000 --- a/modules/folder/firewall-policies.tf +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright 2022 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 { - _factory_cidrs = try( - yamldecode(file(var.firewall_policy_factory.cidr_file)), {} - ) - _factory_name = ( - try(var.firewall_policy_factory.policy_name, null) == null - ? "factory" - : var.firewall_policy_factory.policy_name - ) - _factory_rules = try( - yamldecode(file(var.firewall_policy_factory.rules_file)), {} - ) - _factory_rules_parsed = { - for name, rule in local._factory_rules : name => merge(rule, { - ranges = flatten([ - for r in(rule.ranges == null ? [] : rule.ranges) : - lookup(local._factory_cidrs, trimprefix(r, "$"), r) - ]) - }) - } - _merged_rules = flatten([ - for policy, rules in local.firewall_policies : [ - for name, rule in rules : merge(rule, { - policy = policy - name = name - }) - ] - ]) - firewall_policies = merge(var.firewall_policies, ( - length(local._factory_rules) == 0 - ? {} - : { (local._factory_name) = local._factory_rules_parsed } - )) - firewall_rules = { - for r in local._merged_rules : "${r.policy}-${r.name}" => r - } -} - -resource "google_compute_firewall_policy" "policy" { - for_each = local.firewall_policies - short_name = each.key - parent = local.folder.id -} - -resource "google_compute_firewall_policy_rule" "rule" { - for_each = local.firewall_rules - firewall_policy = google_compute_firewall_policy.policy[each.value.policy].id - action = each.value.action - direction = each.value.direction - priority = try(each.value.priority, null) - target_resources = try(each.value.target_resources, null) - target_service_accounts = try(each.value.target_service_accounts, null) - enable_logging = try(each.value.logging, null) - # preview = each.value.preview - description = each.value.description - match { - src_ip_ranges = each.value.direction == "INGRESS" ? each.value.ranges : null - dest_ip_ranges = each.value.direction == "EGRESS" ? each.value.ranges : null - dynamic "layer4_configs" { - for_each = each.value.ports - iterator = port - content { - ip_protocol = port.key - ports = port.value - } - } - } -} - - -resource "google_compute_firewall_policy_association" "association" { - for_each = var.firewall_policy_association - name = replace(local.folder.id, "/", "-") - attachment_target = local.folder.id - firewall_policy = try(google_compute_firewall_policy.policy[each.value].id, each.value) -} - diff --git a/modules/folder/main.tf b/modules/folder/main.tf index 5d285d2d..e2a77321 100644 --- a/modules/folder/main.tf +++ b/modules/folder/main.tf @@ -41,3 +41,10 @@ resource "google_essential_contacts_contact" "contact" { language_tag = "en" notification_category_subscriptions = each.value } + +resource "google_compute_firewall_policy_association" "default" { + for_each = var.firewall_policy_associations + attachment_target = local.folder.id + name = each.key + firewall_policy = each.value +} diff --git a/modules/folder/outputs.tf b/modules/folder/outputs.tf index bf96c4c8..2a791d74 100644 --- a/modules/folder/outputs.tf +++ b/modules/folder/outputs.tf @@ -13,15 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -output "firewall_policies" { - description = "Map of firewall policy resources created in this folder." - value = { for k, v in google_compute_firewall_policy.policy : k => v } -} - -output "firewall_policy_id" { - description = "Map of firewall policy ids created in this folder." - value = { for k, v in google_compute_firewall_policy.policy : k => v.id } -} output "folder" { description = "Folder resource." diff --git a/modules/folder/variables.tf b/modules/folder/variables.tf index 284f0fd7..6fccce15 100644 --- a/modules/folder/variables.tf +++ b/modules/folder/variables.tf @@ -21,40 +21,13 @@ variable "contacts" { nullable = false } -variable "firewall_policies" { - description = "Hierarchical firewall policies created in this folder." - type = map(map(object({ - action = string - description = string - direction = string - logging = bool - ports = map(list(string)) - priority = number - ranges = list(string) - target_resources = list(string) - target_service_accounts = list(string) - }))) - default = {} - nullable = false -} - -variable "firewall_policy_association" { - description = "The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else." +variable "firewall_policy_associations" { + description = "Hierarchical firewall policies to associate to this folder, in association name => policy id format." type = map(string) default = {} nullable = false } -variable "firewall_policy_factory" { - description = "Configuration for the firewall policy factory." - type = object({ - cidr_file = string - policy_name = string - rules_file = string - }) - default = null -} - variable "folder_create" { description = "Create folder. When set to false, uses id to reference an existing folder." type = bool diff --git a/modules/net-vpc-firewall-policy/README.md b/modules/net-firewall-policy/README.md similarity index 94% rename from modules/net-vpc-firewall-policy/README.md rename to modules/net-firewall-policy/README.md index dd2b2064..ffdd15c2 100644 --- a/modules/net-vpc-firewall-policy/README.md +++ b/modules/net-firewall-policy/README.md @@ -9,13 +9,23 @@ The module also manages policy rules via code or a factory, and optional policy The module also makes fewer assumptions about implicit defaults, only using one to set `match.layer4_configs` to `[{ protocol = "all" }]` if no explicit set of protocols and ports has been specified. + +- [Examples](#examples) + - [Hierarchical Policy](#hierarchical-policy) + - [Global Network policy](#global-network-policy) + - [Regional Network policy](#regional-network-policy) + - [Factory](#factory) +- [Variables](#variables) +- [Outputs](#outputs) + + ## Examples ### Hierarchical Policy ```hcl module "firewall-policy" { - source = "./fabric/modules/net-vpc-firewall-policy" + source = "./fabric/modules/net-firewall-policy" name = "test-1" parent_id = "folders/1234567890" attachments = { @@ -67,9 +77,10 @@ module "vpc" { } module "firewall-policy" { - source = "./fabric/modules/net-vpc-firewall-policy" + source = "./fabric/modules/net-firewall-policy" name = "test-1" parent_id = "my-project" + region = "global" attachments = { my-vpc = module.vpc.self_link } @@ -119,7 +130,7 @@ module "vpc" { } module "firewall-policy" { - source = "./fabric/modules/net-vpc-firewall-policy" + source = "./fabric/modules/net-firewall-policy" name = "test-1" parent_id = "my-project" region = "europe-west8" @@ -164,7 +175,7 @@ This is an example of a simple factory: ```hcl module "firewall-policy" { - source = "./fabric/modules/net-vpc-firewall-policy" + source = "./fabric/modules/net-firewall-policy" name = "test-1" parent_id = "folders/1234567890" attachments = { @@ -219,7 +230,6 @@ icmp: layer4_configs: - protocol: icmp ``` - ## Variables @@ -231,7 +241,7 @@ icmp: | [description](variables.tf#L24) | Policy description. | string | | null | | [egress_rules](variables.tf#L30) | List of egress rule definitions, action can be 'allow', 'deny', 'goto_next'. The match.layer4configs map is in protocol => optional [ports] format. | map(object({…})) | | {} | | [ingress_rules](variables.tf#L71) | List of ingress rule definitions, action can be 'allow', 'deny', 'goto_next'. | map(object({…})) | | {} | -| [region](variables.tf#L125) | Policy region. Leave null for hierarchical policy, or global network policy. | string | | null | +| [region](variables.tf#L125) | Policy region. Leave null for hierarchical policy, set to 'global' for a global network policy. | string | | null | | [rules_factory_config](variables.tf#L131) | Configuration for the optional rules factory. | object({…}) | | {} | ## Outputs diff --git a/modules/net-vpc-firewall-policy/factory.tf b/modules/net-firewall-policy/factory.tf similarity index 89% rename from modules/net-vpc-firewall-policy/factory.tf rename to modules/net-firewall-policy/factory.tf index a0e655c7..cb567338 100644 --- a/modules/net-vpc-firewall-policy/factory.tf +++ b/modules/net-firewall-policy/factory.tf @@ -15,20 +15,14 @@ */ locals { - _factory_egress_rules = ( - var.rules_factory_config.egress_rules_file_path == null - ? {} - : yamldecode(file(var.rules_factory_config.egress_rules_file_path)) + _factory_egress_rules = try( + yamldecode(file(var.rules_factory_config.egress_rules_file_path)), {} ) - _factory_ingress_rules = ( - var.rules_factory_config.ingress_rules_file_path == null - ? {} - : yamldecode(file(var.rules_factory_config.ingress_rules_file_path)) + _factory_ingress_rules = try( + yamldecode(file(var.rules_factory_config.ingress_rules_file_path)), {} ) - factory_cidrs = ( - var.rules_factory_config.cidr_file_path == null - ? {} - : yamldecode(file(var.rules_factory_config.cidr_file_path)) + factory_cidrs = try( + yamldecode(file(var.rules_factory_config.cidr_file_path)), {} ) factory_egress_rules = { for k, v in local._factory_egress_rules : "ingress/${k}" => { diff --git a/modules/net-vpc-firewall-policy/hierarchical.tf b/modules/net-firewall-policy/hierarchical.tf similarity index 100% rename from modules/net-vpc-firewall-policy/hierarchical.tf rename to modules/net-firewall-policy/hierarchical.tf diff --git a/modules/net-vpc-firewall-policy/main.tf b/modules/net-firewall-policy/main.tf similarity index 84% rename from modules/net-vpc-firewall-policy/main.tf rename to modules/net-firewall-policy/main.tf index f253e221..093c8bf2 100644 --- a/modules/net-vpc-firewall-policy/main.tf +++ b/modules/net-firewall-policy/main.tf @@ -27,6 +27,7 @@ locals { local.factory_egress_rules, local.factory_ingress_rules, local._rules_egress, local._rules_ingress ) - use_hierarchical = strcontains(var.parent_id, "/") ? true : false - use_regional = !local.use_hierarchical && var.region != null + # do not depend on the parent id as that might be dynamic and prevent count + use_hierarchical = var.region == null + use_regional = !local.use_hierarchical && var.region != "global" } diff --git a/modules/net-vpc-firewall-policy/net-global.tf b/modules/net-firewall-policy/net-global.tf similarity index 100% rename from modules/net-vpc-firewall-policy/net-global.tf rename to modules/net-firewall-policy/net-global.tf diff --git a/modules/net-vpc-firewall-policy/net-regional.tf b/modules/net-firewall-policy/net-regional.tf similarity index 100% rename from modules/net-vpc-firewall-policy/net-regional.tf rename to modules/net-firewall-policy/net-regional.tf diff --git a/modules/net-vpc-firewall-policy/outputs.tf b/modules/net-firewall-policy/outputs.tf similarity index 71% rename from modules/net-vpc-firewall-policy/outputs.tf rename to modules/net-firewall-policy/outputs.tf index 44c0a7a6..0f16d2a6 100644 --- a/modules/net-vpc-firewall-policy/outputs.tf +++ b/modules/net-firewall-policy/outputs.tf @@ -16,9 +16,13 @@ output "id" { description = "Fully qualified firewall policy id." - value = coalesce([ - try(google_compute_firewall_policy.hierarchical.0.id, null), - try(google_compute_network_firewall_policy.net-global.0.id, null), - try(google_compute_region_network_firewall_policy.net-regional.0.id, null) - ]) + value = ( + local.use_hierarchical + ? google_compute_firewall_policy.hierarchical.0.id + : ( + local.use_regional + ? google_compute_region_network_firewall_policy.net-regional.0.id + : google_compute_network_firewall_policy.net-global.0.id + ) + ) } diff --git a/modules/net-vpc-firewall-policy/variables.tf b/modules/net-firewall-policy/variables.tf similarity index 98% rename from modules/net-vpc-firewall-policy/variables.tf rename to modules/net-firewall-policy/variables.tf index a1694d50..b7d48d96 100644 --- a/modules/net-vpc-firewall-policy/variables.tf +++ b/modules/net-firewall-policy/variables.tf @@ -123,7 +123,7 @@ variable "parent_id" { } variable "region" { - description = "Policy region. Leave null for hierarchical policy, or global network policy." + description = "Policy region. Leave null for hierarchical policy, set to 'global' for a global network policy." type = string default = null } diff --git a/modules/net-vpc-firewall-policy/versions.tf b/modules/net-firewall-policy/versions.tf similarity index 100% rename from modules/net-vpc-firewall-policy/versions.tf rename to modules/net-firewall-policy/versions.tf diff --git a/modules/organization/README.md b/modules/organization/README.md index cf1e64f8..7c4271ab 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -11,6 +11,7 @@ This module allows managing several organization properties: To manage organization policies, the `orgpolicy.googleapis.com` service should be enabled in the quota project. ## TOC + - [TOC](#toc) - [Example](#example) @@ -19,9 +20,7 @@ To manage organization policies, the `orgpolicy.googleapis.com` service should b - [Organization Policy Factory](#organization-policy-factory) - [Organization Policy Custom Constraints](#organization-policy-custom-constraints) - [Organization Policy Custom Constraints Factory](#organization-policy-custom-constraints-factory) -- [Hierarchical Firewall Policies](#hierarchical-firewall-policies) - - [Directly Defined Firewall Policies](#directly-defined-firewall-policies) - - [Firewall Policy Factory](#firewall-policy-factory) +- [Hierarchical Firewall Policy Attachments](#hierarchical-firewall-policy-attachments) - [Log Sinks](#log-sinks) - [Data Access Logs](#data-access-logs) - [Custom Roles](#custom-roles) @@ -226,109 +225,30 @@ custom.dataprocNoMoreThan10Workers: description: Cluster cannot have more than 10 workers, including primary and secondary workers. ``` -## Hierarchical Firewall Policies +## Hierarchical Firewall Policy Attachments -Hierarchical firewall policies can be managed in two ways: - -- via the `firewall_policies` variable, to directly define policies and rules in Terraform -- via the `firewall_policy_factory` variable, to leverage external YaML files via a simple "factory" embedded in the module ([see here](../../blueprints/factories) for more context on factories) - -Once you have policies (either created via the module or externally), you can associate them using the `firewall_policy_association` variable. - -### Directly Defined Firewall Policies +Hierarchical firewall policies can be managed via the [`net-firewall-policy`](../net-firewall-policy/) module, including support for factories. Once a policy is available, attaching it to the organization can be done either in the firewall policy module itself, or here: ```hcl +module "firewall-policy" { + source = "./fabric/modules/net-firewall-policy" + name = "test-1" + parent_id = var.organization_id + # attachment via the firewall policy module + # attachments = { + # org = var.organization_id + # } +} + module "org" { source = "./fabric/modules/organization" organization_id = var.organization_id - firewall_policies = { - iap-policy = { - allow-admins = { - description = "Access from the admin subnet to all subnets" - direction = "INGRESS" - action = "allow" - priority = 1000 - ranges = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] - ports = { all = [] } - target_service_accounts = null - target_resources = null - logging = false - } - allow-iap-ssh = { - description = "Always allow ssh from IAP." - direction = "INGRESS" - action = "allow" - priority = 100 - ranges = ["35.235.240.0/20"] - ports = { - tcp = ["22"] - } - target_service_accounts = null - target_resources = null - logging = false - } - } - } - firewall_policy_association = { - iap_policy = "iap-policy" + # attachment via the organization module + firewall_policy_associations = { + test-1 = module.firewall-policy.id } } -# tftest modules=1 resources=4 inventory=hfw.yaml -``` - -### Firewall Policy Factory - -The in-built factory allows you to define a single policy, using one file for rules, and an optional file for CIDR range substitution variables. Remember that non-absolute paths are relative to the root module (the folder where you run `terraform`). - -```hcl -module "org" { - source = "./fabric/modules/organization" - organization_id = var.organization_id - firewall_policy_factory = { - cidr_file = "configs/firewall-policies/cidrs.yaml" - policy_name = "iap-policy" - rules_file = "configs/firewall-policies/rules.yaml" - } - firewall_policy_association = { - iap_policy = module.org.firewall_policy_id["iap-policy"] - } -} -# tftest modules=1 resources=4 files=cidrs,rules inventory=hfw.yaml -``` - -```yaml -# tftest-file id=cidrs path=configs/firewall-policies/cidrs.yaml -rfc1918: - - 10.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 -``` - -```yaml -# tftest-file id=rules path=configs/firewall-policies/rules.yaml -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - logging: false - -allow-iap-ssh: - description: "Always allow ssh from IAP." - direction: INGRESS - action: allow - priority: 100 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - logging: false +# tftest modules=2 resources=2 ``` ## Log Sinks @@ -530,18 +450,14 @@ module "org" { ``` - - - ## Files | name | description | resources | |---|---|---| -| [firewall-policies.tf](./firewall-policies.tf) | Hierarchical firewall policies. | google_compute_firewall_policy · google_compute_firewall_policy_association · google_compute_firewall_policy_rule | | [iam.tf](./iam.tf) | IAM bindings, roles and audit logging resources. | google_organization_iam_binding · google_organization_iam_custom_role · google_organization_iam_member · google_organization_iam_policy | | [logging.tf](./logging.tf) | Log sinks and data access logs. | google_bigquery_dataset_iam_member · google_logging_organization_exclusion · google_logging_organization_sink · google_organization_iam_audit_config · google_project_iam_member · google_pubsub_topic_iam_member · google_storage_bucket_iam_member | -| [main.tf](./main.tf) | Module-level locals and resources. | google_essential_contacts_contact | +| [main.tf](./main.tf) | Module-level locals and resources. | google_compute_firewall_policy_association · google_essential_contacts_contact | | [org-policy-custom-constraints.tf](./org-policy-custom-constraints.tf) | None | google_org_policy_custom_constraint | | [organization-policies.tf](./organization-policies.tf) | Organization-level organization policies. | google_org_policy_policy | | [outputs.tf](./outputs.tf) | Module outputs. | | @@ -553,27 +469,25 @@ module "org" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [organization_id](variables.tf#L226) | Organization id in organizations/nnnnnn format. | string | ✓ | | +| [organization_id](variables.tf#L199) | Organization id in organizations/nnnnnn format. | string | ✓ | | | [contacts](variables.tf#L17) | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES. | map(list(string)) | | {} | | [custom_roles](variables.tf#L24) | Map of role name => list of permissions to create in this project. | map(list(string)) | | {} | -| [firewall_policies](variables.tf#L31) | Hierarchical firewall policy rules created in the organization. | map(map(object({…}))) | | {} | -| [firewall_policy_association](variables.tf#L48) | The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else. | map(string) | | {} | -| [firewall_policy_factory](variables.tf#L55) | Configuration for the firewall policy factory. | object({…}) | | null | -| [group_iam](variables.tf#L65) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | map(list(string)) | | {} | -| [iam](variables.tf#L72) | IAM bindings, in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [iam_additive](variables.tf#L79) | Non authoritative IAM bindings, in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [iam_additive_members](variables.tf#L86) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string)) | | {} | -| [iam_policy](variables.tf#L93) | IAM authoritative policy in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared, use with extreme caution. | map(list(string)) | | null | -| [logging_data_access](variables.tf#L99) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | map(map(list(string))) | | {} | -| [logging_exclusions](variables.tf#L114) | Logging exclusions for this organization in the form {NAME -> FILTER}. | map(string) | | {} | -| [logging_sinks](variables.tf#L121) | Logging sinks to create for the organization. | map(object({…})) | | {} | -| [network_tags](variables.tf#L151) | Network tags by key name. If `id` is provided, key creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | -| [org_policies](variables.tf#L173) | Organization policies applied to this organization keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L200) | Path containing org policies in YAML format. | string | | null | -| [org_policy_custom_constraints](variables.tf#L206) | Organization policy custom constraints keyed by constraint name. | map(object({…})) | | {} | -| [org_policy_custom_constraints_data_path](variables.tf#L220) | Path containing org policy custom constraints in YAML format. | string | | null | -| [tag_bindings](variables.tf#L235) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null | -| [tags](variables.tf#L241) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | +| [firewall_policy_associations](variables.tf#L31) | Hierarchical firewall policies to associate to this folder, in association name => policy id format. | map(string) | | {} | +| [group_iam](variables.tf#L38) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | map(list(string)) | | {} | +| [iam](variables.tf#L45) | IAM bindings, in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [iam_additive](variables.tf#L52) | Non authoritative IAM bindings, in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [iam_additive_members](variables.tf#L59) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string)) | | {} | +| [iam_policy](variables.tf#L66) | IAM authoritative policy in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared, use with extreme caution. | map(list(string)) | | null | +| [logging_data_access](variables.tf#L72) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | map(map(list(string))) | | {} | +| [logging_exclusions](variables.tf#L87) | Logging exclusions for this organization in the form {NAME -> FILTER}. | map(string) | | {} | +| [logging_sinks](variables.tf#L94) | Logging sinks to create for the organization. | map(object({…})) | | {} | +| [network_tags](variables.tf#L124) | Network tags by key name. If `id` is provided, key creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | +| [org_policies](variables.tf#L146) | Organization policies applied to this organization keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L173) | Path containing org policies in YAML format. | string | | null | +| [org_policy_custom_constraints](variables.tf#L179) | Organization policy custom constraints keyed by constraint name. | map(object({…})) | | {} | +| [org_policy_custom_constraints_data_path](variables.tf#L193) | Path containing org policy custom constraints in YAML format. | string | | null | +| [tag_bindings](variables.tf#L208) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null | +| [tags](variables.tf#L214) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | ## Outputs @@ -582,13 +496,11 @@ module "org" { | [custom_constraint_ids](outputs.tf#L17) | Map of CUSTOM_CONSTRAINTS => ID in the organization. | | | [custom_role_id](outputs.tf#L22) | Map of custom role IDs created in the organization. | | | [custom_roles](outputs.tf#L35) | Map of custom roles resources created in the organization. | | -| [firewall_policies](outputs.tf#L40) | Map of firewall policy resources created in the organization. | | -| [firewall_policy_id](outputs.tf#L45) | Map of firewall policy ids created in the organization. | | -| [id](outputs.tf#L50) | Fully qualified organization id. | | -| [network_tag_keys](outputs.tf#L67) | Tag key resources. | | -| [network_tag_values](outputs.tf#L76) | Tag value resources. | | -| [organization_id](outputs.tf#L86) | Organization id dependent on module resources. | | -| [sink_writer_identities](outputs.tf#L103) | Writer identities created for each sink. | | -| [tag_keys](outputs.tf#L111) | Tag key resources. | | -| [tag_values](outputs.tf#L120) | Tag value resources. | | +| [id](outputs.tf#L40) | Fully qualified organization id. | | +| [network_tag_keys](outputs.tf#L57) | Tag key resources. | | +| [network_tag_values](outputs.tf#L66) | Tag value resources. | | +| [organization_id](outputs.tf#L76) | Organization id dependent on module resources. | | +| [sink_writer_identities](outputs.tf#L93) | Writer identities created for each sink. | | +| [tag_keys](outputs.tf#L101) | Tag key resources. | | +| [tag_values](outputs.tf#L110) | Tag value resources. | | diff --git a/modules/organization/firewall-policies.tf b/modules/organization/firewall-policies.tf deleted file mode 100644 index b5c635af..00000000 --- a/modules/organization/firewall-policies.tf +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -# tfdoc:file:description Hierarchical firewall policies. - -locals { - _factory_cidrs = try( - yamldecode(file(var.firewall_policy_factory.cidr_file)), {} - ) - _factory_name = ( - try(var.firewall_policy_factory.policy_name, null) == null - ? "factory" - : var.firewall_policy_factory.policy_name - ) - _factory_rules = try( - yamldecode(file(var.firewall_policy_factory.rules_file)), {} - ) - _factory_rules_parsed = { - for name, rule in local._factory_rules : name => merge(rule, { - ranges = flatten([ - for r in(rule.ranges == null ? [] : rule.ranges) : - lookup(local._factory_cidrs, trimprefix(r, "$"), r) - ]) - }) - } - _merged_rules = flatten([ - for policy, rules in local.firewall_policies : [ - for name, rule in rules : merge(rule, { - policy = policy - name = name - }) - ] - ]) - firewall_policies = merge(var.firewall_policies, ( - length(local._factory_rules) == 0 - ? {} - : { (local._factory_name) = local._factory_rules_parsed } - )) - firewall_rules = { - for r in local._merged_rules : "${r.policy}-${r.name}" => r - } -} - -resource "google_compute_firewall_policy" "policy" { - for_each = local.firewall_policies - short_name = each.key - parent = var.organization_id - depends_on = [ - google_organization_iam_binding.authoritative, - google_organization_iam_custom_role.roles, - google_organization_iam_member.additive, - google_organization_iam_policy.authoritative, - ] -} - -resource "google_compute_firewall_policy_rule" "rule" { - for_each = local.firewall_rules - firewall_policy = google_compute_firewall_policy.policy[each.value.policy].id - action = each.value.action - direction = each.value.direction - priority = try(each.value.priority, null) - target_resources = try(each.value.target_resources, null) - target_service_accounts = try(each.value.target_service_accounts, null) - enable_logging = try(each.value.logging, null) - # preview = each.value.preview - description = each.value.description - match { - src_ip_ranges = each.value.direction == "INGRESS" ? each.value.ranges : null - dest_ip_ranges = each.value.direction == "EGRESS" ? each.value.ranges : null - dynamic "layer4_configs" { - for_each = each.value.ports - iterator = port - content { - ip_protocol = port.key - ports = port.value - } - } - } -} - -resource "google_compute_firewall_policy_association" "association" { - for_each = var.firewall_policy_association - name = replace(var.organization_id, "/", "-") - attachment_target = var.organization_id - firewall_policy = try(google_compute_firewall_policy.policy[each.value].id, each.value) -} - diff --git a/modules/organization/main.tf b/modules/organization/main.tf index cc757bc6..cd35bb01 100644 --- a/modules/organization/main.tf +++ b/modules/organization/main.tf @@ -26,3 +26,10 @@ resource "google_essential_contacts_contact" "contact" { language_tag = "en" notification_category_subscriptions = each.value } + +resource "google_compute_firewall_policy_association" "default" { + for_each = var.firewall_policy_associations + attachment_target = var.organization_id + name = each.key + firewall_policy = each.value +} diff --git a/modules/organization/outputs.tf b/modules/organization/outputs.tf index 1d149f7e..9c1ec187 100644 --- a/modules/organization/outputs.tf +++ b/modules/organization/outputs.tf @@ -37,16 +37,6 @@ output "custom_roles" { value = google_organization_iam_custom_role.roles } -output "firewall_policies" { - description = "Map of firewall policy resources created in the organization." - value = { for k, v in google_compute_firewall_policy.policy : k => v } -} - -output "firewall_policy_id" { - description = "Map of firewall policy ids created in the organization." - value = { for k, v in google_compute_firewall_policy.policy : k => v.id } -} - output "id" { description = "Fully qualified organization id." value = var.organization_id diff --git a/modules/organization/variables.tf b/modules/organization/variables.tf index 7c2d33e4..b9ba5820 100644 --- a/modules/organization/variables.tf +++ b/modules/organization/variables.tf @@ -28,40 +28,13 @@ variable "custom_roles" { nullable = false } -variable "firewall_policies" { - description = "Hierarchical firewall policy rules created in the organization." - type = map(map(object({ - action = string - description = string - direction = string - logging = bool - ports = map(list(string)) - priority = number - ranges = list(string) - target_resources = list(string) - target_service_accounts = list(string) - # preview = bool - }))) - default = {} -} - -variable "firewall_policy_association" { - description = "The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else." +variable "firewall_policy_associations" { + description = "Hierarchical firewall policies to associate to this folder, in association name => policy id format." type = map(string) default = {} nullable = false } -variable "firewall_policy_factory" { - description = "Configuration for the firewall policy factory." - type = object({ - cidr_file = string - policy_name = string - rules_file = string - }) - default = null -} - variable "group_iam" { description = "Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable." type = map(list(string)) diff --git a/tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml b/tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml index 23bc8b7a..661dd97f 100644 --- a/tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml +++ b/tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml @@ -13,21 +13,611 @@ # limitations under the License. values: - module.test.module.folder.google_compute_firewall_policy.policy["prefix-fw-policy"]: - short_name: prefix-fw-policy + module.test.module.firewall-policy.google_compute_firewall_policy.hierarchical[0]: + description: null + short_name: default + timeouts: null + module.test.module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["egress/allow-admins"]: + action: allow + description: Access from the admin subnet to all subnets + direction: INGRESS + disabled: false + enable_logging: null + match: + - dest_address_groups: null + dest_fqdns: null + dest_ip_ranges: null + dest_region_codes: null + dest_threat_intelligences: null + layer4_configs: + - ip_protocol: all + ports: null + src_address_groups: null + src_fqdns: null + src_ip_ranges: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + src_region_codes: null + src_threat_intelligences: null + priority: 1000 + target_resources: null + target_service_accounts: null + timeouts: null + module.test.module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["egress/allow-healthchecks"]: + action: allow + description: Enable HTTP and HTTPS healthchecks + direction: INGRESS + disabled: false + enable_logging: null + match: + - dest_address_groups: null + dest_fqdns: null + dest_ip_ranges: null + dest_region_codes: null + dest_threat_intelligences: null + layer4_configs: + - ip_protocol: all + ports: null + src_address_groups: null + src_fqdns: null + src_ip_ranges: + - 35.191.0.0/16 + - 130.211.0.0/22 + - 209.85.152.0/22 + - 209.85.204.0/22 + src_region_codes: null + src_threat_intelligences: null + priority: 1001 + target_resources: null + target_service_accounts: null + timeouts: null + module.test.module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["egress/allow-icmp"]: + action: allow + description: Enable ICMP + direction: INGRESS + disabled: false + enable_logging: null + match: + - dest_address_groups: null + dest_fqdns: null + dest_ip_ranges: null + dest_region_codes: null + dest_threat_intelligences: null + layer4_configs: + - ip_protocol: all + ports: null + src_address_groups: null + src_fqdns: null + src_ip_ranges: + - 0.0.0.0/0 + src_region_codes: null + src_threat_intelligences: null + priority: 1003 + target_resources: null + target_service_accounts: null + timeouts: null + module.test.module.firewall-policy.google_compute_firewall_policy_rule.hierarchical["egress/allow-ssh-from-iap"]: + action: allow + description: Enable SSH from IAP + direction: INGRESS + disabled: false + enable_logging: null + match: + - dest_address_groups: null + dest_fqdns: null + dest_ip_ranges: null + dest_region_codes: null + dest_threat_intelligences: null + layer4_configs: + - ip_protocol: all + ports: null + src_address_groups: null + src_fqdns: null + src_ip_ranges: + - 35.235.240.0/20 + src_region_codes: null + src_threat_intelligences: null + priority: 1002 + target_resources: null + target_service_accounts: null + timeouts: null + module.test.module.folder-workload.google_folder.folder[0]: + display_name: prefix-workload + timeouts: null + module.test.module.folder.google_bigquery_dataset_iam_member.bq-sinks-binding["audit-logs"]: + condition: [] + role: roles/bigquery.dataEditor + module.test.module.folder.google_bigquery_dataset_iam_member.bq-sinks-binding["vpc-sc"]: + condition: [] + role: roles/bigquery.dataEditor module.test.module.folder.google_folder.folder[0]: display_name: ShieldedMVP parent: organizations/1234567890123 + timeouts: null + module.test.module.folder.google_folder_iam_binding.authoritative["roles/editor"]: + condition: [] + members: + - group:gcp-data-engineers@example.com + role: roles/editor + module.test.module.folder.google_folder_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]: + condition: [] + members: + - group:gcp-data-engineers@example.com + role: roles/iam.serviceAccountTokenCreator + module.test.module.folder.google_logging_folder_sink.sink["audit-logs"]: + description: audit-logs (Terraform-managed). + disabled: false + exclusions: [] + filter: logName:"/logs/cloudaudit.googleapis.com%2Factivity" OR logName:"/logs/cloudaudit.googleapis.com%2Fsystem_event" + include_children: true + name: audit-logs + module.test.module.folder.google_logging_folder_sink.sink["vpc-sc"]: + description: vpc-sc (Terraform-managed). + disabled: false + exclusions: [] + filter: protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata" + include_children: true + name: vpc-sc + module.test.module.folder.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["compute.requireOsLogin"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: + - in:INTERNAL + denied_values: null + timeouts: null + module.test.module.folder.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["iam.automaticIamGrantsForDefaultServiceAccounts"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["run.allowedIngress"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: + - is:internal + denied_values: null + timeouts: null + module.test.module.folder.google_org_policy_policy.default["sql.restrictAuthorizedNetworks"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["sql.restrictPublicIp"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.folder.google_org_policy_policy.default["storage.uniformBucketLevelAccess"]: + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + module.test.module.log-export-dataset[0].google_bigquery_dataset.default: + dataset_id: prefix_audit_export + default_encryption_configuration: [] + default_partition_expiration_ms: null + default_table_expiration_ms: null + delete_contents_on_destroy: false + description: Terraform managed. + friendly_name: Audit logs export. + location: EU + max_time_travel_hours: '168' + project: prefix-audit-logs + timeouts: null + module.test.module.log-export-project[0].data.google_bigquery_default_service_account.bq_sa[0]: + project: prefix-audit-logs + module.test.module.log-export-project[0].data.google_storage_project_service_account.gcs_sa[0]: + project: prefix-audit-logs + user_project: null module.test.module.log-export-project[0].google_project.project[0]: + auto_create_network: false billing_account: 123456-123456-123456 + labels: null + name: prefix-audit-logs project_id: prefix-audit-logs + skip_delete: false + timeouts: null + module.test.module.log-export-project[0].google_project_iam_binding.authoritative["roles/editor"]: + condition: [] + members: + - group:gcp-data-security@example.com + project: prefix-audit-logs + role: roles/editor + module.test.module.log-export-project[0].google_project_service.project_services["bigquery.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: prefix-audit-logs + service: bigquery.googleapis.com + timeouts: null + module.test.module.log-export-project[0].google_project_service.project_services["pubsub.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: prefix-audit-logs + service: pubsub.googleapis.com + timeouts: null + module.test.module.log-export-project[0].google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: prefix-audit-logs + service: stackdriver.googleapis.com + timeouts: null + module.test.module.log-export-project[0].google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: prefix-audit-logs + service: storage.googleapis.com + timeouts: null + module.test.module.log-export-project[0].google_project_service_identity.jit_si["pubsub.googleapis.com"]: + project: prefix-audit-logs + service: pubsub.googleapis.com + timeouts: null module.test.module.vpc-sc[0].google_access_context_manager_access_policy.default[0]: parent: organizations/1122334455 + timeouts: null title: shielded-folder module.test.module.vpc-sc[0].google_access_context_manager_service_perimeter.regular["shielded"]: description: null perimeter_type: PERIMETER_TYPE_REGULAR + spec: + - access_levels: [] + egress_policies: [] + ingress_policies: + - ingress_from: + - identity_type: null + sources: + - access_level: '*' + resource: null + ingress_to: + - operations: + - method_selectors: [] + service_name: '*' + restricted_services: + - accessapproval.googleapis.com + - adsdatahub.googleapis.com + - aiplatform.googleapis.com + - alloydb.googleapis.com + - alpha-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 + - beyondcorp.googleapis.com + - bigquery.googleapis.com + - bigquerydatapolicy.googleapis.com + - bigquerydatatransfer.googleapis.com + - bigquerymigration.googleapis.com + - bigqueryreservation.googleapis.com + - bigtable.googleapis.com + - binaryauthorization.googleapis.com + - cloudasset.googleapis.com + - cloudbuild.googleapis.com + - clouddebugger.googleapis.com + - clouderrorreporting.googleapis.com + - cloudfunctions.googleapis.com + - cloudkms.googleapis.com + - cloudprofiler.googleapis.com + - cloudresourcemanager.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 + - contentwarehouse.googleapis.com + - datacatalog.googleapis.com + - dataflow.googleapis.com + - datafusion.googleapis.com + - datalineage.googleapis.com + - datamigration.googleapis.com + - datapipelines.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 + - essentialcontacts.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 + - gkemulticloud.googleapis.com + - healthcare.googleapis.com + - iam.googleapis.com + - iamcredentials.googleapis.com + - iaptunnel.googleapis.com + - ids.googleapis.com + - integrations.googleapis.com + - language.googleapis.com + - lifesciences.googleapis.com + - logging.googleapis.com + - managedidentities.googleapis.com + - memcache.googleapis.com + - meshca.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 + - osconfig.googleapis.com + - oslogin.googleapis.com + - policytroubleshooter.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 + - texttospeech.googleapis.com + - tpu.googleapis.com + - trafficdirector.googleapis.com + - transcoder.googleapis.com + - translate.googleapis.com + - videointelligence.googleapis.com + - vision.googleapis.com + - visionai.googleapis.com + - vpcaccess.googleapis.com + - workstations.googleapis.com + vpc_accessible_services: + - allowed_services: + - accessapproval.googleapis.com + - adsdatahub.googleapis.com + - aiplatform.googleapis.com + - alloydb.googleapis.com + - alpha-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 + - beyondcorp.googleapis.com + - bigquery.googleapis.com + - bigquerydatapolicy.googleapis.com + - bigquerydatatransfer.googleapis.com + - bigquerymigration.googleapis.com + - bigqueryreservation.googleapis.com + - bigtable.googleapis.com + - binaryauthorization.googleapis.com + - cloudasset.googleapis.com + - cloudbuild.googleapis.com + - clouddebugger.googleapis.com + - clouderrorreporting.googleapis.com + - cloudfunctions.googleapis.com + - cloudkms.googleapis.com + - cloudprofiler.googleapis.com + - cloudresourcemanager.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 + - contentwarehouse.googleapis.com + - datacatalog.googleapis.com + - dataflow.googleapis.com + - datafusion.googleapis.com + - datalineage.googleapis.com + - datamigration.googleapis.com + - datapipelines.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 + - essentialcontacts.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 + - gkemulticloud.googleapis.com + - healthcare.googleapis.com + - iam.googleapis.com + - iamcredentials.googleapis.com + - iaptunnel.googleapis.com + - ids.googleapis.com + - integrations.googleapis.com + - language.googleapis.com + - lifesciences.googleapis.com + - logging.googleapis.com + - managedidentities.googleapis.com + - memcache.googleapis.com + - meshca.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 + - osconfig.googleapis.com + - oslogin.googleapis.com + - policytroubleshooter.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 + - texttospeech.googleapis.com + - tpu.googleapis.com + - trafficdirector.googleapis.com + - transcoder.googleapis.com + - translate.googleapis.com + - videointelligence.googleapis.com + - vision.googleapis.com + - visionai.googleapis.com + - vpcaccess.googleapis.com + - workstations.googleapis.com + enable_restriction: true + status: [] + timeouts: null title: shielded + use_explicit_dry_run_spec: true counts: google_access_context_manager_access_policy: 1 @@ -47,5 +637,7 @@ counts: google_project_service_identity: 1 google_projects: 1 google_storage_project_service_account: 1 - modules: 6 + modules: 7 resources: 38 + +outputs: {} diff --git a/tests/fast/stages/s2_networking_a_peering/stage.yaml b/tests/fast/stages/s2_networking_a_peering/stage.yaml index 9a16a6b4..2c2ca3da 100644 --- a/tests/fast/stages/s2_networking_a_peering/stage.yaml +++ b/tests/fast/stages/s2_networking_a_peering/stage.yaml @@ -13,5 +13,5 @@ # limitations under the License. counts: - modules: 27 + modules: 28 resources: 151 diff --git a/tests/fast/stages/s2_networking_b_vpn/stage.yaml b/tests/fast/stages/s2_networking_b_vpn/stage.yaml index 70c5c30a..9cb8ee83 100644 --- a/tests/fast/stages/s2_networking_b_vpn/stage.yaml +++ b/tests/fast/stages/s2_networking_b_vpn/stage.yaml @@ -13,5 +13,5 @@ # limitations under the License. counts: - modules: 29 + modules: 30 resources: 188 diff --git a/tests/fast/stages/s2_networking_c_nva/stage.yaml b/tests/fast/stages/s2_networking_c_nva/stage.yaml index e2d1aaf6..3da9b352 100644 --- a/tests/fast/stages/s2_networking_c_nva/stage.yaml +++ b/tests/fast/stages/s2_networking_c_nva/stage.yaml @@ -13,5 +13,5 @@ # limitations under the License. counts: - modules: 41 + modules: 42 resources: 197 diff --git a/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml b/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml index 4b24b412..f60257c4 100644 --- a/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml +++ b/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml @@ -13,5 +13,5 @@ # limitations under the License. counts: - modules: 20 + modules: 21 resources: 168 diff --git a/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml b/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml index ffde4a39..fa62dac0 100644 --- a/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml +++ b/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml @@ -13,5 +13,5 @@ # limitations under the License. counts: - modules: 35 + modules: 36 resources: 210 diff --git a/tests/modules/net_vpc_firewall_policy/examples/factory.yaml b/tests/modules/net_firewall_policy/examples/factory.yaml similarity index 100% rename from tests/modules/net_vpc_firewall_policy/examples/factory.yaml rename to tests/modules/net_firewall_policy/examples/factory.yaml diff --git a/tests/modules/net_vpc_firewall_policy/examples/global-net.yaml b/tests/modules/net_firewall_policy/examples/global-net.yaml similarity index 100% rename from tests/modules/net_vpc_firewall_policy/examples/global-net.yaml rename to tests/modules/net_firewall_policy/examples/global-net.yaml diff --git a/tests/modules/net_vpc_firewall_policy/examples/hierarchical.yaml b/tests/modules/net_firewall_policy/examples/hierarchical.yaml similarity index 100% rename from tests/modules/net_vpc_firewall_policy/examples/hierarchical.yaml rename to tests/modules/net_firewall_policy/examples/hierarchical.yaml diff --git a/tests/modules/net_vpc_firewall_policy/examples/regional-net.yaml b/tests/modules/net_firewall_policy/examples/regional-net.yaml similarity index 100% rename from tests/modules/net_vpc_firewall_policy/examples/regional-net.yaml rename to tests/modules/net_firewall_policy/examples/regional-net.yaml diff --git a/tests/modules/organization/firewall_policies_factory_combined.tfvars b/tests/modules/organization/firewall_policies_factory_combined.tfvars deleted file mode 100644 index 7ea51bb0..00000000 --- a/tests/modules/organization/firewall_policies_factory_combined.tfvars +++ /dev/null @@ -1,51 +0,0 @@ -firewall_policies = { - policy1 = { - allow-ingress = { - description = "" - direction = "INGRESS" - action = "allow" - priority = 100 - ranges = ["10.0.0.0/8"] - ports = { - tcp = ["22"] - } - target_service_accounts = null - target_resources = null - logging = false - } - deny-egress = { - description = "" - direction = "EGRESS" - action = "deny" - priority = 200 - ranges = ["192.168.0.0/24"] - ports = { - tcp = ["443"] - } - target_service_accounts = null - target_resources = null - logging = false - } - } - policy2 = { - allow-ingress = { - description = "" - direction = "INGRESS" - action = "allow" - priority = 100 - ranges = ["10.0.0.0/8"] - ports = { - tcp = ["22"] - } - target_service_accounts = null - target_resources = null - logging = false - } - } -} - -firewall_policy_factory = { - cidr_file = "../../tests/modules/organization/data/firewall-cidrs.yaml" - policy_name = "factory-1" - rules_file = "../../tests/modules/organization/data/firewall-rules.yaml" -} diff --git a/tests/modules/organization/firewall_policies_factory_combined.yaml b/tests/modules/organization/firewall_policies_factory_combined.yaml deleted file mode 100644 index 3b5cf6cc..00000000 --- a/tests/modules/organization/firewall_policies_factory_combined.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2022 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. - -values: - google_compute_firewall_policy.policy["factory-1"]: {} - google_compute_firewall_policy.policy["policy1"]: {} - google_compute_firewall_policy.policy["policy2"]: {} - google_compute_firewall_policy_rule.rule["factory-1-allow-admins"]: {} - google_compute_firewall_policy_rule.rule["factory-1-allow-ssh-from-iap"]: {} - google_compute_firewall_policy_rule.rule["policy1-allow-ingress"]: {} - google_compute_firewall_policy_rule.rule["policy1-deny-egress"]: {} - google_compute_firewall_policy_rule.rule["policy2-allow-ingress"]: {} - -counts: - google_compute_firewall_policy: 3 - google_compute_firewall_policy_rule: 5 diff --git a/tests/modules/organization/tftest.yaml b/tests/modules/organization/tftest.yaml index d179d057..2f1cec23 100644 --- a/tests/modules/organization/tftest.yaml +++ b/tests/modules/organization/tftest.yaml @@ -21,5 +21,4 @@ tests: org_policies_list: org_policies_boolean: org_policies_custom_constraints: - firewall_policies_factory_combined: tags: