Add support for VPC internal ranges to modules/net-vpc (#3318)
* Add support for VPC internal ranges to modules/net-vpc * Fix linting * Fix variable order * Fix README * Sort outputs. * Fix validation for terraform < 1.13
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
* Copyright 2025 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,7 +70,8 @@ variable "dns_policy" {
|
||||
variable "factories_config" {
|
||||
description = "Paths to data files and folders that enable factory functionality."
|
||||
type = object({
|
||||
subnets_folder = optional(string)
|
||||
subnets_folder = optional(string)
|
||||
internal_ranges_folder = optional(string)
|
||||
})
|
||||
default = {}
|
||||
}
|
||||
@@ -87,6 +88,70 @@ variable "firewall_policy_enforcement_order" {
|
||||
}
|
||||
}
|
||||
|
||||
variable "internal_ranges" {
|
||||
description = "Internal range configuration for IPAM operations within the VPC network."
|
||||
type = list(object({
|
||||
name = string
|
||||
description = optional(string)
|
||||
ip_cidr_range = optional(string)
|
||||
labels = optional(map(string), {})
|
||||
usage = string
|
||||
peering = string
|
||||
prefix_length = optional(number)
|
||||
target_cidr_range = optional(list(string))
|
||||
exclude_cidr_ranges = optional(list(string))
|
||||
overlaps = optional(list(string))
|
||||
immutable = optional(bool)
|
||||
allocation_options = optional(object({
|
||||
allocation_strategy = optional(string)
|
||||
first_available_ranges_lookup_size = optional(number)
|
||||
}))
|
||||
migration = optional(object({
|
||||
source = string
|
||||
target = string
|
||||
}))
|
||||
}))
|
||||
default = []
|
||||
nullable = false
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for r in var.internal_ranges :
|
||||
contains(["FOR_VPC", "EXTERNAL_TO_VPC", "FOR_MIGRATION"], r.usage)
|
||||
])
|
||||
error_message = "Usage must be one of: FOR_VPC, EXTERNAL_TO_VPC, FOR_MIGRATION."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for r in var.internal_ranges :
|
||||
contains(["FOR_SELF", "FOR_PEER", "NOT_SHARED"], r.peering)
|
||||
])
|
||||
error_message = "Peering must be one of: FOR_SELF, FOR_PEER, NOT_SHARED."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for r in var.internal_ranges : (
|
||||
r.allocation_options == null ||
|
||||
try(r.allocation_options.allocation_strategy, null) == null ||
|
||||
contains(
|
||||
["RANDOM", "FIRST_AVAILABLE", "RANDOM_FIRST_N_AVAILABLE", "FIRST_SMALLEST_FITTING"],
|
||||
try(r.allocation_options.allocation_strategy, "")
|
||||
)
|
||||
)
|
||||
])
|
||||
error_message = "Allocation strategy must be one of: RANDOM, FIRST_AVAILABLE, RANDOM_FIRST_N_AVAILABLE, FIRST_SMALLEST_FITTING."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for r in var.internal_ranges :
|
||||
r.overlaps == null || alltrue([
|
||||
for overlap in coalesce(r.overlaps, []) :
|
||||
contains(["OVERLAP_ROUTE_RANGE", "OVERLAP_EXISTING_SUBNET_RANGE"], overlap)
|
||||
])
|
||||
])
|
||||
error_message = "Overlaps must contain only: OVERLAP_ROUTE_RANGE, OVERLAP_EXISTING_SUBNET_RANGE."
|
||||
}
|
||||
}
|
||||
|
||||
variable "ipv6_config" {
|
||||
description = "Optional IPv6 configuration for this network."
|
||||
type = object({
|
||||
@@ -263,11 +328,12 @@ variable "subnets" {
|
||||
description = "Subnet configuration."
|
||||
type = list(object({
|
||||
name = string
|
||||
ip_cidr_range = string
|
||||
ip_cidr_range = optional(string)
|
||||
region = string
|
||||
description = optional(string)
|
||||
enable_private_access = optional(bool, true)
|
||||
allow_subnet_cidr_routes_overlap = optional(bool, null)
|
||||
reserved_internal_range = optional(string)
|
||||
flow_logs_config = optional(object({
|
||||
aggregation_interval = optional(string)
|
||||
filter_expression = optional(string)
|
||||
@@ -282,9 +348,12 @@ variable "subnets" {
|
||||
# enable_private_access = optional(string)
|
||||
ipv6_only = optional(bool, false)
|
||||
}))
|
||||
ip_collection = optional(string, null)
|
||||
secondary_ip_ranges = optional(map(string))
|
||||
iam = optional(map(list(string)), {})
|
||||
ip_collection = optional(string, null)
|
||||
secondary_ip_ranges = optional(map(object({
|
||||
ip_cidr_range = optional(string)
|
||||
reserved_internal_range = optional(string)
|
||||
})))
|
||||
iam = optional(map(list(string)), {})
|
||||
iam_bindings = optional(map(object({
|
||||
role = string
|
||||
members = list(string)
|
||||
@@ -306,6 +375,33 @@ variable "subnets" {
|
||||
}))
|
||||
default = []
|
||||
nullable = false
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for s in var.subnets :
|
||||
(
|
||||
length([
|
||||
for field in [s.ip_cidr_range, s.reserved_internal_range, s.ip_collection] :
|
||||
field if field != null
|
||||
]) == 1
|
||||
) || (
|
||||
length([
|
||||
for field in [s.ip_cidr_range, s.reserved_internal_range, s.ip_collection] :
|
||||
field if field != null
|
||||
]) == 0 && try(s.ipv6.ipv6_only, false) == true
|
||||
)
|
||||
])
|
||||
error_message = "Each subnet must specify exactly one of ip_cidr_range, reserved_internal_range, or ip_collection, or all three can be null for IPv6-only subnets (ipv6.ipv6_only = true)."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for s in var.subnets :
|
||||
s.secondary_ip_ranges == null || alltrue([
|
||||
for range_name, range_config in coalesce(s.secondary_ip_ranges, {}) :
|
||||
(range_config.ip_cidr_range != null) != (range_config.reserved_internal_range != null)
|
||||
])
|
||||
])
|
||||
error_message = "Each secondary IP range must specify either ip_cidr_range or reserved_internal_range, but not both."
|
||||
}
|
||||
}
|
||||
|
||||
variable "subnets_private_nat" {
|
||||
|
||||
Reference in New Issue
Block a user