diff --git a/blueprints/cloud-operations/packer-image-builder/main.tf b/blueprints/cloud-operations/packer-image-builder/main.tf index f8ea374f7..f6de3af51 100644 --- a/blueprints/cloud-operations/packer-image-builder/main.tf +++ b/blueprints/cloud-operations/packer-image-builder/main.tf @@ -67,17 +67,16 @@ module "firewall" { source = "../../../modules/net-vpc-firewall" project_id = module.project.project_id network = module.vpc.name - custom_rules = { + ingress_rules = { image-builder-ingress-builder-vm = { description = "Allow image builder vm ingress traffic" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = var.packer_source_cidrs + source_ranges = var.packer_source_cidrs targets = [module.service-account-image-builder-vm.email] use_service_accounts = true - rules = [{ protocol = "tcp", ports = [22, 5985, 5986] }] - extra_attributes = {} + rules = [{ + protocol = "tcp" + ports = [22, 5985, 5986] + }] } } } diff --git a/blueprints/cloud-operations/vm-migration/single-project/main.tf b/blueprints/cloud-operations/vm-migration/single-project/main.tf index acb06a91b..a6fee8430 100644 --- a/blueprints/cloud-operations/vm-migration/single-project/main.tf +++ b/blueprints/cloud-operations/vm-migration/single-project/main.tf @@ -66,24 +66,7 @@ module "landing-vpc" { } module "landing-vpc-firewall" { - source = "../../../../modules/net-vpc-firewall" - project_id = module.landing-project.project_id - network = module.landing-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - custom_rules = { - allow-ssh = { - description = "Allow SSH from IAP" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = ["35.235.240.0/20"] - targets = [] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = ["22"] }] - extra_attributes = {} - } - } + source = "../../../../modules/net-vpc-firewall" + project_id = module.landing-project.project_id + network = module.landing-vpc.name } diff --git a/blueprints/data-solutions/cloudsql-multiregion/main.tf b/blueprints/data-solutions/cloudsql-multiregion/main.tf index 41a111fed..1fd76aa3f 100644 --- a/blueprints/data-solutions/cloudsql-multiregion/main.tf +++ b/blueprints/data-solutions/cloudsql-multiregion/main.tf @@ -128,11 +128,13 @@ module "vpc" { } module "firewall" { - source = "../../../modules/net-vpc-firewall" - count = local.use_shared_vpc ? 0 : 1 - project_id = module.project.project_id - network = module.vpc.0.name - admin_ranges = ["10.0.0.0/20"] + source = "../../../modules/net-vpc-firewall" + count = local.use_shared_vpc ? 0 : 1 + project_id = module.project.project_id + network = module.vpc.0.name + default_rules_config = { + admin_ranges = ["10.0.0.0/20"] + } } module "nat" { diff --git a/blueprints/data-solutions/cmek-via-centralized-kms/main.tf b/blueprints/data-solutions/cmek-via-centralized-kms/main.tf index d507bfdff..fb7f9fdd1 100644 --- a/blueprints/data-solutions/cmek-via-centralized-kms/main.tf +++ b/blueprints/data-solutions/cmek-via-centralized-kms/main.tf @@ -59,10 +59,12 @@ module "vpc" { } module "vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project-service.project_id - network = module.vpc.name - admin_ranges = [var.vpc_ip_cidr_range] + source = "../../../modules/net-vpc-firewall" + project_id = module.project-service.project_id + network = module.vpc.name + default_rules_config = { + admin_ranges = [var.vpc_ip_cidr_range] + } } ############################################################################### diff --git a/blueprints/data-solutions/data-platform-foundations/02-load.tf b/blueprints/data-solutions/data-platform-foundations/02-load.tf index 5c61da9f8..74cb9f8b0 100644 --- a/blueprints/data-solutions/data-platform-foundations/02-load.tf +++ b/blueprints/data-solutions/data-platform-foundations/02-load.tf @@ -118,11 +118,13 @@ module "load-vpc" { } module "load-vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - count = local.use_shared_vpc ? 0 : 1 - project_id = module.load-project.project_id - network = module.load-vpc.0.name - admin_ranges = ["10.10.0.0/24"] + source = "../../../modules/net-vpc-firewall" + count = local.use_shared_vpc ? 0 : 1 + project_id = module.load-project.project_id + network = module.load-vpc.0.name + default_rules_config = { + admin_ranges = ["10.10.0.0/24"] + } } module "load-nat" { diff --git a/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf b/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf index 2990a2c57..2974c1227 100644 --- a/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf +++ b/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf @@ -133,11 +133,13 @@ module "orch-vpc" { } module "orch-vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - count = local.use_shared_vpc ? 0 : 1 - project_id = module.orch-project.project_id - network = module.orch-vpc.0.name - admin_ranges = ["10.10.0.0/24"] + source = "../../../modules/net-vpc-firewall" + count = local.use_shared_vpc ? 0 : 1 + project_id = module.orch-project.project_id + network = module.orch-vpc.0.name + default_rules_config = { + admin_ranges = ["10.10.0.0/24"] + } } module "orch-nat" { diff --git a/blueprints/data-solutions/data-platform-foundations/04-transformation.tf b/blueprints/data-solutions/data-platform-foundations/04-transformation.tf index e696bec6b..3d3a818c5 100644 --- a/blueprints/data-solutions/data-platform-foundations/04-transformation.tf +++ b/blueprints/data-solutions/data-platform-foundations/04-transformation.tf @@ -142,11 +142,13 @@ module "transf-vpc" { } module "transf-vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - count = local.use_shared_vpc ? 0 : 1 - project_id = module.transf-project.project_id - network = module.transf-vpc.0.name - admin_ranges = ["10.10.0.0/24"] + source = "../../../modules/net-vpc-firewall" + count = local.use_shared_vpc ? 0 : 1 + project_id = module.transf-project.project_id + network = module.transf-vpc.0.name + default_rules_config = { + admin_ranges = ["10.10.0.0/24"] + } } module "transf-nat" { diff --git a/blueprints/data-solutions/data-playground/main.tf b/blueprints/data-solutions/data-playground/main.tf index bcdea5dfa..a561c1d63 100644 --- a/blueprints/data-solutions/data-playground/main.tf +++ b/blueprints/data-solutions/data-playground/main.tf @@ -72,22 +72,19 @@ module "vpc" { } module "vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project.project_id - network = module.vpc.name - admin_ranges = [var.vpc_config.ip_cidr_range] - custom_rules = { + source = "../../../modules/net-vpc-firewall" + project_id = module.project.project_id + network = module.vpc.name + default_rules_config = { + admin_ranges = [var.vpc_config.ip_cidr_range] + } + ingress_rules = { #TODO Remove and rely on 'ssh' tag once terraform-provider-google/issues/9273 is fixed ("${var.prefix}-iap") = { - description = "Enable SSH from IAP on Notebooks." - direction = "INGRESS" - action = "allow" - sources = [] - ranges = ["35.235.240.0/20"] - targets = ["notebook-instance"] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = [22] }] - extra_attributes = {} + description = "Enable SSH from IAP on Notebooks." + source_ranges = ["35.235.240.0/20"] + targets = ["notebook-instance"] + rules = [{ protocol = "tcp", ports = [22] }] } } } diff --git a/blueprints/data-solutions/gcs-to-bq-with-least-privileges/vpc.tf b/blueprints/data-solutions/gcs-to-bq-with-least-privileges/vpc.tf index aab9a657b..fd47952bf 100644 --- a/blueprints/data-solutions/gcs-to-bq-with-least-privileges/vpc.tf +++ b/blueprints/data-solutions/gcs-to-bq-with-least-privileges/vpc.tf @@ -27,11 +27,13 @@ module "vpc" { } module "vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - count = local.use_shared_vpc ? 0 : 1 - project_id = module.project.project_id - network = module.vpc[0].name - admin_ranges = [var.vpc_subnet_range] + source = "../../../modules/net-vpc-firewall" + count = local.use_shared_vpc ? 0 : 1 + project_id = module.project.project_id + network = module.vpc[0].name + default_rules_config = { + admin_ranges = [var.vpc_subnet_range] + } } module "nat" { diff --git a/blueprints/data-solutions/sqlserver-alwayson/vpc.tf b/blueprints/data-solutions/sqlserver-alwayson/vpc.tf index d3e816cb7..6f0b9120e 100644 --- a/blueprints/data-solutions/sqlserver-alwayson/vpc.tf +++ b/blueprints/data-solutions/sqlserver-alwayson/vpc.tf @@ -76,69 +76,52 @@ module "vpc" { } module "firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = local.vpc_project - network = local.network - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - custom_rules = { + source = "../../../modules/net-vpc-firewall" + project_id = local.vpc_project + network = local.network + default_rules_config = { + disabled = true + } + ingress_rules = { "${local.prefix}allow-all-between-wsfc-nodes" = { description = "Allow all between WSFC nodes" - direction = "INGRESS" - action = "allow" sources = [module.compute-service-account.email] targets = [module.compute-service-account.email] - ranges = [] use_service_accounts = true rules = [ - { protocol = "tcp", ports = [] }, - { protocol = "udp", ports = [] }, - { protocol = "icmp", ports = [] } + { protocol = "tcp" }, + { protocol = "udp" }, + { protocol = "icmp" } ] - extra_attributes = {} } "${local.prefix}allow-all-between-wsfc-witness" = { description = "Allow all between WSFC witness nodes" - direction = "INGRESS" - action = "allow" sources = [module.compute-service-account.email] targets = [module.witness-service-account.email] - ranges = [] use_service_accounts = true rules = [ - { protocol = "tcp", ports = [] }, - { protocol = "udp", ports = [] }, - { protocol = "icmp", ports = [] } + { protocol = "tcp" }, + { protocol = "udp" }, + { protocol = "icmp" } ] - extra_attributes = {} } "${local.prefix}allow-sql-to-wsfc-nodes" = { description = "Allow SQL connections to WSFC nodes" - direction = "INGRESS" - action = "allow" - sources = [] targets = [module.compute-service-account.email] ranges = var.sql_client_cidrs use_service_accounts = true rules = [ { protocol = "tcp", ports = [1433] }, ] - extra_attributes = {} } "${local.prefix}allow-health-check-to-wsfc-nodes" = { description = "Allow health checks to WSFC nodes" - direction = "INGRESS" - action = "allow" - sources = [] targets = [module.compute-service-account.email] ranges = var.health_check_ranges use_service_accounts = true rules = [ - { protocol = "tcp", ports = [] }, + { protocol = "tcp" } ] - extra_attributes = {} } } } diff --git a/blueprints/gke/multi-cluster-mesh-gke-fleet-api/vpc.tf b/blueprints/gke/multi-cluster-mesh-gke-fleet-api/vpc.tf index 6c09546a2..604797be7 100644 --- a/blueprints/gke/multi-cluster-mesh-gke-fleet-api/vpc.tf +++ b/blueprints/gke/multi-cluster-mesh-gke-fleet-api/vpc.tf @@ -40,36 +40,36 @@ module "firewall" { source = "../../../modules/net-vpc-firewall" project_id = module.host_project.project_id network = module.svpc.name - custom_rules = merge({ allow-mesh = { - description = "Allow " - direction = "INGRESS" - action = "allow" - sources = [] - ranges = [for k, v in var.clusters_config : v.pods_cidr_block] - targets = [for k, v in var.clusters_config : "${k}-node"] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = null }, - { protocol = "udp", ports = null }, - { protocol = "icmp", ports = null }, - { protocol = "esp", ports = null }, - { protocol = "ah", ports = null }, - { protocol = "sctp", ports = null }] - extra_attributes = { - priority = 900 - } - } }, - { for k, v in var.clusters_config : "allow-${k}-istio" => { - description = "Allow " - direction = "INGRESS" - action = "allow" - sources = [] - ranges = [v.master_cidr_block] - targets = ["${k}-node"] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = [8080, 15014, 15017] }] - extra_attributes = { - priority = 1000 + ingress_rules = merge( + { + allow-mesh = { + description = "Allow mesh." + priority = 900 + source_ranges = [ + for k, v in var.clusters_config : v.pods_cidr_block + ] + targets = [ + for k, v in var.clusters_config : "${k}-node" + ] + rules = [ + { protocol = "tcp" }, + { protocol = "udp" }, + { protocol = "icmp" }, + { protocol = "esp" }, + { protocol = "ah" }, + { protocol = "sctp" } + ] } + }, + { + for k, v in var.clusters_config : "allow-${k}-istio" => { + description = "Allow istio." + source_ranges = [v.master_cidr_block] + targets = ["${k}-node"] + rules = [{ + protocol = "tcp" + ports = [8080, 15014, 15017] + }] } } ) diff --git a/blueprints/networking/filtering-proxy/main.tf b/blueprints/networking/filtering-proxy/main.tf index eef3bf2db..06efa8147 100644 --- a/blueprints/networking/filtering-proxy/main.tf +++ b/blueprints/networking/filtering-proxy/main.tf @@ -74,17 +74,18 @@ module "firewall" { source = "../../../modules/net-vpc-firewall" project_id = module.project-host.project_id network = module.vpc.name - custom_rules = { + ingress_rules = { allow-ingress-squid = { - description = "Allow squid ingress traffic" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = [var.cidrs.apps, "35.191.0.0/16", "130.211.0.0/22"] + description = "Allow squid ingress traffic" + source_ranges = [ + var.cidrs.apps, "35.191.0.0/16", "130.211.0.0/22" + ] targets = [module.service-account-squid.email] use_service_accounts = true - rules = [{ protocol = "tcp", ports = [3128] }] - extra_attributes = {} + rules = [{ + protocol = "tcp" + ports = [3128] + }] } } } diff --git a/blueprints/networking/hub-and-spoke-peering/main.tf b/blueprints/networking/hub-and-spoke-peering/main.tf index 525e20d0f..7fa8142e4 100644 --- a/blueprints/networking/hub-and-spoke-peering/main.tf +++ b/blueprints/networking/hub-and-spoke-peering/main.tf @@ -69,10 +69,12 @@ module "nat-hub" { } module "vpc-hub-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = var.project_id - network = module.vpc-hub.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = var.project_id + network = module.vpc-hub.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } ################################################################################ @@ -93,10 +95,12 @@ module "vpc-spoke-1" { } module "vpc-spoke-1-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project.project_id - network = module.vpc-spoke-1.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = module.project.project_id + network = module.vpc-spoke-1.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } module "nat-spoke-1" { @@ -138,10 +142,12 @@ module "vpc-spoke-2" { } module "vpc-spoke-2-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project.project_id - network = module.vpc-spoke-2.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = module.project.project_id + network = module.vpc-spoke-2.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } module "nat-spoke-2" { diff --git a/blueprints/networking/hub-and-spoke-vpn/net-dev.tf b/blueprints/networking/hub-and-spoke-vpn/net-dev.tf index 7d1c08358..736c742f6 100644 --- a/blueprints/networking/hub-and-spoke-vpn/net-dev.tf +++ b/blueprints/networking/hub-and-spoke-vpn/net-dev.tf @@ -39,10 +39,12 @@ module "dev-vpc" { } module "dev-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = var.project_id - network = module.dev-vpc.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = var.project_id + network = module.dev-vpc.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } module "dev-dns-peering" { diff --git a/blueprints/networking/hub-and-spoke-vpn/net-landing.tf b/blueprints/networking/hub-and-spoke-vpn/net-landing.tf index c70e2295e..b385bfb1d 100644 --- a/blueprints/networking/hub-and-spoke-vpn/net-landing.tf +++ b/blueprints/networking/hub-and-spoke-vpn/net-landing.tf @@ -39,10 +39,12 @@ module "landing-vpc" { } module "landing-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = var.project_id - network = module.landing-vpc.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = var.project_id + network = module.landing-vpc.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } module "landing-dns-zone" { diff --git a/blueprints/networking/hub-and-spoke-vpn/net-prod.tf b/blueprints/networking/hub-and-spoke-vpn/net-prod.tf index aeb62019f..ad58b5858 100644 --- a/blueprints/networking/hub-and-spoke-vpn/net-prod.tf +++ b/blueprints/networking/hub-and-spoke-vpn/net-prod.tf @@ -39,10 +39,12 @@ module "prod-vpc" { } module "prod-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = var.project_id - network = module.prod-vpc.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = var.project_id + network = module.prod-vpc.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } module "prod-dns-peering" { diff --git a/blueprints/networking/ilb-next-hop/vpc-left.tf b/blueprints/networking/ilb-next-hop/vpc-left.tf index 426614c9f..f5df5234c 100644 --- a/blueprints/networking/ilb-next-hop/vpc-left.tf +++ b/blueprints/networking/ilb-next-hop/vpc-left.tf @@ -35,11 +35,13 @@ module "vpc-left" { } module "firewall-left" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project.project_id - network = module.vpc-left.name - admin_ranges = values(var.ip_ranges) - ssh_source_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22"] + source = "../../../modules/net-vpc-firewall" + project_id = module.project.project_id + network = module.vpc-left.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + ssh_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22"] + } } module "nat-left" { diff --git a/blueprints/networking/ilb-next-hop/vpc-right.tf b/blueprints/networking/ilb-next-hop/vpc-right.tf index 95350eb09..edd6941d6 100644 --- a/blueprints/networking/ilb-next-hop/vpc-right.tf +++ b/blueprints/networking/ilb-next-hop/vpc-right.tf @@ -46,11 +46,13 @@ module "vpc-right" { } module "firewall-right" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project.project_id - network = module.vpc-right.name - admin_ranges = values(var.ip_ranges) - ssh_source_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22"] + source = "../../../modules/net-vpc-firewall" + project_id = module.project.project_id + network = module.vpc-right.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + ssh_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22"] + } } module "nat-right" { diff --git a/blueprints/networking/nginx-reverse-proxy-cluster/main.tf b/blueprints/networking/nginx-reverse-proxy-cluster/main.tf index 5c58401c8..c361aca05 100644 --- a/blueprints/networking/nginx-reverse-proxy-cluster/main.tf +++ b/blueprints/networking/nginx-reverse-proxy-cluster/main.tf @@ -161,28 +161,22 @@ module "firewall" { source = "../../../modules/net-vpc-firewall" project_id = module.project.project_id network = module.vpc.name - custom_rules = { + ingress_rules = { format("%sallow-http-to-proxy-cluster", var.prefix) = { - description = "Allow Nginx HTTP(S) ingress traffic" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = [var.cidrs[var.subnetwork], "35.191.0.0/16", "130.211.0.0/22"] + description = "Allow Nginx HTTP(S) ingress traffic" + source_ranges = [ + var.cidrs[var.subnetwork], "35.191.0.0/16", "130.211.0.0/22" + ] targets = [module.service-account-proxy.email] use_service_accounts = true rules = [{ protocol = "tcp", ports = [80, 443] }] - extra_attributes = {} } format("%sallow-iap-ssh", var.prefix) = { description = "Allow Nginx SSH traffic from IAP" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = ["35.235.240.0/20"] + source_ranges = ["35.235.240.0/20"] targets = [module.service-account-proxy.email] use_service_accounts = true rules = [{ protocol = "tcp", ports = [22] }] - extra_attributes = {} } } } diff --git a/blueprints/networking/onprem-google-access-dns/main.tf b/blueprints/networking/onprem-google-access-dns/main.tf index 4a78f2cab..141860608 100644 --- a/blueprints/networking/onprem-google-access-dns/main.tf +++ b/blueprints/networking/onprem-google-access-dns/main.tf @@ -69,11 +69,13 @@ module "vpc" { } module "vpc-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = var.project_id - network = module.vpc.name - admin_ranges = values(var.ip_ranges) - ssh_source_ranges = var.ssh_source_ranges + source = "../../../modules/net-vpc-firewall" + project_id = var.project_id + network = module.vpc.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + ssh_ranges = var.ssh_source_ranges + } } module "vpn1" { diff --git a/blueprints/networking/shared-vpc-gke/main.tf b/blueprints/networking/shared-vpc-gke/main.tf index 59d07d2dd..2e770377f 100644 --- a/blueprints/networking/shared-vpc-gke/main.tf +++ b/blueprints/networking/shared-vpc-gke/main.tf @@ -130,10 +130,12 @@ module "vpc-shared" { } module "vpc-shared-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.project-host.project_id - network = module.vpc-shared.name - admin_ranges = values(var.ip_ranges) + source = "../../../modules/net-vpc-firewall" + project_id = module.project-host.project_id + network = module.vpc-shared.name + default_rules_config = { + admin_ranges = values(var.ip_ranges) + } } module "nat" { diff --git a/fast/assets/schemas/firewall_rules.schema.yaml b/fast/assets/schemas/firewall_rules.schema.yaml index 1fd96caf1..6f8a8054d 100644 --- a/fast/assets/schemas/firewall_rules.schema.yaml +++ b/fast/assets/schemas/firewall_rules.schema.yaml @@ -12,18 +12,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -map(include('firewall_rule')) +egress: map(include('firewall_rule'), required=False) +ingress: map(include('firewall_rule'), required=False) --- firewall_rule: - description: str() - direction: enum("INGRESS", "EGRESS") - action: enum("allow", "deny") - sources: list(str()) - ranges: list(str()) - targets: list(str()) - use_service_accounts: bool() - rules: list(include('rule')) + deny: bool(required=False) + description: str(required=False) + destination_ranges: list(str(), required=False) + disabled: bool(required=False) + # enable_logging: + # include_metadata: bool(required=False) + priority: int(required=False) + source_ranges: list(str(), required=False) + sources: list(str(), required=False) + targets: list(str(), required=False) + use_service_accounts: bool(required=False) + rules: list(include('rule'), required=False) --- rule: - protocol: enum("tcp", "udp", "all") + protocol: str() ports: list(num()) diff --git a/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml index 3e2d9cc9d..cab42edc9 100644 --- a/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml +++ b/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml @@ -1,27 +1,21 @@ # skip boilerplate check -ingress-allow-composer-nodes: - description: "Allow traffic to Composer nodes." - direction: INGRESS - action: allow - sources: - - composer-worker - targets: - - composer-worker - use_service_accounts: false - rules: - - protocol: tcp - ports: [80, 443, 3306, 3307] - -ingress-allow-dataflow-load: - description: "Allow traffic to Dataflow nodes." - direction: INGRESS - action: allow - sources: - - dataflow - targets: - - dataflow - use_service_accounts: false - rules: - - protocol: tcp - ports: [12345, 12346] +ingress: + ingress-allow-composer-nodes: + description: "Allow traffic to Composer nodes." + sources: + - composer-worker + targets: + - composer-worker + rules: + - protocol: tcp + ports: [80, 443, 3306, 3307] + ingress-allow-dataflow-load: + description: "Allow traffic to Dataflow nodes." + sources: + - dataflow + targets: + - dataflow + rules: + - protocol: tcp + ports: [12345, 12346] diff --git a/fast/stages/02-networking-nva/data/firewall-rules/landing-trusted/rules.yaml b/fast/stages/02-networking-nva/data/firewall-rules/landing-trusted/rules.yaml index 672af07f7..1405170fb 100644 --- a/fast/stages/02-networking-nva/data/firewall-rules/landing-trusted/rules.yaml +++ b/fast/stages/02-networking-nva/data/firewall-rules/landing-trusted/rules.yaml @@ -1,29 +1,19 @@ # skip boilerplate check -allow-hc-nva-ssh-trusted: - description: "Allow traffic from Google healthchecks to NVA appliances" - direction: INGRESS - action: allow - sources: [] - ranges: - - $healthchecks - targets: [] - use_service_accounts: false - rules: - - protocol: tcp - ports: - - 22 - -allow-onprem-probes-trusted-example: - description: "Allow traffic from onprem probes" - direction: INGRESS - action: allow - sources: [] - ranges: - - $onprem_probes - targets: [] - use_service_accounts: false - rules: - - protocol: tcp - ports: - - 12345 +ingress: + allow-hc-nva-ssh-trusted: + description: "Allow traffic from Google healthchecks to NVA appliances" + source_ranges: + - healthchecks + rules: + - protocol: tcp + ports: + - 22 + allow-onprem-probes-trusted-example: + description: "Allow traffic from onprem probes" + source_ranges: + - onprem_probes + rules: + - protocol: tcp + ports: + - 12345 diff --git a/fast/stages/02-networking-nva/data/firewall-rules/landing-untrusted/rules.yaml b/fast/stages/02-networking-nva/data/firewall-rules/landing-untrusted/rules.yaml index 15db503ba..aa51c0fe8 100644 --- a/fast/stages/02-networking-nva/data/firewall-rules/landing-untrusted/rules.yaml +++ b/fast/stages/02-networking-nva/data/firewall-rules/landing-untrusted/rules.yaml @@ -1,15 +1,11 @@ # skip boilerplate check -allow-hc-nva-ssh-untrusted: - description: "Allow traffic from Google healthchecks to NVA appliances" - direction: INGRESS - action: allow - sources: [] - ranges: - - $healthchecks - targets: [] - use_service_accounts: false - rules: - - protocol: tcp - ports: - - 22 +ingress: + allow-hc-nva-ssh-untrusted: + description: "Allow traffic from Google healthchecks to NVA appliances" + source_ranges: + - healthchecks + rules: + - protocol: tcp + ports: + - 22 diff --git a/fast/stages/02-networking-nva/landing.tf b/fast/stages/02-networking-nva/landing.tf index be051b766..5a990030f 100644 --- a/fast/stages/02-networking-nva/landing.tf +++ b/fast/stages/02-networking-nva/landing.tf @@ -57,15 +57,16 @@ module "landing-untrusted-vpc" { } module "landing-untrusted-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.landing-project.project_id - network = module.landing-untrusted-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/landing-untrusted" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.landing-project.project_id + network = module.landing-untrusted-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/landing-untrusted" + } } # NAT @@ -123,13 +124,14 @@ module "landing-trusted-vpc" { } module "landing-trusted-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.landing-project.project_id - network = module.landing-trusted-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/landing-trusted" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.landing-project.project_id + network = module.landing-trusted-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/landing-trusted" + } } diff --git a/fast/stages/02-networking-nva/spoke-dev.tf b/fast/stages/02-networking-nva/spoke-dev.tf index 3c6843e2a..fb88384c4 100644 --- a/fast/stages/02-networking-nva/spoke-dev.tf +++ b/fast/stages/02-networking-nva/spoke-dev.tf @@ -97,15 +97,16 @@ module "dev-spoke-vpc" { } module "dev-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.dev-spoke-project.project_id - network = module.dev-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/dev" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.dev-spoke-project.project_id + network = module.dev-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/dev" + } } module "peering-dev" { diff --git a/fast/stages/02-networking-nva/spoke-prod.tf b/fast/stages/02-networking-nva/spoke-prod.tf index 5d35ca8fe..484550aca 100644 --- a/fast/stages/02-networking-nva/spoke-prod.tf +++ b/fast/stages/02-networking-nva/spoke-prod.tf @@ -97,15 +97,16 @@ module "prod-spoke-vpc" { } module "prod-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.prod-spoke-project.project_id - network = module.prod-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/prod" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.prod-spoke-project.project_id + network = module.prod-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/prod" + } } module "peering-prod" { diff --git a/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml index 3e2d9cc9d..cab42edc9 100644 --- a/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml +++ b/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml @@ -1,27 +1,21 @@ # skip boilerplate check -ingress-allow-composer-nodes: - description: "Allow traffic to Composer nodes." - direction: INGRESS - action: allow - sources: - - composer-worker - targets: - - composer-worker - use_service_accounts: false - rules: - - protocol: tcp - ports: [80, 443, 3306, 3307] - -ingress-allow-dataflow-load: - description: "Allow traffic to Dataflow nodes." - direction: INGRESS - action: allow - sources: - - dataflow - targets: - - dataflow - use_service_accounts: false - rules: - - protocol: tcp - ports: [12345, 12346] +ingress: + ingress-allow-composer-nodes: + description: "Allow traffic to Composer nodes." + sources: + - composer-worker + targets: + - composer-worker + rules: + - protocol: tcp + ports: [80, 443, 3306, 3307] + ingress-allow-dataflow-load: + description: "Allow traffic to Dataflow nodes." + sources: + - dataflow + targets: + - dataflow + rules: + - protocol: tcp + ports: [12345, 12346] diff --git a/fast/stages/02-networking-peering/data/firewall-rules/landing/rules.yaml b/fast/stages/02-networking-peering/data/firewall-rules/landing/rules.yaml index e72b7c9c7..3c1425a7c 100644 --- a/fast/stages/02-networking-peering/data/firewall-rules/landing/rules.yaml +++ b/fast/stages/02-networking-peering/data/firewall-rules/landing/rules.yaml @@ -1,15 +1,11 @@ # skip boilerplate check -allow-onprem-probes-example: - description: "Allow traffic from onprem probes" - direction: INGRESS - action: allow - sources: [] - ranges: - - $onprem_probes - targets: [] - use_service_accounts: false - rules: - - protocol: tcp - ports: - - 12345 +ingress: + allow-onprem-probes-example: + description: "Allow traffic from onprem probes" + source_ranges: + - onprem_probes + rules: + - protocol: tcp + ports: + - 12345 diff --git a/fast/stages/02-networking-peering/landing.tf b/fast/stages/02-networking-peering/landing.tf index ccd0d6254..83a0d509a 100644 --- a/fast/stages/02-networking-peering/landing.tf +++ b/fast/stages/02-networking-peering/landing.tf @@ -67,15 +67,16 @@ module "landing-vpc" { } module "landing-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.landing-project.project_id - network = module.landing-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/landing" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.landing-project.project_id + network = module.landing-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/landing" + } } module "landing-nat-ew1" { diff --git a/fast/stages/02-networking-peering/spoke-dev.tf b/fast/stages/02-networking-peering/spoke-dev.tf index 9fe6c480f..e67cfb70d 100644 --- a/fast/stages/02-networking-peering/spoke-dev.tf +++ b/fast/stages/02-networking-peering/spoke-dev.tf @@ -67,15 +67,16 @@ module "dev-spoke-vpc" { } module "dev-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.dev-spoke-project.project_id - network = module.dev-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/dev" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.dev-spoke-project.project_id + network = module.dev-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/dev" + } } module "dev-spoke-cloudnat" { diff --git a/fast/stages/02-networking-peering/spoke-prod.tf b/fast/stages/02-networking-peering/spoke-prod.tf index 8ff69a98c..cf49152fa 100644 --- a/fast/stages/02-networking-peering/spoke-prod.tf +++ b/fast/stages/02-networking-peering/spoke-prod.tf @@ -67,15 +67,16 @@ module "prod-spoke-vpc" { } module "prod-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.prod-spoke-project.project_id - network = module.prod-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/prod" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.prod-spoke-project.project_id + network = module.prod-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/prod" + } } module "prod-spoke-cloudnat" { diff --git a/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml index d4df8cdc3..67386c446 100644 --- a/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml +++ b/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml @@ -1,27 +1,17 @@ # skip boilerplate check -ingress-allow-composer-nodes: - description: "Allow traffic to Composer nodes." - direction: INGRESS - action: allow - sources: [] - ranges: ["0.0.0.0/0"] - targets: - - composer-worker - use_service_accounts: false - rules: - - protocol: tcp - ports: [80, 443, 3306, 3307] - -ingress-allow-dataflow-load: - description: "Allow traffic to Dataflow nodes." - direction: INGRESS - action: allow - sources: [] - ranges: ["0.0.0.0/0"] - targets: - - dataflow - use_service_accounts: false - rules: - - protocol: tcp - ports: [12345, 12346] +ingress: + ingress-allow-composer-nodes: + description: "Allow traffic to Composer nodes." + targets: + - composer-worker + rules: + - protocol: tcp + ports: [80, 443, 3306, 3307] + ingress-allow-dataflow-load: + description: "Allow traffic to Dataflow nodes." + targets: + - dataflow + rules: + - protocol: tcp + ports: [12345, 12346] diff --git a/fast/stages/02-networking-separate-envs/spoke-dev.tf b/fast/stages/02-networking-separate-envs/spoke-dev.tf index 08eac2305..ca7d8d468 100644 --- a/fast/stages/02-networking-separate-envs/spoke-dev.tf +++ b/fast/stages/02-networking-separate-envs/spoke-dev.tf @@ -66,15 +66,16 @@ module "dev-spoke-vpc" { } module "dev-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.dev-spoke-project.project_id - network = module.dev-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/dev" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.dev-spoke-project.project_id + network = module.dev-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/dev" + } } module "dev-spoke-cloudnat" { diff --git a/fast/stages/02-networking-separate-envs/spoke-prod.tf b/fast/stages/02-networking-separate-envs/spoke-prod.tf index 4261f1ce0..eba530a6c 100644 --- a/fast/stages/02-networking-separate-envs/spoke-prod.tf +++ b/fast/stages/02-networking-separate-envs/spoke-prod.tf @@ -66,15 +66,16 @@ module "prod-spoke-vpc" { } module "prod-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.prod-spoke-project.project_id - network = module.prod-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/prod" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.prod-spoke-project.project_id + network = module.prod-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/prod" + } } module "prod-spoke-cloudnat" { diff --git a/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml index 3e2d9cc9d..cab42edc9 100644 --- a/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml +++ b/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml @@ -1,27 +1,21 @@ # skip boilerplate check -ingress-allow-composer-nodes: - description: "Allow traffic to Composer nodes." - direction: INGRESS - action: allow - sources: - - composer-worker - targets: - - composer-worker - use_service_accounts: false - rules: - - protocol: tcp - ports: [80, 443, 3306, 3307] - -ingress-allow-dataflow-load: - description: "Allow traffic to Dataflow nodes." - direction: INGRESS - action: allow - sources: - - dataflow - targets: - - dataflow - use_service_accounts: false - rules: - - protocol: tcp - ports: [12345, 12346] +ingress: + ingress-allow-composer-nodes: + description: "Allow traffic to Composer nodes." + sources: + - composer-worker + targets: + - composer-worker + rules: + - protocol: tcp + ports: [80, 443, 3306, 3307] + ingress-allow-dataflow-load: + description: "Allow traffic to Dataflow nodes." + sources: + - dataflow + targets: + - dataflow + rules: + - protocol: tcp + ports: [12345, 12346] diff --git a/fast/stages/02-networking-vpn/data/firewall-rules/landing/rules.yaml b/fast/stages/02-networking-vpn/data/firewall-rules/landing/rules.yaml index e72b7c9c7..3c1425a7c 100644 --- a/fast/stages/02-networking-vpn/data/firewall-rules/landing/rules.yaml +++ b/fast/stages/02-networking-vpn/data/firewall-rules/landing/rules.yaml @@ -1,15 +1,11 @@ # skip boilerplate check -allow-onprem-probes-example: - description: "Allow traffic from onprem probes" - direction: INGRESS - action: allow - sources: [] - ranges: - - $onprem_probes - targets: [] - use_service_accounts: false - rules: - - protocol: tcp - ports: - - 12345 +ingress: + allow-onprem-probes-example: + description: "Allow traffic from onprem probes" + source_ranges: + - onprem_probes + rules: + - protocol: tcp + ports: + - 12345 diff --git a/fast/stages/02-networking-vpn/landing.tf b/fast/stages/02-networking-vpn/landing.tf index ccd0d6254..83a0d509a 100644 --- a/fast/stages/02-networking-vpn/landing.tf +++ b/fast/stages/02-networking-vpn/landing.tf @@ -67,15 +67,16 @@ module "landing-vpc" { } module "landing-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.landing-project.project_id - network = module.landing-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/landing" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.landing-project.project_id + network = module.landing-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/landing" + } } module "landing-nat-ew1" { diff --git a/fast/stages/02-networking-vpn/spoke-dev.tf b/fast/stages/02-networking-vpn/spoke-dev.tf index 9fe6c480f..e67cfb70d 100644 --- a/fast/stages/02-networking-vpn/spoke-dev.tf +++ b/fast/stages/02-networking-vpn/spoke-dev.tf @@ -67,15 +67,16 @@ module "dev-spoke-vpc" { } module "dev-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.dev-spoke-project.project_id - network = module.dev-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/dev" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.dev-spoke-project.project_id + network = module.dev-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/dev" + } } module "dev-spoke-cloudnat" { diff --git a/fast/stages/02-networking-vpn/spoke-prod.tf b/fast/stages/02-networking-vpn/spoke-prod.tf index 8ff69a98c..cf49152fa 100644 --- a/fast/stages/02-networking-vpn/spoke-prod.tf +++ b/fast/stages/02-networking-vpn/spoke-prod.tf @@ -67,15 +67,16 @@ module "prod-spoke-vpc" { } module "prod-spoke-firewall" { - source = "../../../modules/net-vpc-firewall" - project_id = module.prod-spoke-project.project_id - network = module.prod-spoke-vpc.name - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - data_folder = "${var.data_dir}/firewall-rules/prod" - cidr_template_file = "${var.data_dir}/cidrs.yaml" + source = "../../../modules/net-vpc-firewall" + project_id = module.prod-spoke-project.project_id + network = module.prod-spoke-vpc.name + default_rules_config = { + disabled = true + } + factories_config = { + cidr_tpl_file = "${var.data_dir}/cidrs.yaml" + rules_folder = "${var.data_dir}/firewall-rules/prod" + } } module "prod-spoke-cloudnat" { diff --git a/modules/gke-hub/README.md b/modules/gke-hub/README.md index 1a3c547c6..17069180a 100644 --- a/modules/gke-hub/README.md +++ b/modules/gke-hub/README.md @@ -178,50 +178,28 @@ module "firewall" { source = "./fabric/modules/net-vpc-firewall" project_id = module.project.project_id network = module.vpc.name - custom_rules = { + ingress_rules = { allow-mesh = { - description = "Allow mesh" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = ["10.1.0.0/16", "10.3.0.0/16"] - targets = ["cluster-1-node", "cluster-2-node"] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = null }, - { protocol = "udp", ports = null }, - { protocol = "icmp", ports = null }, - { protocol = "esp", ports = null }, - { protocol = "ah", ports = null }, - { protocol = "sctp", ports = null }] - extra_attributes = { - priority = 900 - } - }, + description = "Allow mesh" + priority = 900 + source_ranges = ["10.1.0.0/16", "10.3.0.0/16"] + targets = ["cluster-1-node", "cluster-2-node"] + }, "allow-cluster-1-istio" = { - description = "Allow istio sidecar injection, istioctl version and istioctl ps" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = [ "192.168.1.0/28" ] - targets = ["cluster-1-node"] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = [8080, 15014, 15017] }] - extra_attributes = { - priority = 1000 - } + description = "Allow istio sidecar injection, istioctl version and istioctl ps" + source_ranges = ["192.168.1.0/28"] + targets = ["cluster-1-node"] + rules = [ + { protocol = "tcp", ports = [8080, 15014, 15017] } + ] }, "allow-cluster-2-istio" = { - description = "Allow istio sidecar injection, istioctl version and istioctl ps" - direction = "INGRESS" - action = "allow" - sources = [] - ranges = [ "192.168.2.0/28" ] - targets = ["cluster-2-node"] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = [8080, 15014, 15017] }] - extra_attributes = { - priority = 1000 - } + description = "Allow istio sidecar injection, istioctl version and istioctl ps" + source_ranges = ["192.168.2.0/28"] + targets = ["cluster-2-node"] + rules = [ + { protocol = "tcp", ports = [8080, 15014, 15017] } + ] } } } diff --git a/modules/net-vpc-firewall/README.md b/modules/net-vpc-firewall/README.md index 188dbc0b1..7cc0d452f 100644 --- a/modules/net-vpc-firewall/README.md +++ b/modules/net-vpc-firewall/README.md @@ -2,11 +2,10 @@ This module allows creation and management of different types of firewall rules for a single VPC network: -- blanket ingress rules based on IP ranges that allow all traffic via the `admin_ranges` variable -- simplified tag-based ingress rules for the HTTP, HTTPS and SSH protocols via the `xxx_source_ranges` variables; HTTP and HTTPS tags match those set by the console via the "Allow HTTP(S) traffic" instance flags -- custom rules via the `custom_rules` variables +- custom rules via the `egress_rules` and `ingress_rules` variables +- optional predefined rules that simplify prototyping via the `default_rules_config` variable -The simplified tag-based rules are enabled by default, set to the ranges of the GCP health checkers for HTTP/HTTPS, and the IAP forwarders for SSH. To disable them set the corresponding variables to empty lists. +The predefined rules are enabled by default and set to the ranges of the GCP health checkers for HTTP/HTTPS, and the IAP forwarders for SSH. See the relevant section below on how to configure or disable them. ## Examples @@ -16,10 +15,12 @@ This is often useful for prototyping or testing infrastructure, allowing open in ```hcl module "firewall" { - source = "./fabric/modules/net-vpc-firewall" - project_id = "my-project" - network = "my-network" - admin_ranges = ["10.0.0.0/8"] + source = "./fabric/modules/net-vpc-firewall" + project_id = "my-project" + network = "my-network" + default_rules_config = { + admin_ranges = ["10.0.0.0/8"] + } } # tftest modules=1 resources=4 ``` @@ -28,68 +29,117 @@ module "firewall" { This is an example of how to define custom rules, with a sample rule allowing open ingress for the NTP protocol to instances with the `ntp-svc` tag. -```hcl -module "firewall" { - source = "./fabric/modules/net-vpc-firewall" - project_id = "my-project" - network = "my-network" - admin_ranges = ["10.0.0.0/8"] - custom_rules = { - ntp-svc = { - description = "NTP service." - direction = "INGRESS" - action = "allow" - sources = [] - ranges = ["0.0.0.0/0"] - targets = ["ntp-svc"] - use_service_accounts = false - rules = [{ protocol = "udp", ports = [123] }] - extra_attributes = {} - } - } -} -# tftest modules=1 resources=5 -``` +Some implicit defaults are used in the rules variable types and can be controlled by explicitly setting specific attributes: -### No predefined rules - -If you don't want any predefined rules set `admin_ranges`, `http_source_ranges`, `https_source_ranges` and `ssh_source_ranges` to an empty list. +- action is controlled via the `deny` attribute which defaults to `true` for egress and `false` for ingress +- priority defaults to `1000` +- destination ranges (for egress) and source ranges (for ingress) default to `["0.0.0.0/0"]` if not explicitly set +- rules default to all protocols if not set ```hcl module "firewall" { - source = "./fabric/modules/net-vpc-firewall" - project_id = "my-project" - network = "my-network" - admin_ranges = [] - http_source_ranges = [] - https_source_ranges = [] - ssh_source_ranges = [] - custom_rules = { - allow-https = { - description = "Allow HTTPS from internal networks." - direction = "INGRESS" - action = "allow" - sources = [] - ranges = ["rfc1918"] - targets = [] - use_service_accounts = false - rules = [{ protocol = "tcp", ports = [443] }] - extra_attributes = {} + source = "./fabric/modules/net-vpc-firewall" + project_id = "my-project" + network = "my-network" + default_rules_config = { + admin_ranges = ["10.0.0.0/8"] + } + egress_rules = { + # implicit `deny` action + allow-egress-rfc1918 = { + description = "Allow egress to RFC 1918 ranges." + destination_ranges = [ + "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" + ] + # implicit { protocol = "all" } rule + } + deny-egress-all = { + description = "Block egress." + # implicit ["0.0.0.0/0"] destination ranges + # implicit { protocol = "all" } rule + } + } + ingress_rules = { + # implicit `allow` action + allow-ingress-ntp = { + description = "Allow NTP service based on tag." + source_ranges = ["0.0.0.0/0"] + targets = ["ntp-svc"] + rules = [{ protocol = "udp", ports = [123] }] } } } -# tftest modules=1 resources=1 +# tftest modules=1 resources=7 ``` +### Controlling or turning off default rules + +Predefined rules can be controlled or turned off via the `default_rules_config` variable. + +#### Overriding default tags and ranges + +Each protocol rule has a default set of tags and ranges: + +- the health check range and the `http-server`/`https-server` tag for HTTP/HTTPS, matching tags set via GCP console flags on GCE instances +- the IAP forwarders range and `ssh` tag for SSH + +Default tags and ranges can be overridden for each protocol, like shown here for SSH: + +```hcl +module "firewall" { + source = "./fabric/modules/net-vpc-firewall" + project_id = "my-project" + network = "my-network" + default_rules_config = { + ssh_ranges = ["10.0.0.0/8"] + ssh_rags = ["ssh-default"] + } +} +# tftest modules=1 resources=3 +``` + +#### Disabling predefined rules + +Default rules can be disabled individually by specifying an empty set of ranges: + +```hcl +module "firewall" { + source = "./fabric/modules/net-vpc-firewall" + project_id = "my-project" + network = "my-network" + default_rules_config = { + ssh_ranges = [] + } +} +# tftest modules=1 resources=2 +``` + +Or the entire set of rules can be disabled via the `disabled` attribute: + +```hcl +module "firewall" { + source = "./fabric/modules/net-vpc-firewall" + project_id = "my-project" + network = "my-network" + default_rules_config = { + disabled = true + } +} +# tftest modules=0 resources=0 +``` ### Rules Factory + The module includes a rules factory (see [Resource Factories](../../blueprints/factories/)) for the massive creation of rules leveraging YaML configuration files. Each configuration file can optionally contain more than one rule which a structure that reflects the `custom_rules` variable. ```hcl module "firewall" { - source = "./fabric/modules/net-vpc-firewall" - project_id = "my-project" - network = "my-network" + source = "./fabric/modules/net-vpc-firewall" + project_id = "my-project" + network = "my-network" + factories_config = { + + } data_folder = "config/firewall" cidr_template_file = "config/cidr_template.yaml" } @@ -100,13 +150,9 @@ module "firewall" { # ./config/firewall/load_balancers.yaml allow-healthchecks: description: Allow ingress from healthchecks. - direction: INGRESS - action: allow - sources: [] ranges: - - $healthchecks + - healthchecks targets: ["lb-backends"] - use_service_accounts: false rules: - protocol: tcp ports: @@ -129,26 +175,19 @@ healthchecks: | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [network](variables.tf#L80) | Name of the network this set of firewall rules applies to. | string | ✓ | | -| [project_id](variables.tf#L85) | Project id of the project that holds the network. | string | ✓ | | -| [admin_ranges](variables.tf#L17) | IP CIDR ranges that have complete access to all subnets. | list(string) | | [] | -| [cidr_template_file](variables.tf#L23) | Path for optional file containing name->cidr_list map to be used by the rules factory. | string | | null | -| [custom_rules](variables.tf#L29) | List of custom rule definitions (refer to variables file for syntax). | map(object({…})) | | {} | -| [data_folder](variables.tf#L48) | Path for optional folder containing firewall rules defined as YaML objects used by the rules factory. | string | | null | -| [http_source_ranges](variables.tf#L54) | List of IP CIDR ranges for tag-based HTTP rule, defaults to the health checkers ranges. | list(string) | | ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] | -| [https_source_ranges](variables.tf#L60) | List of IP CIDR ranges for tag-based HTTPS rule, defaults to the health checkers ranges. | list(string) | | ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] | -| [named_ranges](variables.tf#L66) | Names that can be used of valid values for the `ranges` field of `custom_rules`. | map(list(string)) | | {…} | -| [ssh_source_ranges](variables.tf#L90) | List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range. | list(string) | | ["35.235.240.0/20"] | +| [network](variables.tf#L109) | Name of the network this set of firewall rules applies to. | string | ✓ | | +| [project_id](variables.tf#L114) | Project id of the project that holds the network. | string | ✓ | | +| [default_rules_config](variables.tf#L17) | Optionally created convenience rules. Set the variable or individual members to null to disable. | object({…}) | | {} | +| [egress_rules](variables.tf#L37) | List of egress rule definitions, default to deny action. | map(object({…})) | | {} | +| [factories_config](variables.tf#L83) | Paths to data files and folders that enable factory functionality. | object({…}) | | null | +| [ingress_rules](variables.tf#L60) | List of ingress rule definitions, default to allow action. | map(object({…})) | | {} | +| [named_ranges](variables.tf#L92) | Define mapping of names to ranges that can be used in custom rules. | map(list(string)) | | {…} | ## Outputs | name | description | sensitive | |---|---|:---:| -| [admin_ranges](outputs.tf#L17) | Admin ranges data. | | -| [custom_egress_allow_rules](outputs.tf#L26) | Custom egress rules with allow blocks. | | -| [custom_egress_deny_rules](outputs.tf#L34) | Custom egress rules with allow blocks. | | -| [custom_ingress_allow_rules](outputs.tf#L42) | Custom ingress rules with allow blocks. | | -| [custom_ingress_deny_rules](outputs.tf#L50) | Custom ingress rules with deny blocks. | | -| [rules](outputs.tf#L58) | All google_compute_firewall resources created. | | +| [default_rules](outputs.tf#L17) | Default rule resources. | | +| [rules](outputs.tf#L27) | Custom rule resources. | | diff --git a/modules/net-vpc-firewall/default-rules.tf b/modules/net-vpc-firewall/default-rules.tf new file mode 100644 index 000000000..bbca6dd57 --- /dev/null +++ b/modules/net-vpc-firewall/default-rules.tf @@ -0,0 +1,77 @@ +/** + * 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 Optional default rule resources. + +locals { + default_rules = { + for k, v in var.default_rules_config : + k => var.default_rules_config.disabled == true || v == null ? [] : v + if k != "disabled" + } +} + +resource "google_compute_firewall" "allow-admins" { + count = length(local.default_rules.admin_ranges) > 0 ? 1 : 0 + name = "${var.network}-ingress-admins" + description = "Access from the admin subnet to all subnets." + network = var.network + project = var.project_id + source_ranges = local.default_rules.admin_ranges + allow { protocol = "all" } +} + +resource "google_compute_firewall" "allow-tag-http" { + count = length(local.default_rules.http_ranges) > 0 ? 1 : 0 + name = "${var.network}-ingress-tag-http" + description = "Allow http to machines with matching tags." + network = var.network + project = var.project_id + source_ranges = local.default_rules.http_ranges + target_tags = local.default_rules.http_tags + allow { + protocol = "tcp" + ports = ["80"] + } +} + +resource "google_compute_firewall" "allow-tag-https" { + count = length(local.default_rules.https_ranges) > 0 ? 1 : 0 + name = "${var.network}-ingress-tag-https" + description = "Allow http to machines with matching tags." + network = var.network + project = var.project_id + source_ranges = local.default_rules.https_ranges + target_tags = local.default_rules.https_tags + allow { + protocol = "tcp" + ports = ["443"] + } +} + +resource "google_compute_firewall" "allow-tag-ssh" { + count = length(local.default_rules.ssh_ranges) > 0 ? 1 : 0 + name = "${var.network}-ingress-tag-ssh" + description = "Allow SSH to machines with matching tags." + network = var.network + project = var.project_id + source_ranges = local.default_rules.ssh_ranges + target_tags = local.default_rules.ssh_tags + allow { + protocol = "tcp" + ports = ["22"] + } +} diff --git a/modules/net-vpc-firewall/main.tf b/modules/net-vpc-firewall/main.tf index c08b2d165..708b8844b 100644 --- a/modules/net-vpc-firewall/main.tf +++ b/modules/net-vpc-firewall/main.tf @@ -15,149 +15,125 @@ */ locals { - _custom_rules = { - for id, rule in var.custom_rules : - id => merge(rule, { - # make rules a map so we use it in a for_each - rules = { for index, ports in rule.rules : index => ports } - # lookup any named ranges references - ranges = flatten([ - for range in rule.ranges : - try(var.named_ranges[range], range) + # define list of rule files + _factory_rule_files = [ + for f in try(fileset(var.factories_config.rules_folder, "**/*.yaml"), []) : + "${var.factories_config.rules_folder}/${f}" + ] + # decode rule files and account for optional attributes + _factory_rule_list = flatten([ + for f in local._factory_rule_files : [ + for direction, ruleset in yamldecode(file(f)) : [ + for name, rule in ruleset : { + name = name + deny = try(rule.deny, false) + rules = try(rule.rules, [{ protocol = "all" }]) + description = try(rule.description, null) + destination_ranges = try(rule.destination_ranges, null) + direction = upper(direction) + disabled = try(rule.disabled, null) + enable_logging = try(rule.enable_logging, null) + priority = try(rule.priority, 1000) + source_ranges = try(rule.source_ranges, null) + sources = try(rule.sources, null) + targets = try(rule.targets, null) + use_service_accounts = try(rule.use_service_accounts, false) + } + ] + ] + ]) + _factory_rules = { + for r in local._factory_rule_list : r.name => r + if contains(["EGRESS", "INGRESS"], r.direction) + } + _named_ranges = merge( + try(yamldecode(file(var.factories_config.cidr_tpl_file)), {}), + var.named_ranges + ) + _rules = merge( + local._factory_rules, local._rules_egress, local._rules_ingress + ) + _rules_egress = { + for name, rule in merge(var.egress_rules) : + name => merge(rule, { direction = "EGRESS" }) + } + _rules_ingress = { + for name, rule in merge(var.ingress_rules) : + name => merge(rule, { direction = "INGRESS" }) + } + # convert rules data to resource format and replace range template variables + rules = { + for name, rule in local._rules : + name => merge(rule, { + action = rule.deny == true ? "DENY" : "ALLOW" + destination_ranges = flatten([ + for range in coalesce(try(rule.destination_ranges, null), []) : + try(local._named_ranges[range], range) + ]) + rules = { for k, v in rule.rules : k => v } + source_ranges = flatten([ + for range in coalesce(try(rule.source_ranges, null), []) : + try(local._named_ranges[range], range) ]) }) } - - cidrs = try({ - for name, cidrs in yamldecode(file(var.cidr_template_file)) : - name => cidrs - }, {}) - - _factory_rules_raw = flatten([ - for file in try(fileset(var.data_folder, "**/*.yaml"), []) : [ - for key, ruleset in yamldecode(file("${var.data_folder}/${file}")) : - merge(ruleset, { - name = "${key}" - rules = { for index, ports in ruleset.rules : index => ports } - ranges = try(ruleset.ranges, null) == null ? null : flatten( - [for cidr in ruleset.ranges : - can(regex("^\\$", cidr)) - ? local.cidrs[trimprefix(cidr, "$")] - : [cidr] - ]) - extra_attributes = try(ruleset.extra_attributes, {}) - }) - ] - ]) - - _factory_rules = { - for d in local._factory_rules_raw : d["name"] => d - } - - custom_rules = merge(local._custom_rules, local._factory_rules) } - -############################################################################### -# rules based on IP ranges -############################################################################### - -resource "google_compute_firewall" "allow-admins" { - count = length(var.admin_ranges) > 0 ? 1 : 0 - name = "${var.network}-ingress-admins" - description = "Access from the admin subnet to all subnets" - network = var.network - project = var.project_id - source_ranges = var.admin_ranges - allow { protocol = "all" } -} - -############################################################################### -# rules based on tags -############################################################################### - -resource "google_compute_firewall" "allow-tag-ssh" { - count = length(var.ssh_source_ranges) > 0 ? 1 : 0 - name = "${var.network}-ingress-tag-ssh" - description = "Allow SSH to machines with the 'ssh' tag" - network = var.network - project = var.project_id - source_ranges = var.ssh_source_ranges - target_tags = ["ssh"] - allow { - protocol = "tcp" - ports = ["22"] - } -} - -resource "google_compute_firewall" "allow-tag-http" { - count = length(var.http_source_ranges) > 0 ? 1 : 0 - name = "${var.network}-ingress-tag-http" - description = "Allow HTTP to machines with the 'http-server' tag" - network = var.network - project = var.project_id - source_ranges = var.http_source_ranges - target_tags = ["http-server"] - allow { - protocol = "tcp" - ports = ["80"] - } -} - -resource "google_compute_firewall" "allow-tag-https" { - count = length(var.https_source_ranges) > 0 ? 1 : 0 - name = "${var.network}-ingress-tag-https" - description = "Allow HTTPS to machines with the 'https' tag" - network = var.network - project = var.project_id - source_ranges = var.https_source_ranges - target_tags = ["https-server"] - allow { - protocol = "tcp" - ports = ["443"] - } -} - -################################################################################ -# dynamic rules # -################################################################################ - resource "google_compute_firewall" "custom-rules" { - # provider = "google-beta" - for_each = local.custom_rules + for_each = local.rules + project = var.project_id + network = var.network name = each.key description = each.value.description direction = each.value.direction - network = var.network - project = var.project_id source_ranges = ( each.value.direction == "INGRESS" - ? coalesce(each.value.ranges, []) == [] ? ["0.0.0.0/0"] : each.value.ranges - : null + ? ( + coalesce(each.value.source_ranges, []) == [] + ? ["0.0.0.0/0"] + : each.value.source_ranges + ) : null ) destination_ranges = ( each.value.direction == "EGRESS" - ? coalesce(each.value.ranges, []) == [] ? ["0.0.0.0/0"] : each.value.ranges + ? ( + coalesce(each.value.destination_ranges, []) == [] + ? ["0.0.0.0/0"] + : each.value.destination_ranges + ) : null + ) + source_tags = ( + each.value.use_service_accounts || each.value.direction == "EGRESS" + ? null + : each.value.sources + ) + source_service_accounts = ( + each.value.use_service_accounts && each.value.direction == "INGRESS" + ? each.value.sources : null ) - source_tags = each.value.use_service_accounts || each.value.direction == "EGRESS" ? null : each.value.sources - source_service_accounts = each.value.use_service_accounts && each.value.direction == "INGRESS" ? each.value.sources : null - target_tags = each.value.use_service_accounts ? null : each.value.targets - target_service_accounts = each.value.use_service_accounts ? each.value.targets : null - disabled = lookup(each.value.extra_attributes, "disabled", false) - priority = lookup(each.value.extra_attributes, "priority", 1000) + target_tags = ( + each.value.use_service_accounts ? null : each.value.targets + ) + target_service_accounts = ( + each.value.use_service_accounts ? each.value.targets : null + ) + disabled = each.value.disabled == true + priority = each.value.priority dynamic "log_config" { - for_each = lookup(each.value.extra_attributes, "logging", null) != null ? [each.value.extra_attributes.logging] : [] - iterator = logging_config + for_each = each.value.enable_logging == null ? [] : [""] content { - metadata = logging_config.value + metadata = ( + try(each.value.enable_logging.include_metadata, null) == true + ? "INCLUDE_ALL_METADATA" + : "EXCLUDE_ALL_METADATA" + ) } } dynamic "deny" { - for_each = each.value.action == "deny" ? each.value.rules : {} - + for_each = each.value.action == "DENY" ? each.value.rules : {} iterator = rule content { protocol = rule.value.protocol @@ -166,8 +142,7 @@ resource "google_compute_firewall" "custom-rules" { } dynamic "allow" { - for_each = each.value.action == "allow" ? each.value.rules : {} - + for_each = each.value.action == "ALLOW" ? each.value.rules : {} iterator = rule content { protocol = rule.value.protocol diff --git a/modules/net-vpc-firewall/outputs.tf b/modules/net-vpc-firewall/outputs.tf index f784583c5..9206ab546 100644 --- a/modules/net-vpc-firewall/outputs.tf +++ b/modules/net-vpc-firewall/outputs.tf @@ -14,54 +14,17 @@ * limitations under the License. */ -output "admin_ranges" { - description = "Admin ranges data." - +output "default_rules" { + description = "Default rule resources." value = { - enabled = length(var.admin_ranges) > 0 - ranges = join(",", var.admin_ranges) + admin = try(google_compute_firewall.allow-admins, null) + http = try(google_compute_firewall.allow-tag-http, null) + https = try(google_compute_firewall.allow-tag-https, null) + ssh = try(google_compute_firewall.allow-tag-ssh, null) } } -output "custom_egress_allow_rules" { - description = "Custom egress rules with allow blocks." - value = [ - for rule in google_compute_firewall.custom-rules : - rule.name if rule.direction == "EGRESS" && try(length(rule.allow), 0) > 0 - ] -} - -output "custom_egress_deny_rules" { - description = "Custom egress rules with allow blocks." - value = [ - for rule in google_compute_firewall.custom-rules : - rule.name if rule.direction == "EGRESS" && try(length(rule.deny), 0) > 0 - ] -} - -output "custom_ingress_allow_rules" { - description = "Custom ingress rules with allow blocks." - value = [ - for rule in google_compute_firewall.custom-rules : - rule.name if rule.direction == "INGRESS" && try(length(rule.allow), 0) > 0 - ] -} - -output "custom_ingress_deny_rules" { - description = "Custom ingress rules with deny blocks." - value = [ - for rule in google_compute_firewall.custom-rules : - rule.name if rule.direction == "INGRESS" && try(length(rule.deny), 0) > 0 - ] -} - output "rules" { - description = "All google_compute_firewall resources created." - value = merge( - google_compute_firewall.custom-rules, - try({ (google_compute_firewall.allow-admins.0.name) = google_compute_firewall.allow-admins.0 }, {}), - try({ (google_compute_firewall.allow-tag-ssh.0.name) = google_compute_firewall.allow-tag-ssh.0 }, {}), - try({ (google_compute_firewall.allow-tag-http.0.name) = google_compute_firewall.allow-tag-http.0 }, {}), - try({ (google_compute_firewall.allow-tag-https.0.name) = google_compute_firewall.allow-tag-https.0 }, {}) - ) + description = "Custom rule resources." + value = google_compute_firewall.custom-rules } diff --git a/modules/net-vpc-firewall/variables.tf b/modules/net-vpc-firewall/variables.tf index b0a2a9d79..dd8033342 100644 --- a/modules/net-vpc-firewall/variables.tf +++ b/modules/net-vpc-firewall/variables.tf @@ -14,67 +14,96 @@ * limitations under the License. */ -variable "admin_ranges" { - description = "IP CIDR ranges that have complete access to all subnets." - type = list(string) - default = [] +variable "default_rules_config" { + description = "Optionally created convenience rules. Set the variable or individual members to null to disable." + type = object({ + admin_ranges = optional(list(string)) + disabled = optional(bool, false) + http_ranges = optional(list(string), [ + "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] + ) + http_tags = optional(list(string), ["http-server"]) + https_ranges = optional(list(string), [ + "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] + ) + https_tags = optional(list(string), ["https-server"]) + ssh_ranges = optional(list(string), ["35.235.240.0/20"]) + ssh_tags = optional(list(string), ["ssh"]) + }) + default = {} + nullable = false } -variable "cidr_template_file" { - description = "Path for optional file containing name->cidr_list map to be used by the rules factory." - type = string - default = null -} - -variable "custom_rules" { - description = "List of custom rule definitions (refer to variables file for syntax)." +variable "egress_rules" { + description = "List of egress rule definitions, default to deny action." type = map(object({ - description = string - direction = string - action = string # (allow|deny) - ranges = list(string) - sources = list(string) - targets = list(string) - use_service_accounts = bool - rules = list(object({ - protocol = string - ports = list(string) + deny = optional(bool, true) + description = optional(string) + destination_ranges = optional(list(string)) + disabled = optional(bool, false) + enable_logging = optional(object({ + include_metadata = optional(bool) })) - extra_attributes = map(string) + priority = optional(number, 1000) + sources = optional(list(string)) + targets = optional(list(string)) + use_service_accounts = optional(bool, false) + rules = optional(list(object({ + protocol = string + ports = optional(list(string)) + })), [{ protocol = "all" }]) })) - default = {} + default = {} + nullable = false } -variable "data_folder" { - description = "Path for optional folder containing firewall rules defined as YaML objects used by the rules factory." - type = string - default = null +variable "ingress_rules" { + description = "List of ingress rule definitions, default to allow action." + type = map(object({ + deny = optional(bool, false) + description = optional(string) + disabled = optional(bool, false) + enable_logging = optional(object({ + include_metadata = optional(bool) + })) + priority = optional(number, 1000) + source_ranges = optional(list(string)) + sources = optional(list(string)) + targets = optional(list(string)) + use_service_accounts = optional(bool, false) + rules = optional(list(object({ + protocol = string + ports = optional(list(string)) + })), [{ protocol = "all" }]) + })) + default = {} + nullable = false } -variable "http_source_ranges" { - description = "List of IP CIDR ranges for tag-based HTTP rule, defaults to the health checkers ranges." - type = list(string) - default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] -} - -variable "https_source_ranges" { - description = "List of IP CIDR ranges for tag-based HTTPS rule, defaults to the health checkers ranges." - type = list(string) - default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] +variable "factories_config" { + description = "Paths to data files and folders that enable factory functionality." + type = object({ + cidr_tpl_file = optional(string) + rules_folder = string + }) + default = null } variable "named_ranges" { - description = "Names that can be used of valid values for the `ranges` field of `custom_rules`." + description = "Define mapping of names to ranges that can be used in custom rules." type = map(list(string)) default = { - any = ["0.0.0.0/0"] - dns-forwarders = ["35.199.192.0/19"] - health-checkers = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] + any = ["0.0.0.0/0"] + dns-forwarders = ["35.199.192.0/19"] + health-checkers = [ + "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22" + ] iap-forwarders = ["35.235.240.0/20"] private-googleapis = ["199.36.153.8/30"] restricted-googleapis = ["199.36.153.4/30"] rfc1918 = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] } + nullable = false } variable "network" { @@ -86,10 +115,3 @@ variable "project_id" { description = "Project id of the project that holds the network." type = string } - -variable "ssh_source_ranges" { - description = "List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range." - type = list(string) - default = ["35.235.240.0/20"] -} - diff --git a/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py b/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py index 7d8a47b15..6e2c141da 100644 --- a/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py +++ b/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py @@ -14,12 +14,11 @@ import os - FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 4 - assert len(resources) == 18 + "Test that plan works and the numbers of resources is as expected." + modules, resources = e2e_plan_runner(FIXTURES_DIR) + assert len(modules) == 4 + assert len(resources) == 20 diff --git a/tests/conftest.py b/tests/conftest.py index 3ec581076..ab4e00e6b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,8 +28,8 @@ BASEDIR = os.path.dirname(os.path.dirname(__file__)) def _plan_runner(): "Returns a function to run Terraform plan on a fixture." - def run_plan(fixture_path=None, targets=None, refresh=True, tmpdir=True, - **tf_vars): + def run_plan(fixture_path=None, extra_files=None, tf_var_file=None, + targets=None, refresh=True, tmpdir=True, **tf_vars): "Runs Terraform plan and returns parsed output." if fixture_path is None: # find out the fixture directory from the caller's directory @@ -46,9 +46,9 @@ def _plan_runner(): shutil.copytree(fixture_path, tmp_path, dirs_exist_ok=True) tf = tftest.TerraformTest(tmp_path if tmpdir else fixture_path, BASEDIR, os.environ.get('TERRAFORM', 'terraform')) - tf.setup(upgrade=True) - plan = tf.plan(output=True, refresh=refresh, tf_vars=tf_vars, - targets=targets) + tf.setup(extra_files=extra_files, upgrade=True) + plan = tf.plan(output=True, refresh=refresh, tf_var_file=tf_var_file, + tf_vars=tf_vars, targets=targets) return plan return run_plan @@ -58,9 +58,11 @@ def _plan_runner(): def plan_runner(_plan_runner): "Returns a function to run Terraform plan on a module fixture." - def run_plan(fixture_path=None, targets=None, **tf_vars): + def run_plan(fixture_path=None, extra_files=None, tf_var_file=None, + targets=None, **tf_vars): "Runs Terraform plan and returns plan and module resources." - plan = _plan_runner(fixture_path, targets=targets, **tf_vars) + plan = _plan_runner(fixture_path, extra_files=extra_files, + tf_var_file=tf_var_file, targets=targets, **tf_vars) # skip the fixture root_module = plan.root_module['child_modules'][0] return plan, root_module['resources'] diff --git a/tests/modules/net_vpc_firewall/fixture/config/firewall/load_balancers.yaml b/tests/modules/net_vpc_firewall/fixture/config/firewall/load_balancers.yaml index 508c9efe1..9e773273a 100644 --- a/tests/modules/net_vpc_firewall/fixture/config/firewall/load_balancers.yaml +++ b/tests/modules/net_vpc_firewall/fixture/config/firewall/load_balancers.yaml @@ -12,17 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -allow-healthchecks: - description: Allow ingress from healthchecks. - direction: INGRESS - action: allow - sources: [] - ranges: - - $healthchecks - targets: ["lb-backends"] - use_service_accounts: false - rules: - - protocol: tcp - ports: - - 80 - - 443 +ingress: + allow-healthchecks: + description: Allow ingress from healthchecks. + source_ranges: + - healthchecks + targets: ["lb-backends"] + rules: + - protocol: tcp + ports: + - 80 + - 443 diff --git a/tests/modules/net_vpc_firewall/fixture/main.tf b/tests/modules/net_vpc_firewall/fixture/main.tf index 26237cd69..e69aeff10 100644 --- a/tests/modules/net_vpc_firewall/fixture/main.tf +++ b/tests/modules/net_vpc_firewall/fixture/main.tf @@ -15,14 +15,11 @@ */ module "firewall" { - source = "../../../../modules/net-vpc-firewall" - project_id = var.project_id - network = var.network - admin_ranges = var.admin_ranges - http_source_ranges = var.http_source_ranges - https_source_ranges = var.https_source_ranges - ssh_source_ranges = var.ssh_source_ranges - custom_rules = var.custom_rules - data_folder = var.data_folder - cidr_template_file = var.cidr_template_file + source = "../../../../modules/net-vpc-firewall" + project_id = "test-project" + network = "test-vpc" + default_rules_config = var.default_rules_config + egress_rules = var.egress_rules + ingress_rules = var.ingress_rules + factories_config = var.factories_config } diff --git a/tests/modules/net_vpc_firewall/fixture/test.rules.tfvars b/tests/modules/net_vpc_firewall/fixture/test.rules.tfvars new file mode 100644 index 000000000..36944bea4 --- /dev/null +++ b/tests/modules/net_vpc_firewall/fixture/test.rules.tfvars @@ -0,0 +1,22 @@ +egress_rules = { + allow-egress-rfc1918 = { + description = "Allow egress to RFC 1918 ranges." + is_egress = true + destination_ranges = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] + } + deny-egress-all = { + description = "Block egress." + is_deny = true + is_egress = true + } +} +ingress_rules = { + allow-ingress-ntp = { + description = "Allow NTP service based on tag." + targets = ["ntp-svc"] + rules = [{ protocol = "udp", ports = [123] }] + } +} +default_rules_config = { + disabled = true +} diff --git a/tests/modules/net_vpc_firewall/fixture/variables.tf b/tests/modules/net_vpc_firewall/fixture/variables.tf index 8627bf813..fd71e93b8 100644 --- a/tests/modules/net_vpc_firewall/fixture/variables.tf +++ b/tests/modules/net_vpc_firewall/fixture/variables.tf @@ -14,84 +14,38 @@ * limitations under the License. */ -variable "admin_ranges" { - description = "IP CIDR ranges that have complete access to all subnets." - type = list(string) - default = [] -} +/** + * 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. + */ -variable "cidr_template_file" { - description = "Path for optional file containing name->cidr_list map to be used by the rules factory." - type = string - default = null -} - -variable "custom_rules" { - description = "List of custom rule definitions (refer to variables file for syntax)." - type = map(object({ - description = string - direction = string - action = string # (allow|deny) - ranges = list(string) - sources = list(string) - targets = list(string) - use_service_accounts = bool - rules = list(object({ - protocol = string - ports = list(string) - })) - extra_attributes = map(string) - })) +variable "default_rules_config" { + type = any default = {} } -variable "data_folder" { - description = "Path for optional folder containing firewall rules defined as YaML objects used by the rules factory." - type = string - default = null +variable "egress_rules" { + type = any + default = {} } -variable "http_source_ranges" { - description = "List of IP CIDR ranges for tag-based HTTP rule, defaults to the health checkers ranges." - type = list(string) - default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] +variable "factories_config" { + type = any + default = null } -variable "https_source_ranges" { - description = "List of IP CIDR ranges for tag-based HTTPS rule, defaults to the health checkers ranges." - type = list(string) - default = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] +variable "ingress_rules" { + type = any + default = {} } - -variable "named_ranges" { - description = "Names that can be used of valid values for the `ranges` field of `custom_rules`." - type = map(list(string)) - default = { - any = ["0.0.0.0/0"] - dns-forwarders = ["35.199.192.0/19"] - health-checkers = ["35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"] - iap-forwarders = ["35.235.240.0/20"] - private-googleapis = ["199.36.153.8/30"] - restricted-googleapis = ["199.36.153.4/30"] - rfc1918 = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] - } -} - -variable "network" { - description = "Name of the network this set of firewall rules applies to." - type = string - default = "vpc" -} - -variable "project_id" { - description = "Project id of the project that holds the network." - type = string - default = "project" -} - -variable "ssh_source_ranges" { - description = "List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range." - type = list(string) - default = ["35.235.240.0/20"] -} - diff --git a/tests/modules/net_vpc_firewall/test_plan.py b/tests/modules/net_vpc_firewall/test_plan.py index 52de2a4f3..cc928e644 100644 --- a/tests/modules/net_vpc_firewall/test_plan.py +++ b/tests/modules/net_vpc_firewall/test_plan.py @@ -12,27 +12,48 @@ # See the License for the specific language governing permissions and # limitations under the License. -def test_vpc_firewall_simple(plan_runner): - "Test vpc with no extra options." +import pytest + + +def test_defaults(plan_runner): + "Test variable defaults." _, resources = plan_runner() assert len(resources) == 3 - assert set([r['type'] for r in resources]) == set( - ['google_compute_firewall']) - assert set([r['values']['name'] for r in resources]) == set( - ['vpc-ingress-tag-http', 'vpc-ingress-tag-https', 'vpc-ingress-tag-ssh']) - assert set([r['values']['project'] for r in resources]) == set(['project']) - assert set([r['values']['network'] for r in resources]) == set(['vpc']) + assert set([r['type'] for r in resources]) == set(['google_compute_firewall']) + assert set([r['values']['name'] for r in resources]) == set([ + 'test-vpc-ingress-tag-http', 'test-vpc-ingress-tag-https', + 'test-vpc-ingress-tag-ssh' + ]) + assert set([r['values']['project'] for r in resources + ]) == set(['test-project']) + assert set([r['values']['network'] for r in resources]) == set(['test-vpc']) -def test_vpc_firewall_factory(plan_runner): - "Test shared vpc variables." - _, resources = plan_runner( - data_folder="config/firewall", - cidr_template_file="config/cidr_template.yaml" - ) +def test_rules(plan_runner): + "Test custom rules." + tfvars = 'test.rules.tfvars' + _, resources = plan_runner(extra_files=[tfvars], tf_var_file=tfvars) + assert len(resources) == 3 + rules = {r['index']: r['values'] for r in resources} + rule = rules['allow-ingress-ntp'] + assert rule['source_ranges'] == ['0.0.0.0/0'] + assert rule['allow'] == [{'ports': ['123'], 'protocol': 'udp'}] + rule = rules['deny-egress-all'] + assert rule['destination_ranges'] == ['0.0.0.0/0'] + assert rule['deny'] == [{'ports': [], 'protocol': 'all'}] + + +def test_factory(plan_runner): + "Test factory." + factories_config = '''{ + cidr_tpl_file = "config/cidr_template.yaml" + rules_folder = "config/firewall" + }''' + _, resources = plan_runner(factories_config=factories_config) assert len(resources) == 4 - factory_rule = [r for r in resources if r["values"] - ["name"] == "allow-healthchecks"][0]["values"] + factory_rule = [ + r for r in resources if r["values"]["name"] == "allow-healthchecks" + ][0]["values"] assert set(factory_rule["source_ranges"]) == set( ["130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22", "35.191.0.0/16"]) assert set(factory_rule["target_tags"]) == set(["lb-backends"])