Add support for context to net-lb-int net-vpc-firewall and net-vpc module (#3419)

* net-lb-int

* net-vpc-firewall

* net-vpc

* net-vpc
This commit is contained in:
Ludovico Magnocavallo
2025-10-16 07:54:14 +02:00
committed by GitHub
parent ecdc248f3f
commit 7c920d7d35
25 changed files with 1044 additions and 221 deletions

View File

@@ -269,13 +269,14 @@ module "firewall" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [network](variables.tf#L111) | Name of the network this set of firewall rules applies to. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L116) | Project id of the project that holds the network. | <code>string</code> | ✓ | |
| [default_rules_config](variables.tf#L17) | Optionally created convenience rules. Set the 'disabled' attribute to true, or individual rule attributes to empty lists to disable. | <code title="object&#40;&#123;&#10; admin_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; http_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#93;&#10; &#41;&#10; http_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#34;http-server&#34;&#93;&#41;&#10; https_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#93;&#10; &#41;&#10; https_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#34;https-server&#34;&#93;&#41;&#10; ssh_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#34;35.235.240.0&#47;20&#34;&#93;&#41;&#10; ssh_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#34;ssh&#34;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [egress_rules](variables.tf#L37) | List of egress rule definitions, default to deny action. Null destination ranges will be replaced with 0/0. | <code title="map&#40;object&#40;&#123;&#10; deny &#61; optional&#40;bool, true&#41;&#10; description &#61; optional&#40;string&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;object&#40;&#123;&#10; include_metadata &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;&#10; priority &#61; optional&#40;number, 1000&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; targets &#61; optional&#40;list&#40;string&#41;&#41;&#10; use_service_accounts &#61; optional&#40;bool, false&#41;&#10; rules &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; string&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123; protocol &#61; &#34;all&#34; &#125;&#93;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L60) | Paths to data files and folders that enable factory functionality. | <code title="object&#40;&#123;&#10; cidr_tpl_file &#61; optional&#40;string&#41;&#10; rules_folder &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_rules](variables.tf#L70) | List of ingress rule definitions, default to allow action. Null source ranges will be replaced with 0/0. | <code title="map&#40;object&#40;&#123;&#10; deny &#61; optional&#40;bool, false&#41;&#10; description &#61; optional&#40;string&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41; &#35; empty list is needed as default to allow deletion after initial creation with a value. See https:&#47;&#47;github.com&#47;hashicorp&#47;terraform-provider-google&#47;issues&#47;14270&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;object&#40;&#123;&#10; include_metadata &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;&#10; priority &#61; optional&#40;number, 1000&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; sources &#61; optional&#40;list&#40;string&#41;&#41;&#10; targets &#61; optional&#40;list&#40;string&#41;&#41;&#10; use_service_accounts &#61; optional&#40;bool, false&#41;&#10; rules &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; string&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123; protocol &#61; &#34;all&#34; &#125;&#93;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [named_ranges](variables.tf#L94) | Define mapping of names to ranges that can be used in custom rules. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; any &#61; &#91;&#34;0.0.0.0&#47;0&#34;&#93;&#10; dns-forwarders &#61; &#91;&#34;35.199.192.0&#47;19&#34;&#93;&#10; health-checkers &#61; &#91;&#10; &#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#10; &#93;&#10; iap-forwarders &#61; &#91;&#34;35.235.240.0&#47;20&#34;&#93;&#10; private-googleapis &#61; &#91;&#34;199.36.153.8&#47;30&#34;&#93;&#10; restricted-googleapis &#61; &#91;&#34;199.36.153.4&#47;30&#34;&#93;&#10; rfc1918 &#61; &#91;&#34;10.0.0.0&#47;8&#34;, &#34;172.16.0.0&#47;12&#34;, &#34;192.168.0.0&#47;16&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [network](variables.tf#L123) | Name of the network this set of firewall rules applies to. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L128) | Project id of the project that holds the network. | <code>string</code> | ✓ | |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; cidr_ranges &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; networks &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [default_rules_config](variables.tf#L29) | Optionally created convenience rules. Set the 'disabled' attribute to true, or individual rule attributes to empty lists to disable. | <code title="object&#40;&#123;&#10; admin_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; http_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#93;&#10; &#41;&#10; http_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#34;http-server&#34;&#93;&#41;&#10; https_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#10; &#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#93;&#10; &#41;&#10; https_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#34;https-server&#34;&#93;&#41;&#10; ssh_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#34;35.235.240.0&#47;20&#34;&#93;&#41;&#10; ssh_tags &#61; optional&#40;list&#40;string&#41;, &#91;&#34;ssh&#34;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [egress_rules](variables.tf#L49) | List of egress rule definitions, default to deny action. Null destination ranges will be replaced with 0/0. | <code title="map&#40;object&#40;&#123;&#10; deny &#61; optional&#40;bool, true&#41;&#10; description &#61; optional&#40;string&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;object&#40;&#123;&#10; include_metadata &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;&#10; priority &#61; optional&#40;number, 1000&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; targets &#61; optional&#40;list&#40;string&#41;&#41;&#10; use_service_accounts &#61; optional&#40;bool, false&#41;&#10; rules &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; string&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123; protocol &#61; &#34;all&#34; &#125;&#93;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L72) | Paths to data files and folders that enable factory functionality. | <code title="object&#40;&#123;&#10; cidr_tpl_file &#61; optional&#40;string&#41;&#10; rules_folder &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_rules](variables.tf#L82) | List of ingress rule definitions, default to allow action. Null source ranges will be replaced with 0/0. | <code title="map&#40;object&#40;&#123;&#10; deny &#61; optional&#40;bool, false&#41;&#10; description &#61; optional&#40;string&#41;&#10; destination_ranges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41; &#35; empty list is needed as default to allow deletion after initial creation with a value. See https:&#47;&#47;github.com&#47;hashicorp&#47;terraform-provider-google&#47;issues&#47;14270&#10; disabled &#61; optional&#40;bool, false&#41;&#10; enable_logging &#61; optional&#40;object&#40;&#123;&#10; include_metadata &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;&#10; priority &#61; optional&#40;number, 1000&#41;&#10; source_ranges &#61; optional&#40;list&#40;string&#41;&#41;&#10; sources &#61; optional&#40;list&#40;string&#41;&#41;&#10; targets &#61; optional&#40;list&#40;string&#41;&#41;&#10; use_service_accounts &#61; optional&#40;bool, false&#41;&#10; rules &#61; optional&#40;list&#40;object&#40;&#123;&#10; protocol &#61; string&#10; ports &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#91;&#123; protocol &#61; &#34;all&#34; &#125;&#93;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [named_ranges](variables.tf#L106) | Define mapping of names to ranges that can be used in custom rules. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; any &#61; &#91;&#34;0.0.0.0&#47;0&#34;&#93;&#10; dns-forwarders &#61; &#91;&#34;35.199.192.0&#47;19&#34;&#93;&#10; health-checkers &#61; &#91;&#10; &#34;35.191.0.0&#47;16&#34;, &#34;130.211.0.0&#47;22&#34;, &#34;209.85.152.0&#47;22&#34;, &#34;209.85.204.0&#47;22&#34;&#10; &#93;&#10; iap-forwarders &#61; &#91;&#34;35.235.240.0&#47;20&#34;&#93;&#10; private-googleapis &#61; &#91;&#34;199.36.153.8&#47;30&#34;&#93;&#10; restricted-googleapis &#61; &#91;&#34;199.36.153.4&#47;30&#34;&#93;&#10; rfc1918 &#61; &#91;&#34;10.0.0.0&#47;8&#34;, &#34;172.16.0.0&#47;12&#34;, &#34;192.168.0.0&#47;16&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> |
## Outputs

View File

@@ -25,23 +25,27 @@ locals {
}
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
count = length(local.default_rules.admin_ranges) > 0 ? 1 : 0
project = local.project_id
network = local.network
name = "${local.network_name}-ingress-admins"
description = "Access from the admin subnet to all subnets."
source_ranges = [
for r in local.default_rules.admin_ranges : lookup(local.ctx.cidr_ranges, r, r)
]
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
count = length(local.default_rules.http_ranges) > 0 ? 1 : 0
project = local.project_id
network = local.network
name = "${local.network_name}-ingress-tag-http"
description = "Allow http to machines with matching tags."
source_ranges = [
for r in local.default_rules.http_ranges : lookup(local.ctx.cidr_ranges, r, r)
]
target_tags = local.default_rules.http_tags
allow {
protocol = "tcp"
ports = ["80"]
@@ -49,13 +53,15 @@ resource "google_compute_firewall" "allow-tag-http" {
}
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
count = length(local.default_rules.https_ranges) > 0 ? 1 : 0
project = local.project_id
network = local.network
name = "${local.network_name}-ingress-tag-https"
description = "Allow http to machines with matching tags."
source_ranges = [
for r in local.default_rules.https_ranges : lookup(local.ctx.cidr_ranges, r, r)
]
target_tags = local.default_rules.https_tags
allow {
protocol = "tcp"
ports = ["443"]
@@ -63,13 +69,15 @@ resource "google_compute_firewall" "allow-tag-https" {
}
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
count = length(local.default_rules.ssh_ranges) > 0 ? 1 : 0
project = local.project_id
network = local.network
name = "${local.network_name}-ingress-tag-ssh"
description = "Allow SSH to machines with matching tags."
source_ranges = [
for r in local.default_rules.ssh_ranges : lookup(local.ctx.cidr_ranges, r, r)
]
target_tags = local.default_rules.ssh_tags
allow {
protocol = "tcp"
ports = ["22"]

View File

@@ -66,6 +66,15 @@ locals {
for name, rule in merge(var.ingress_rules) :
name => merge(rule, { direction = "INGRESS" })
}
ctx = {
for k, v in var.context : k => {
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
}
}
ctx_p = "$"
network = lookup(local.ctx.networks, var.network, var.network)
network_name = reverse(split("/", local.network))[0]
project_id = lookup(local.ctx.project_ids, var.project_id, var.project_id)
# convert rules data to resource format and replace range template variables
rules = {
for name, rule in local._rules :
@@ -94,30 +103,32 @@ locals {
resource "google_compute_firewall" "custom-rules" {
for_each = local.rules
project = var.project_id
network = var.network
project = local.project_id
network = local.network
name = each.key
description = each.value.description
direction = each.value.direction
source_ranges = (
each.value.direction == "INGRESS"
each.value.source_ranges == null
? (
each.value.source_ranges == null && each.value.sources == null
each.value.direction == "INGRESS" && each.value.sources == null
? ["0.0.0.0/0"]
: each.value.source_ranges
: null
)
#for egress, we will include the source_ranges when provided. Previously, null was forced
: each.value.source_ranges
: [
for r in each.value.source_ranges : lookup(local.ctx.cidr_ranges, r, r)
]
)
destination_ranges = (
each.value.direction == "EGRESS"
each.value.destination_ranges == null
? (
each.value.destination_ranges == null
each.value.direction == "EGRESS"
? ["0.0.0.0/0"]
: each.value.destination_ranges
: null
)
#for ingress, we will include the destination_ranges when provided. Previously, null was forced
: each.value.destination_ranges
: [
for r in each.value.destination_ranges : lookup(local.ctx.cidr_ranges, r, r)
]
)
source_tags = (
each.value.use_service_accounts || each.value.direction == "EGRESS"
@@ -126,14 +137,19 @@ resource "google_compute_firewall" "custom-rules" {
)
source_service_accounts = (
each.value.use_service_accounts && each.value.direction == "INGRESS"
? each.value.sources
? (each.value.sources == null ? null : [
for s in each.value.sources : lookup(local.ctx.iam_principals, s, s)
])
: null
)
target_tags = (
each.value.use_service_accounts ? null : each.value.targets
!each.value.use_service_accounts ? each.value.targets : null
)
target_service_accounts = (
each.value.use_service_accounts ? each.value.targets : null
!each.value.use_service_accounts ? null : (
each.value.targets == null ? null : [
for s in each.value.targets : lookup(local.ctx.iam_principals, s, s)
])
)
disabled = each.value.disabled == true
priority = each.value.priority

View File

@@ -14,6 +14,18 @@
* limitations under the License.
*/
variable "context" {
description = "Context-specific interpolations."
type = object({
cidr_ranges = optional(map(string), {})
iam_principals = optional(map(string), {})
networks = optional(map(string), {})
project_ids = optional(map(string), {})
})
default = {}
nullable = false
}
variable "default_rules_config" {
description = "Optionally created convenience rules. Set the 'disabled' attribute to true, or individual rule attributes to empty lists to disable."
type = object({