diff --git a/README.md b/README.md
index 43b5818..20be12e 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ No modules.
| Name | Type |
|------|------|
| [google_compute_network.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource |
+| [google_compute_subnetwork.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource |
## Inputs
@@ -47,6 +48,7 @@ No modules.
| [network\_firewall\_policy\_enforcement\_order](#input\_network\_firewall\_policy\_enforcement\_order) | (Optional) Set the order that Firewall Rules and Firewall Policies are evaluated. Default value is AFTER\_CLASSIC\_FIREWALL. Possible values are: BEFORE\_CLASSIC\_FIREWALL, AFTER\_CLASSIC\_FIREWALL. | `string` | `null` | no |
| [project](#input\_project) | (Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used. | `string` | `null` | no |
| [routing\_mode](#input\_routing\_mode) | (Optional) The network-wide routing mode to use. If set to REGIONAL, this network's cloud routers will only advertise routes with subnetworks of this network in the same region as the router. If set to GLOBAL, this network's cloud routers will advertise routes with all subnetworks of this network, across regions. Possible values are: REGIONAL, GLOBAL. | `string` | `"GLOBAL"` | no |
+| [subnets](#input\_subnets) | (Optional) List of subnetworks. Each element must contain the following attributes:
- name: Name of the subnetwork.
- ip\_cidr\_range: The range of internal addresses that are owned by this subnetwork.
- network: The network this subnet belongs to. If not provided, the network will be created in auto subnet mode.
- description: (Optional) An optional description of this resource. The resource must be recreated to modify this field.
- purpose: (Optional) The purpose of the resource. Possible values are: INTERNAL\_HTTPS\_LOAD\_BALANCER, INTERNAL\_TCP\_UDP\_LOAD\_BALANCER, PRIVATE, PUBLIC.
- role: (Optional) The role of subnetwork. Possible values are: ACTIVE, INACTIVE.
- secondary\_ip\_range: (Optional) List of secondary ip ranges to be used in this subnetwork.
- private\_ipv6\_google\_access: (Optional) The private ipv6 google access type. Possible values are: OFF, ON.
- private\_ip\_google\_access: (Optional) The private ip google access type. Default is false.
- region: The region this subnetwork belongs to.
- log\_config: (Optional) List of log config for a subnetwork. Each element must contain the following attributes:
- aggregation\_interval: (Optional) The aggregation interval for flow logs. Default is 5 seconds.
- flow\_sampling: (Optional) The flow sampling for flow logs. Default is 0.5.
- metadata: (Optional) The metadata for flow logs. Possible values are: INCLUDE\_ALL\_METADATA, EXCLUDE\_ALL\_METADATA, CUSTOM\_METADATA.
- metadata\_fields: (Optional) The metadata fields for flow logs. Required if metadata is CUSTOM\_METADATA.
- filter\_expr: (Optional) The filter expression for flow logs.
- stack\_type: (Optional) The stack type of the subnetwork. Possible values are: IPV4\_ONLY, IPV4\_IPV6.
- ipv6\_access\_type: (Optional) The ipv6 access type of the subnetwork. Possible values are: OFF, ON.
- external\_ipv6\_prefix: (Optional) The external ipv6 prefix of the subnetwork.
- allow\_subnet\_cidr\_routes\_overlap: (Optional) Whether to allow subnet cidr routes overlap. Default is false. |
map(object({| `{}` | no | ## Outputs @@ -56,4 +58,5 @@ No modules. | [id](#output\_id) | an identifier for the resource with format projects/{{project}}/global/networks/{{name}} | | [numeric\_id](#output\_numeric\_id) | The unique identifier for the resource. This identifier is defined by the server. | | [self\_link](#output\_self\_link) | The URI of the created resource. | +| [subnet\_ids](#output\_subnet\_ids) | n/a | \ No newline at end of file diff --git a/main.tf b/main.tf index c397dac..4066d68 100644 --- a/main.tf +++ b/main.tf @@ -11,5 +11,46 @@ resource "google_compute_network" "this" { internal_ipv6_range = var.internal_ipv6_range network_firewall_policy_enforcement_order = var.network_firewall_policy_enforcement_order delete_default_routes_on_create = var.delete_default_routes_on_create +} + + +resource "google_compute_subnetwork" "this" { + for_each = var.subnets + + name = each.value.subnet_name + ip_cidr_range = each.value.ip_cidr_range + network = var.create ? google_compute_network.this[0].id : each.value.network + project = var.project + description = try(each.value, "description", null) + purpose = try(each.value, "purpose", null) + role = try(each.value, "role", null) + dynamic "secondary_ip_range" { + for_each = each.value.subnet_secondary_ip_ranges != null ? each.value.subnet_secondary_ip_ranges : [] + + content { + range_name = secondary_ip_range.value.range_name + ip_cidr_range = secondary_ip_range.value.ip_cidr_range + } + } + private_ipv6_google_access = try(each.value, "private_ipv6_google_access", null) + private_ip_google_access = try(each.value, "private_ip_google_access", "false") + region = each.value.region + + + dynamic "log_config" { + for_each = each.value.log_config != null ? each.value.log_config : [] + content { + aggregation_interval = try(log_config.value.aggregation_interval, null) + flow_sampling = try(log_config.value.flow_sampling, null) + metadata = try(log_config.value.metadata, null) + metadata_fields = log_config.value.metadata == "CUSTOM_METADATA" ? try(log_config.value.metadata_fields, null) : null + filter_expr = try(log_config.value.filter_expr, null) + + } + } + stack_type = try(each.value, "stack_type", null) + ipv6_access_type = try(each.value, "ipv6_access_type", null) + external_ipv6_prefix = try(each.value, "external_ipv6_prefix", null) + # allow_subnet_cidr_routes_overlap = try(each.value, "allow_subnet_cidr_routes_overlap", false) } diff --git a/outputs.tf b/outputs.tf index 7a3ecc9..d1138c4 100644 --- a/outputs.tf +++ b/outputs.tf @@ -18,3 +18,15 @@ output "self_link" { value = try(google_compute_network.this[0].self_link, null) } + +### Subnet Outputs ### + +output "subnet_ids" { + value = { + for subnet_key, subnet in google_compute_subnetwork.this : + subnet.name => { + id = subnet.id + gateway_address = subnet.gateway_address + } + } +} diff --git a/variables.tf b/variables.tf index 5aab558..b58b24a 100644 --- a/variables.tf +++ b/variables.tf @@ -63,3 +63,55 @@ variable "delete_default_routes_on_create" { description = "(Optional) If set to true, default routes (0.0.0.0/0) will be deleted immediately after network creation. Defaults to false." default = true } + +#### Subnets #### + +variable "subnets" { + type = map(object({ + name = string + ip_cidr_range = string + network = optional(string) + description = optional(string) + purpose = optional(string) + role = optional(string) + secondary_ip_range = list(map(string)) + private_ipv6_google_access = optional(string) + private_ip_google_access = optional(bool) + region = string + log_config = optional(list(object({ + aggregation_interval = optional(string) + flow_sampling = optional(string) + metadata = optional(string) + metadata_fields = optional(list(string)) + filter_expr = optional(string) + }))) + stack_type = optional(string) + ipv6_access_type = optional(string) + external_ipv6_prefix = optional(string) + allow_subnet_cidr_routes_overlap = optional(bool) + })) + description = <<_EOT + (Optional) List of subnetworks. Each element must contain the following attributes: + - name: Name of the subnetwork. + - ip_cidr_range: The range of internal addresses that are owned by this subnetwork. + - network: The network this subnet belongs to. If not provided, the network will be created in auto subnet mode. + - description: (Optional) An optional description of this resource. The resource must be recreated to modify this field. + - purpose: (Optional) The purpose of the resource. Possible values are: INTERNAL_HTTPS_LOAD_BALANCER, INTERNAL_TCP_UDP_LOAD_BALANCER, PRIVATE, PUBLIC. + - role: (Optional) The role of subnetwork. Possible values are: ACTIVE, INACTIVE. + - secondary_ip_range: (Optional) List of secondary ip ranges to be used in this subnetwork. + - private_ipv6_google_access: (Optional) The private ipv6 google access type. Possible values are: OFF, ON. + - private_ip_google_access: (Optional) The private ip google access type. Default is false. + - region: The region this subnetwork belongs to. + - log_config: (Optional) List of log config for a subnetwork. Each element must contain the following attributes: + - aggregation_interval: (Optional) The aggregation interval for flow logs. Default is 5 seconds. + - flow_sampling: (Optional) The flow sampling for flow logs. Default is 0.5. + - metadata: (Optional) The metadata for flow logs. Possible values are: INCLUDE_ALL_METADATA, EXCLUDE_ALL_METADATA, CUSTOM_METADATA. + - metadata_fields: (Optional) The metadata fields for flow logs. Required if metadata is CUSTOM_METADATA. + - filter_expr: (Optional) The filter expression for flow logs. + - stack_type: (Optional) The stack type of the subnetwork. Possible values are: IPV4_ONLY, IPV4_IPV6. + - ipv6_access_type: (Optional) The ipv6 access type of the subnetwork. Possible values are: OFF, ON. + - external_ipv6_prefix: (Optional) The external ipv6 prefix of the subnetwork. + - allow_subnet_cidr_routes_overlap: (Optional) Whether to allow subnet cidr routes overlap. Default is false. + _EOT + default = {} +}
name = string
ip_cidr_range = string
network = optional(string)
description = optional(string)
purpose = optional(string)
role = optional(string)
secondary_ip_range = list(map(string))
private_ipv6_google_access = optional(string)
private_ip_google_access = optional(bool)
region = string
log_config = optional(list(object({
aggregation_interval = optional(string)
flow_sampling = optional(string)
metadata = optional(string)
metadata_fields = optional(list(string))
filter_expr = optional(string)
})))
stack_type = optional(string)
ipv6_access_type = optional(string)
external_ipv6_prefix = optional(string)
allow_subnet_cidr_routes_overlap = optional(bool)
}))