From 9ace223f245abc12b5d380f837d76e180571374e Mon Sep 17 00:00:00 2001 From: Horia Gunica Date: Wed, 2 Oct 2024 19:33:45 +0300 Subject: [PATCH 1/6] Added log_config block support for subnetworks --- modules/vpc/main.tf | 13 ++++++++++++- modules/vpc/variables.tf | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/vpc/main.tf b/modules/vpc/main.tf index b8d94fe..8fb1bfc 100644 --- a/modules/vpc/main.tf +++ b/modules/vpc/main.tf @@ -51,6 +51,17 @@ resource "google_compute_subnetwork" "this" { project = var.project_id stack_type = each.value.stack_type ipv6_access_type = each.value.ipv6_access_type + dynamic "log_config" { + for_each = each.value.log_config != null ? [each.value.log_config] : [] + + content { + aggregation_interval = log_config.value.aggregation_interval + flow_sampling = log_config.value.flow_sampling + metadata = log_config.value.metadata + metadata_fields = log_config.value.metadata_fields + filter_expr = log_config.value.filter_expr + } + } } resource "google_compute_firewall" "this" { @@ -80,4 +91,4 @@ resource "google_compute_firewall" "this" { metadata = log_config.value } } -} \ No newline at end of file +} diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf index 43a62a9..ffe922e 100644 --- a/modules/vpc/variables.tf +++ b/modules/vpc/variables.tf @@ -50,6 +50,13 @@ variable "subnetworks" { region = string stack_type = optional(string) ipv6_access_type = optional(string) + log_config = optional(object({ + aggregation_interval = optional(string) + flow_sampling = optional(string) + metadata = optional(string) + metadata_fields = optional(list(string)) + filter_expr = optional(string) + })) })) } From a40a067b0e4e435703c3d6b1e6cda2f5305c98bc Mon Sep 17 00:00:00 2001 From: Horia Gunica Date: Wed, 2 Oct 2024 19:40:02 +0300 Subject: [PATCH 2/6] Updated docs --- modules/vpc/README.md | 2 +- modules/vpc/variables.tf | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/vpc/README.md b/modules/vpc/README.md index 01dc5df..66ddd2f 100644 --- a/modules/vpc/README.md +++ b/modules/vpc/README.md @@ -137,7 +137,7 @@ No modules. | [name](#input\_name) | The name of the created or already existing VPC Network. | `string` | n/a | yes | | [project\_id](#input\_project\_id) | Project in which to create or look for VPCs and subnets | `string` | `null` | no | | [routing\_mode](#input\_routing\_mode) | Type of network-wide routing mode to use. Possible types are: REGIONAL and GLOBAL.
REGIONAL routing mode will set the cloud routers to only advertise subnetworks within the same region as the router.
GLOBAL routing mode will set the cloud routers to advertise all the subnetworks that belong to this network. | `string` | `"REGIONAL"` | no | -| [subnetworks](#input\_subnetworks) | A map containing subnetworks configuration. Subnets can belong to different regions.
List of available attributes of each subnetwork entry:
- `name` : Name of the subnetwork.
- `create_subnetwork` : Boolean value to control the creation or reading of the subnetwork. If set to `true` - this will create the subnetwork. If set to `false` - this will read a subnet with provided information.
- `ip_cidr_range` : A string that contains the subnetwork to create. Only IPv4 format is supported.
- `region` : Region where to configure or import the subnet.
- `stack_type` : IP stack type. IPV4\_ONLY (default) and IPV4\_IPV6 are supported.
- `ipv6_access_type` : The access type of IPv6 address. It's immutable and can only be specified during creation or the first time the subnet is updated into IPV4\_IPV6 dual stack. Possible values are: EXTERNAL, INTERNAL.

Example:
subnetworks = {
my-sub = {
name = "my-sub"
create_subnetwork = true
ip_cidr_range = "192.168.0.0/24"
region = "us-east1"
}
}
|
map(object({
name = string
create_subnetwork = optional(bool, true)
ip_cidr_range = string
region = string
stack_type = optional(string)
ipv6_access_type = optional(string)
}))
| `{}` | no | +| [subnetworks](#input\_subnetworks) | A map containing subnetworks configuration. Subnets can belong to different regions.
List of available attributes of each subnetwork entry:
- `name` : Name of the subnetwork.
- `create_subnetwork` : Boolean value to control the creation or reading of the subnetwork. If set to `true` - this will create the subnetwork. If set to `false` - this will read a subnet with provided information.
- `ip_cidr_range` : A string that contains the subnetwork to create. Only IPv4 format is supported.
- `region` : Region where to configure or import the subnet.
- `stack_type` : IP stack type. IPV4\_ONLY (default) and IPV4\_IPV6 are supported.
- `ipv6_access_type` : The access type of IPv6 address. It's immutable and can only be specified during creation or the first time the subnet is updated into IPV4\_IPV6 dual stack. Possible values are: EXTERNAL, INTERNAL.
- `log_config` : (Optional) A map containing the logging configuration for the subnetwork.
- `aggregation_interval` : (Optional) The interval at which logs are aggregated for the subnetwork. Possible values are: `INTERVAL_5_SEC`, `INTERVAL_30_SEC`, `INTERVAL_1_MIN`, `INTERVAL_5_MIN`, `INTERVAL_10_MIN`, `INTERVAL_15_MIN`.
- `flow_sampling` : (Optional) The value of the field must be in [0, 1]. Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported.
- `metadata` : (Optional) Configures whether metadata fields should be added to the reported VPC flow logs. Default value is `INCLUDE_ALL_METADATA`. Possible values are: `EXCLUDE_ALL_METADATA`, `INCLUDE_ALL_METADATA`, `CUSTOM_METADATA`.
- `metadata_fields` : (Optional) List of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and `metadata` is set to `CUSTOM_METADATA`.
- `filter_expr` : (Optional) Export filter used to define which VPC flow logs should be logged, as as CEL expression.

Example:
subnetworks = {
my-sub = {
name = "my-sub"
create_subnetwork = true
ip_cidr_range = "192.168.0.0/24"
region = "us-east1"
}
}
|
map(object({
name = string
create_subnetwork = optional(bool, true)
ip_cidr_range = string
region = string
stack_type = optional(string)
ipv6_access_type = optional(string)
log_config = optional(object({
aggregation_interval = optional(string)
flow_sampling = optional(string)
metadata = optional(string)
metadata_fields = optional(list(string))
filter_expr = optional(string)
}))
}))
| `{}` | no | ### Outputs diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf index ffe922e..9e6ccd1 100644 --- a/modules/vpc/variables.tf +++ b/modules/vpc/variables.tf @@ -29,6 +29,12 @@ variable "subnetworks" { - `region` : Region where to configure or import the subnet. - `stack_type` : IP stack type. IPV4_ONLY (default) and IPV4_IPV6 are supported. - `ipv6_access_type` : The access type of IPv6 address. It's immutable and can only be specified during creation or the first time the subnet is updated into IPV4_IPV6 dual stack. Possible values are: EXTERNAL, INTERNAL. + - `log_config` : (Optional) A map containing the logging configuration for the subnetwork. + - `aggregation_interval` : (Optional) The interval at which logs are aggregated for the subnetwork. Possible values are: `INTERVAL_5_SEC`, `INTERVAL_30_SEC`, `INTERVAL_1_MIN`, `INTERVAL_5_MIN`, `INTERVAL_10_MIN`, `INTERVAL_15_MIN`. + - `flow_sampling` : (Optional) The value of the field must be in [0, 1]. Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. + - `metadata` : (Optional) Configures whether metadata fields should be added to the reported VPC flow logs. Default value is `INCLUDE_ALL_METADATA`. Possible values are: `EXCLUDE_ALL_METADATA`, `INCLUDE_ALL_METADATA`, `CUSTOM_METADATA`. + - `metadata_fields` : (Optional) List of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and `metadata` is set to `CUSTOM_METADATA`. + - `filter_expr` : (Optional) Export filter used to define which VPC flow logs should be logged, as as CEL expression. Example: ``` From c4be26312901f37d29315c2abbd072251fdc914c Mon Sep 17 00:00:00 2001 From: Horia Gunica <43091730+horiagunica@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:35:36 +0300 Subject: [PATCH 3/6] Update modules/vpc/main.tf Co-authored-by: michalbil <92343355+michalbil@users.noreply.github.com> --- modules/vpc/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/vpc/main.tf b/modules/vpc/main.tf index 8fb1bfc..67b9efe 100644 --- a/modules/vpc/main.tf +++ b/modules/vpc/main.tf @@ -51,6 +51,7 @@ resource "google_compute_subnetwork" "this" { project = var.project_id stack_type = each.value.stack_type ipv6_access_type = each.value.ipv6_access_type + dynamic "log_config" { for_each = each.value.log_config != null ? [each.value.log_config] : [] From 45a5a22e90da044c337c39917bdc9d76ec9f19a4 Mon Sep 17 00:00:00 2001 From: Horia Gunica Date: Tue, 8 Oct 2024 17:24:32 +0300 Subject: [PATCH 4/6] Added validation logic for log_config section --- modules/vpc/variables.tf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf index 9e6ccd1..243ff44 100644 --- a/modules/vpc/variables.tf +++ b/modules/vpc/variables.tf @@ -64,6 +64,16 @@ variable "subnetworks" { filter_expr = optional(string) })) })) + validation { + condition = alltrue([ + for subnet in var.subnetworks : + subnet.log_config != null ? ( + (subnet.log_config.aggregation_interval != null && can(regex("^INTERVAL_(5_SEC|30_SEC|1_MIN|5_MIN|10_MIN|15_MIN)$", subnet.log_config.aggregation_interval)) ? true : false) && + (subnet.log_config.metadata != null && can(regex("^(EXCLUDE_ALL_METADATA|INCLUDE_ALL_METADATA|CUSTOM_METADATA)$", subnet.log_config.metadata)) ? true : false) + ) : true + ]) + error_message = "If log_config is specified, aggregation_interval must be one of INTERVAL_5_SEC, INTERVAL_30_SEC, INTERVAL_1_MIN, INTERVAL_5_MIN, INTERVAL_10_MIN, INTERVAL_15_MIN, and metadata must be one of EXCLUDE_ALL_METADATA, INCLUDE_ALL_METADATA, or CUSTOM_METADATA." + } } variable "firewall_rules" { From bd60bb26266de0c72a158382ad470d5d0cdce087 Mon Sep 17 00:00:00 2001 From: Horia Gunica Date: Tue, 8 Oct 2024 17:46:50 +0300 Subject: [PATCH 5/6] Pre-commit hook fmt update --- modules/vpc/variables.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf index 243ff44..72381ee 100644 --- a/modules/vpc/variables.tf +++ b/modules/vpc/variables.tf @@ -66,11 +66,11 @@ variable "subnetworks" { })) validation { condition = alltrue([ - for subnet in var.subnetworks : - subnet.log_config != null ? ( - (subnet.log_config.aggregation_interval != null && can(regex("^INTERVAL_(5_SEC|30_SEC|1_MIN|5_MIN|10_MIN|15_MIN)$", subnet.log_config.aggregation_interval)) ? true : false) && - (subnet.log_config.metadata != null && can(regex("^(EXCLUDE_ALL_METADATA|INCLUDE_ALL_METADATA|CUSTOM_METADATA)$", subnet.log_config.metadata)) ? true : false) - ) : true + for subnet in var.subnetworks : + subnet.log_config != null ? ( + (subnet.log_config.aggregation_interval != null && can(regex("^INTERVAL_(5_SEC|30_SEC|1_MIN|5_MIN|10_MIN|15_MIN)$", subnet.log_config.aggregation_interval)) ? true : false) && + (subnet.log_config.metadata != null && can(regex("^(EXCLUDE_ALL_METADATA|INCLUDE_ALL_METADATA|CUSTOM_METADATA)$", subnet.log_config.metadata)) ? true : false) + ) : true ]) error_message = "If log_config is specified, aggregation_interval must be one of INTERVAL_5_SEC, INTERVAL_30_SEC, INTERVAL_1_MIN, INTERVAL_5_MIN, INTERVAL_10_MIN, INTERVAL_15_MIN, and metadata must be one of EXCLUDE_ALL_METADATA, INCLUDE_ALL_METADATA, or CUSTOM_METADATA." } From f38e0e3ea0ce4be649324b573c893fedb28a1792 Mon Sep 17 00:00:00 2001 From: Horia Gunica Date: Wed, 9 Oct 2024 11:34:33 +0300 Subject: [PATCH 6/6] Updated validation after discussion with michalbil --- modules/vpc/variables.tf | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/vpc/variables.tf b/modules/vpc/variables.tf index 72381ee..3dc30ec 100644 --- a/modules/vpc/variables.tf +++ b/modules/vpc/variables.tf @@ -67,12 +67,14 @@ variable "subnetworks" { validation { condition = alltrue([ for subnet in var.subnetworks : - subnet.log_config != null ? ( - (subnet.log_config.aggregation_interval != null && can(regex("^INTERVAL_(5_SEC|30_SEC|1_MIN|5_MIN|10_MIN|15_MIN)$", subnet.log_config.aggregation_interval)) ? true : false) && - (subnet.log_config.metadata != null && can(regex("^(EXCLUDE_ALL_METADATA|INCLUDE_ALL_METADATA|CUSTOM_METADATA)$", subnet.log_config.metadata)) ? true : false) - ) : true + subnet.log_config != null ? (anytrue([ + (subnet.log_config.aggregation_interval != null && can(regex("^INTERVAL_(5_SEC|30_SEC|1_MIN|5_MIN|10_MIN|15_MIN)$", subnet.log_config.aggregation_interval)) ? true : false), + (subnet.log_config.metadata != null && can(regex("^(EXCLUDE_ALL_METADATA|INCLUDE_ALL_METADATA|CUSTOM_METADATA)$", subnet.log_config.metadata)) ? true : false), + (subnet.log_config.flow_sampling != null && can(subnet.log_config.flow_sampling >= 0 && subnet.log_config.flow_sampling <= 1) ? true : false), + (subnet.log_config.filter_expr != null ? true : false) + ])) : true ]) - error_message = "If log_config is specified, aggregation_interval must be one of INTERVAL_5_SEC, INTERVAL_30_SEC, INTERVAL_1_MIN, INTERVAL_5_MIN, INTERVAL_10_MIN, INTERVAL_15_MIN, and metadata must be one of EXCLUDE_ALL_METADATA, INCLUDE_ALL_METADATA, or CUSTOM_METADATA." + error_message = "If log_config is specified, at least one of the following must be specified : aggregation_interval, metadata, flow_sampling, filter_expr." } } @@ -203,4 +205,4 @@ variable "internal_ipv6_range" { EOF type = string default = "" -} \ No newline at end of file +}