diff --git a/data-solutions/cmek-via-centralized-kms/main.tf b/data-solutions/cmek-via-centralized-kms/main.tf
index bf19d03f..4f7e351a 100644
--- a/data-solutions/cmek-via-centralized-kms/main.tf
+++ b/data-solutions/cmek-via-centralized-kms/main.tf
@@ -60,11 +60,10 @@ module "vpc" {
}
module "vpc-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = module.project-service.project_id
- network = module.vpc.name
- admin_ranges_enabled = true
- admin_ranges = [var.vpc_ip_cidr_range]
+ source = "../../modules/net-vpc-firewall"
+ project_id = module.project-service.project_id
+ network = module.vpc.name
+ admin_ranges = [var.vpc_ip_cidr_range]
}
###############################################################################
diff --git a/data-solutions/data-platform-foundations/02-resources/main.tf b/data-solutions/data-platform-foundations/02-resources/main.tf
index 9e9b1f8d..d67930d4 100644
--- a/data-solutions/data-platform-foundations/02-resources/main.tf
+++ b/data-solutions/data-platform-foundations/02-resources/main.tf
@@ -167,14 +167,13 @@ module "vpc-transformation" {
}
module "firewall" {
- source = "../../../modules/net-vpc-firewall"
- project_id = var.project_ids.transformation
- network = module.vpc-transformation.name
- admin_ranges_enabled = false
- admin_ranges = [""]
- http_source_ranges = []
- https_source_ranges = []
- ssh_source_ranges = []
+ source = "../../../modules/net-vpc-firewall"
+ project_id = var.project_ids.transformation
+ network = module.vpc-transformation.name
+ admin_ranges = []
+ http_source_ranges = []
+ https_source_ranges = []
+ ssh_source_ranges = []
custom_rules = {
iap-svc = {
diff --git a/data-solutions/gcs-to-bq-with-dataflow/main.tf b/data-solutions/gcs-to-bq-with-dataflow/main.tf
index c2e56084..f179f7d2 100644
--- a/data-solutions/gcs-to-bq-with-dataflow/main.tf
+++ b/data-solutions/gcs-to-bq-with-dataflow/main.tf
@@ -178,11 +178,10 @@ module "vpc" {
}
module "vpc-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = module.project-service.project_id
- network = module.vpc.name
- admin_ranges_enabled = true
- admin_ranges = [var.vpc_ip_cidr_range]
+ source = "../../modules/net-vpc-firewall"
+ project_id = module.project-service.project_id
+ network = module.vpc.name
+ admin_ranges = [var.vpc_ip_cidr_range]
}
module "nat" {
diff --git a/modules/net-vpc-firewall/README.md b/modules/net-vpc-firewall/README.md
index d4909fec..83f8f7cd 100644
--- a/modules/net-vpc-firewall/README.md
+++ b/modules/net-vpc-firewall/README.md
@@ -19,7 +19,6 @@ module "firewall" {
source = "./modules/net-vpc-firewall"
project_id = "my-project"
network = "my-network"
- admin_ranges_enabled = true
admin_ranges = ["10.0.0.0/8"]
}
# tftest:modules=1:resources=4
@@ -31,11 +30,10 @@ This is an example of how to define custom rules, with a sample rule allowing op
```hcl
module "firewall" {
- source = "./modules/net-vpc-firewall"
- project_id = "my-project"
- network = "my-network"
- admin_ranges_enabled = true
- admin_ranges = ["10.0.0.0/8"]
+ source = "./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."
@@ -53,6 +51,36 @@ module "firewall" {
# tftest:modules=1:resources=5
```
+### 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.
+
+```hcl
+module "firewall" {
+ source = "./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 = {}
+ }
+ }
+}
+# tftest:modules=1:resources=1
+```
+
## Variables
@@ -61,10 +89,10 @@ module "firewall" {
| network | Name of the network this set of firewall rules applies to. | string
| ✓ | |
| project_id | Project id of the project that holds the network. | string
| ✓ | |
| *admin_ranges* | IP CIDR ranges that have complete access to all subnets. | list(string)
| | []
|
-| *admin_ranges_enabled* | Enable admin ranges-based rules. | bool
| | false
|
| *custom_rules* | List of custom rule definitions (refer to variables file for syntax). | map(object({...}))
| | {}
|
| *http_source_ranges* | 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* | 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* | Names that can be used of valid values for the `ranges` field of `custom_rules` | map(list(string))
| | ...
|
| *ssh_source_ranges* | List of IP CIDR ranges for tag-based SSH rule, defaults to the IAP forwarders range. | list(string)
| | ["35.235.240.0/20"]
|
## Outputs
@@ -76,4 +104,5 @@ module "firewall" {
| custom_egress_deny_rules | Custom egress rules with allow blocks. | |
| custom_ingress_allow_rules | Custom ingress rules with allow blocks. | |
| custom_ingress_deny_rules | Custom ingress rules with deny blocks. | |
+| rules | All google_compute_firewall resources created. | |
diff --git a/modules/net-vpc-firewall/main.tf b/modules/net-vpc-firewall/main.tf
index 2e2a1825..c196e470 100644
--- a/modules/net-vpc-firewall/main.tf
+++ b/modules/net-vpc-firewall/main.tf
@@ -15,11 +15,17 @@
*/
locals {
- rules-allow = {
- for name, attrs in var.custom_rules : name => attrs if attrs.action == "allow"
- }
- rules-deny = {
- for name, attrs in var.custom_rules : name => attrs if attrs.action == "deny"
+ 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)
+ ])
+ })
}
}
@@ -28,7 +34,7 @@ locals {
###############################################################################
resource "google_compute_firewall" "allow-admins" {
- count = var.admin_ranges_enabled == true ? 1 : 0
+ 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
@@ -87,44 +93,9 @@ resource "google_compute_firewall" "allow-tag-https" {
# dynamic rules #
################################################################################
-resource "google_compute_firewall" "custom_allow" {
+resource "google_compute_firewall" "custom-rules" {
# provider = "google-beta"
- for_each = local.rules-allow
- name = each.key
- description = each.value.description
- direction = each.value.direction
- network = var.network
- project = var.project_id
- source_ranges = each.value.direction == "INGRESS" ? each.value.ranges : null
- destination_ranges = each.value.direction == "EGRESS" ? each.value.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
- 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)
-
- dynamic "log_config" {
- for_each = lookup(each.value.extra_attributes, "logging", null) != null ? [each.value.extra_attributes.logging] : []
- iterator = logging_config
- content {
- metadata = logging_config.value
- }
- }
-
- dynamic "allow" {
- for_each = each.value.rules
- iterator = rule
- content {
- protocol = rule.value.protocol
- ports = rule.value.ports
- }
- }
-}
-
-resource "google_compute_firewall" "custom_deny" {
- # provider = "google-beta"
- for_each = local.rules-deny
+ for_each = local.custom_rules
name = each.key
description = each.value.description
direction = each.value.direction
@@ -148,7 +119,18 @@ resource "google_compute_firewall" "custom_deny" {
}
dynamic "deny" {
- for_each = each.value.rules
+ for_each = each.value.action == "deny" ? each.value.rules : {}
+
+ iterator = rule
+ content {
+ protocol = rule.value.protocol
+ ports = rule.value.ports
+ }
+ }
+
+ dynamic "allow" {
+ 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 5a952f2a..5ddb56b1 100644
--- a/modules/net-vpc-firewall/outputs.tf
+++ b/modules/net-vpc-firewall/outputs.tf
@@ -18,39 +18,50 @@ output "admin_ranges" {
description = "Admin ranges data."
value = {
- enabled = var.admin_ranges_enabled
- ranges = var.admin_ranges_enabled ? join(",", var.admin_ranges) : ""
+ enabled = length(var.admin_ranges) > 0
+ ranges = join(",", var.admin_ranges)
}
}
output "custom_ingress_allow_rules" {
description = "Custom ingress rules with allow blocks."
value = [
- for rule in google_compute_firewall.custom_allow :
- rule.name if rule.direction == "INGRESS"
+ 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_deny :
- rule.name if rule.direction == "INGRESS"
+ for rule in google_compute_firewall.custom-rules :
+ rule.name if rule.direction == "INGRESS" && try(length(rule.deny), 0) > 0
]
}
output "custom_egress_allow_rules" {
description = "Custom egress rules with allow blocks."
value = [
- for rule in google_compute_firewall.custom_allow :
- rule.name if rule.direction == "EGRESS"
+ 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_deny :
- rule.name if rule.direction == "EGRESS"
+ for rule in google_compute_firewall.custom-rules :
+ rule.name if rule.direction == "EGRESS" && 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 }, {})
+ )
+}
diff --git a/modules/net-vpc-firewall/variables.tf b/modules/net-vpc-firewall/variables.tf
index ff8a5b60..94755d2e 100644
--- a/modules/net-vpc-firewall/variables.tf
+++ b/modules/net-vpc-firewall/variables.tf
@@ -14,46 +14,12 @@
* limitations under the License.
*/
-variable "network" {
- description = "Name of the network this set of firewall rules applies to."
- type = string
-}
-
-variable "project_id" {
- description = "Project id of the project that holds the network."
- type = string
-}
-
-variable "admin_ranges_enabled" {
- description = "Enable admin ranges-based rules."
- type = bool
- default = false
-}
-
variable "admin_ranges" {
description = "IP CIDR ranges that have complete access to all subnets."
type = list(string)
default = []
}
-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"]
-}
-
-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 "custom_rules" {
description = "List of custom rule definitions (refer to variables file for syntax)."
type = map(object({
@@ -72,3 +38,45 @@ variable "custom_rules" {
}))
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 "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 "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
+}
+
+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/networking/hub-and-spoke-peering/main.tf b/networking/hub-and-spoke-peering/main.tf
index a4800de4..6a6b3bfa 100644
--- a/networking/hub-and-spoke-peering/main.tf
+++ b/networking/hub-and-spoke-peering/main.tf
@@ -74,11 +74,10 @@ module "nat-hub" {
}
module "vpc-hub-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = var.project_id
- network = module.vpc-hub.name
- admin_ranges_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = var.project_id
+ network = module.vpc-hub.name
+ admin_ranges = values(var.ip_ranges)
}
################################################################################
@@ -100,11 +99,10 @@ 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_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = module.project.project_id
+ network = module.vpc-spoke-1.name
+ admin_ranges = values(var.ip_ranges)
}
module "nat-spoke-1" {
@@ -146,11 +144,10 @@ 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_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = module.project.project_id
+ network = module.vpc-spoke-2.name
+ admin_ranges = values(var.ip_ranges)
}
module "nat-spoke-2" {
diff --git a/networking/hub-and-spoke-vpn/main.tf b/networking/hub-and-spoke-vpn/main.tf
index f3a1dec4..e1d61bc3 100644
--- a/networking/hub-and-spoke-vpn/main.tf
+++ b/networking/hub-and-spoke-vpn/main.tf
@@ -48,11 +48,10 @@ module "vpc-hub" {
}
module "vpc-hub-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = var.project_id
- network = module.vpc-hub.name
- admin_ranges_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = var.project_id
+ network = module.vpc-hub.name
+ admin_ranges = values(var.ip_ranges)
}
module "vpn-hub-a" {
@@ -140,11 +139,10 @@ module "vpc-spoke-1" {
}
module "vpc-spoke-1-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = var.project_id
- network = module.vpc-spoke-1.name
- admin_ranges_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = var.project_id
+ network = module.vpc-spoke-1.name
+ admin_ranges = values(var.ip_ranges)
}
module "vpn-spoke-1" {
@@ -204,11 +202,10 @@ module "vpc-spoke-2" {
}
module "vpc-spoke-2-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = var.project_id
- network = module.vpc-spoke-2.name
- admin_ranges_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = var.project_id
+ network = module.vpc-spoke-2.name
+ admin_ranges = values(var.ip_ranges)
}
module "vpn-spoke-2" {
diff --git a/networking/ilb-next-hop/vpc-left.tf b/networking/ilb-next-hop/vpc-left.tf
index aedf3a4d..c5f8df22 100644
--- a/networking/ilb-next-hop/vpc-left.tf
+++ b/networking/ilb-next-hop/vpc-left.tf
@@ -38,12 +38,11 @@ module "vpc-left" {
}
module "firewall-left" {
- source = "../../modules/net-vpc-firewall"
- project_id = module.project.project_id
- network = module.vpc-left.name
- admin_ranges_enabled = true
- 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
+ admin_ranges = values(var.ip_ranges)
+ ssh_source_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22"]
}
module "nat-left" {
diff --git a/networking/ilb-next-hop/vpc-right.tf b/networking/ilb-next-hop/vpc-right.tf
index 661fd5d4..1bf590e9 100644
--- a/networking/ilb-next-hop/vpc-right.tf
+++ b/networking/ilb-next-hop/vpc-right.tf
@@ -52,12 +52,11 @@ module "vpc-right" {
}
module "firewall-right" {
- source = "../../modules/net-vpc-firewall"
- project_id = module.project.project_id
- network = module.vpc-right.name
- admin_ranges_enabled = true
- 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
+ admin_ranges = values(var.ip_ranges)
+ ssh_source_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22"]
}
module "nat-right" {
diff --git a/networking/onprem-google-access-dns/main.tf b/networking/onprem-google-access-dns/main.tf
index 9f39265d..caf66563 100644
--- a/networking/onprem-google-access-dns/main.tf
+++ b/networking/onprem-google-access-dns/main.tf
@@ -71,12 +71,11 @@ module "vpc" {
}
module "vpc-firewall" {
- source = "../../modules/net-vpc-firewall"
- project_id = var.project_id
- network = module.vpc.name
- admin_ranges_enabled = true
- 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
+ admin_ranges = values(var.ip_ranges)
+ ssh_source_ranges = var.ssh_source_ranges
}
module "vpn1" {
diff --git a/networking/shared-vpc-gke/main.tf b/networking/shared-vpc-gke/main.tf
index da404f04..fa11ebf4 100644
--- a/networking/shared-vpc-gke/main.tf
+++ b/networking/shared-vpc-gke/main.tf
@@ -130,11 +130,10 @@ 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_enabled = true
- admin_ranges = values(var.ip_ranges)
+ source = "../../modules/net-vpc-firewall"
+ project_id = module.project-host.project_id
+ network = module.vpc-shared.name
+ admin_ranges = values(var.ip_ranges)
}
module "nat" {