diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e4e7da..b784816 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.96.1 + rev: v1.99.5 hooks: - id: terraform_fmt - id: terraform_wrapper_module_for_each diff --git a/README.md b/README.md index 71bc81d..63616b7 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Examples codified under the [`examples`](https://github.com/terraform-aws-module | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | ## Providers @@ -114,37 +114,43 @@ No resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [availability\_zone\_change\_protection](#input\_availability\_zone\_change\_protection) | A setting indicating whether the firewall is protected against changes to its Availability Zone configuration. When set to true, you must first disable this protection before adding or removing Availability Zones | `bool` | `null` | no | +| [availability\_zone\_mapping](#input\_availability\_zone\_mapping) | Required when creating a transit gateway-attached firewall. Set of configuration blocks describing the avaiability availability where you want to create firewall endpoints for a transit gateway-attached firewall |
list(object({
availability_zone_id = string
}))
| `null` | no | | [create](#input\_create) | Controls if resources should be created | `bool` | `true` | no | -| [create\_logging\_configuration](#input\_create\_logging\_configuration) | Controls if a Logging Configuration should be created | `bool` | `false` | no | +| [create\_logging\_configuration](#input\_create\_logging\_configuration) | Controls if a Logging Configuration should be created | `bool` | `null` | no | | [create\_policy](#input\_create\_policy) | Controls if policy should be created | `bool` | `true` | no | -| [create\_policy\_resource\_policy](#input\_create\_policy\_resource\_policy) | Controls if a resource policy should be created | `bool` | `false` | no | +| [create\_policy\_resource\_policy](#input\_create\_policy\_resource\_policy) | Controls if a resource policy should be created | `bool` | `null` | no | | [delete\_protection](#input\_delete\_protection) | A boolean flag indicating whether it is possible to delete the firewall. Defaults to `true` | `bool` | `true` | no | | [description](#input\_description) | A friendly description of the firewall | `string` | `""` | no | -| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings | `any` | `{}` | no | +| [enabled\_analysis\_types](#input\_enabled\_analysis\_types) | Set of types for which to collect analysis metrics. Valid values: `TLS_SNI`, `HTTP_HOST`. Defaults to `[]` | `list(string)` | `null` | no | +| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings |
object({
key_id = optional(string)
type = string
})
| `null` | no | | [firewall\_policy\_arn](#input\_firewall\_policy\_arn) | The ARN of the Firewall Policy to use | `string` | `""` | no | | [firewall\_policy\_change\_protection](#input\_firewall\_policy\_change\_protection) | A boolean flag indicating whether it is possible to change the associated firewall policy. Defaults to `false` | `bool` | `null` | no | -| [logging\_configuration\_destination\_config](#input\_logging\_configuration\_destination\_config) | A list of min 1, max 2 configuration blocks describing the destination for the logging configuration | `any` | `[]` | no | +| [logging\_configuration\_destination\_config](#input\_logging\_configuration\_destination\_config) | A list of min 1, max 2 configuration blocks describing the destination for the logging configuration |
list(object({
log_destination = map(string)
log_destination_type = string
log_type = string
}))
| `null` | no | | [name](#input\_name) | A friendly name of the firewall | `string` | `""` | no | -| [policy\_attach\_resource\_policy](#input\_policy\_attach\_resource\_policy) | Controls if a resource policy should be attached to the firewall policy | `bool` | `false` | no | +| [policy\_attach\_resource\_policy](#input\_policy\_attach\_resource\_policy) | Controls if a resource policy should be attached to the firewall policy | `bool` | `null` | no | | [policy\_description](#input\_policy\_description) | A friendly description of the firewall policy | `string` | `null` | no | -| [policy\_encryption\_configuration](#input\_policy\_encryption\_configuration) | KMS encryption configuration settings | `any` | `{}` | no | +| [policy\_encryption\_configuration](#input\_policy\_encryption\_configuration) | KMS encryption configuration settings |
object({
key_id = optional(string)
type = string
})
| `null` | no | | [policy\_name](#input\_policy\_name) | A friendly name of the firewall policy | `string` | `""` | no | -| [policy\_ram\_resource\_associations](#input\_policy\_ram\_resource\_associations) | A map of RAM resource associations for the created firewall policy | `map(string)` | `{}` | no | +| [policy\_ram\_resource\_associations](#input\_policy\_ram\_resource\_associations) | A map of RAM resource associations for the created firewall policy | `map(string)` | `null` | no | | [policy\_resource\_policy](#input\_policy\_resource\_policy) | The policy JSON to use for the resource policy; required when `create_resource_policy` is `false` | `string` | `""` | no | -| [policy\_resource\_policy\_actions](#input\_policy\_resource\_policy\_actions) | A list of IAM actions allowed in the resource policy | `list(string)` | `[]` | no | -| [policy\_resource\_policy\_principals](#input\_policy\_resource\_policy\_principals) | A list of IAM principals allowed in the resource policy | `list(string)` | `[]` | no | -| [policy\_stateful\_default\_actions](#input\_policy\_stateful\_default\_actions) | Set of actions to take on a packet if it does not match any stateful rules in the policy. This can only be specified if the policy has a `stateful_engine_options` block with a rule\_order value of `STRICT_ORDER`. You can specify one of either or neither values of `aws:drop_strict` or `aws:drop_established`, as well as any combination of `aws:alert_strict` and `aws:alert_established` | `list(string)` | `[]` | no | -| [policy\_stateful\_engine\_options](#input\_policy\_stateful\_engine\_options) | A configuration block that defines options on how the policy handles stateful rules. See [Stateful Engine Options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-engine-options) for details | `any` | `{}` | no | -| [policy\_stateful\_rule\_group\_reference](#input\_policy\_stateful\_rule\_group\_reference) | Set of configuration blocks containing references to the stateful rule groups that are used in the policy. See [Stateful Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-rule-group-reference) for details | `any` | `{}` | no | -| [policy\_stateless\_custom\_action](#input\_policy\_stateless\_custom\_action) | Set of configuration blocks describing the custom action definitions that are available for use in the firewall policy's `stateless_default_actions` | `any` | `{}` | no | -| [policy\_stateless\_default\_actions](#input\_policy\_stateless\_default\_actions) | Set of actions to take on a packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe` | `list(string)` |
[
"aws:pass"
]
| no | -| [policy\_stateless\_fragment\_default\_actions](#input\_policy\_stateless\_fragment\_default\_actions) | Set of actions to take on a fragmented packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe` | `list(string)` |
[
"aws:pass"
]
| no | -| [policy\_stateless\_rule\_group\_reference](#input\_policy\_stateless\_rule\_group\_reference) | Set of configuration blocks containing references to the stateless rule groups that are used in the policy. See [Stateless Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateless-rule-group-reference) for details | `any` | `{}` | no | +| [policy\_resource\_policy\_actions](#input\_policy\_resource\_policy\_actions) | A list of IAM actions allowed in the resource policy | `list(string)` | `null` | no | +| [policy\_resource\_policy\_principals](#input\_policy\_resource\_policy\_principals) | A list of IAM principals allowed in the resource policy | `list(string)` | `null` | no | +| [policy\_stateful\_default\_actions](#input\_policy\_stateful\_default\_actions) | Set of actions to take on a packet if it does not match any stateful rules in the policy. This can only be specified if the policy has a `stateful_engine_options` block with a rule\_order value of `STRICT_ORDER`. You can specify one of either or neither values of `aws:drop_strict` or `aws:drop_established`, as well as any combination of `aws:alert_strict` and `aws:alert_established` | `list(string)` | `null` | no | +| [policy\_stateful\_engine\_options](#input\_policy\_stateful\_engine\_options) | A configuration block that defines options on how the policy handles stateful rules. See [Stateful Engine Options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-engine-options) for details |
object({
flow_timeouts = optional(object({
tcp_idle_timeout_seconds = optional(number)
}))
rule_order = optional(string)
stream_exception_policy = optional(string)
})
| `null` | no | +| [policy\_stateful\_rule\_group\_reference](#input\_policy\_stateful\_rule\_group\_reference) | Set of configuration blocks containing references to the stateful rule groups that are used in the policy. See [Stateful Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-rule-group-reference) for details |
map(object({
deep_threat_inspection = optional(bool)
override = optional(object({
action = optional(string)
}))
priority = optional(number)
resource_arn = string
}))
| `null` | no | +| [policy\_stateless\_custom\_action](#input\_policy\_stateless\_custom\_action) | Set of configuration blocks describing the custom action definitions that are available for use in the firewall policy's `stateless_default_actions` |
map(object({
action_definition = object({
publish_metric_action = optional(object({
dimension = optional(string)
}))
})
action_name = string
}))
| `null` | no | +| [policy\_stateless\_default\_actions](#input\_policy\_stateless\_default\_actions) | Set of actions to take on a packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe` | `list(string)` | `null` | no | +| [policy\_stateless\_fragment\_default\_actions](#input\_policy\_stateless\_fragment\_default\_actions) | Set of actions to take on a fragmented packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe` | `list(string)` | `null` | no | +| [policy\_stateless\_rule\_group\_reference](#input\_policy\_stateless\_rule\_group\_reference) | Set of configuration blocks containing references to the stateless rule groups that are used in the policy. See [Stateless Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateless-rule-group-reference) for details |
map(object({
priority = number
resource_arn = string
}))
| `null` | no | | [policy\_tags](#input\_policy\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [policy\_variables](#input\_policy\_variables) | Contains variables that you can use to override default Suricata settings in your firewall policy |
object({
rule_variables = list(object({
ip_set = optional(object({
definition = list(string)
}))
key = string
}))
})
| `null` | no | +| [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no | | [subnet\_change\_protection](#input\_subnet\_change\_protection) | A boolean flag indicating whether it is possible to change the associated subnet(s). Defaults to `true` | `bool` | `true` | no | -| [subnet\_mapping](#input\_subnet\_mapping) | Set of configuration blocks describing the public subnets. Each subnet must belong to a different Availability Zone in the VPC. AWS Network Firewall creates a firewall endpoint in each subnet | `any` | `{}` | no | +| [subnet\_mapping](#input\_subnet\_mapping) | Set of configuration blocks describing the public subnets. Each subnet must belong to a different Availability Zone in the VPC. AWS Network Firewall creates a firewall endpoint in each subnet |
map(object({
ip_address_type = optional(string)
subnet_id = string
}))
| `null` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | The unique identifier of the VPC where AWS Network Firewall should create the firewall | `string` | `""` | no | +| [transit\_gateway\_id](#input\_transit\_gateway\_id) | The ID of the transit gateway to which the firewall is attached. Required when creating a transit gateway-attached firewall | `string` | `null` | no | +| [vpc\_id](#input\_vpc\_id) | The unique identifier of the VPC where AWS Network Firewall should create the firewall | `string` | `null` | no | ## Outputs diff --git a/examples/complete/README.md b/examples/complete/README.md index 41b0be1..2908608 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -22,14 +22,14 @@ Note that this example may create resources which will incur monetary charges on | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.2 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.5 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.2 | +| [aws](#provider\_aws) | >= 6.5 | ## Modules @@ -39,7 +39,7 @@ Note that this example may create resources which will incur monetary charges on | [network\_firewall\_disabled](#module\_network\_firewall\_disabled) | ../.. | n/a | | [network\_firewall\_rule\_group\_stateful](#module\_network\_firewall\_rule\_group\_stateful) | ../../modules/rule-group | n/a | | [network\_firewall\_rule\_group\_stateless](#module\_network\_firewall\_rule\_group\_stateless) | ../../modules/rule-group | n/a | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | ## Resources diff --git a/examples/complete/main.tf b/examples/complete/main.tf index b2654f3..effb755 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -187,7 +187,7 @@ module "network_firewall_rule_group_stateless" { module "vpc" { source = "terraform-aws-modules/vpc/aws" - version = "~> 5.0" + version = "~> 6.0" name = local.name cidr = local.vpc_cidr diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index cc22f92..1548bda 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/examples/separate/README.md b/examples/separate/README.md index 972e7c3..cbca6c7 100644 --- a/examples/separate/README.md +++ b/examples/separate/README.md @@ -23,14 +23,14 @@ Note that this example may create resources which will incur monetary charges on | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.2 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.5 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.2 | +| [aws](#provider\_aws) | >= 6.5 | ## Modules @@ -43,7 +43,7 @@ Note that this example may create resources which will incur monetary charges on | [network\_firewall\_rule\_group\_disabled](#module\_network\_firewall\_rule\_group\_disabled) | ../../modules/rule-group | n/a | | [network\_firewall\_rule\_group\_stateful](#module\_network\_firewall\_rule\_group\_stateful) | ../../modules/rule-group | n/a | | [network\_firewall\_rule\_group\_stateless](#module\_network\_firewall\_rule\_group\_stateless) | ../../modules/rule-group | n/a | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | ## Resources diff --git a/examples/separate/main.tf b/examples/separate/main.tf index fb25d59..a31b324 100644 --- a/examples/separate/main.tf +++ b/examples/separate/main.tf @@ -209,7 +209,7 @@ module "network_firewall_rule_group_disabled" { module "vpc" { source = "terraform-aws-modules/vpc/aws" - version = "~> 5.0" + version = "~> 6.0" name = local.name cidr = local.vpc_cidr diff --git a/examples/separate/versions.tf b/examples/separate/versions.tf index cc22f92..1548bda 100644 --- a/examples/separate/versions.tf +++ b/examples/separate/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/main.tf b/main.tf index cc1e194..8a31864 100644 --- a/main.tf +++ b/main.tf @@ -6,17 +6,22 @@ module "firewall" { source = "./modules/firewall" create = var.create + region = var.region # Firewall - delete_protection = var.delete_protection - description = var.description - encryption_configuration = var.encryption_configuration - firewall_policy_arn = var.create_policy ? module.policy.arn : var.firewall_policy_arn - firewall_policy_change_protection = var.firewall_policy_change_protection - name = var.name - subnet_change_protection = var.subnet_change_protection - subnet_mapping = var.subnet_mapping - vpc_id = var.vpc_id + availability_zone_change_protection = var.availability_zone_change_protection + availability_zone_mapping = var.availability_zone_mapping + delete_protection = var.delete_protection + description = var.description + enabled_analysis_types = var.enabled_analysis_types + encryption_configuration = var.encryption_configuration + firewall_policy_arn = var.create_policy ? module.policy.arn : var.firewall_policy_arn + firewall_policy_change_protection = var.firewall_policy_change_protection + name = var.name + subnet_change_protection = var.subnet_change_protection + subnet_mapping = var.subnet_mapping + transit_gateway_id = var.transit_gateway_id + vpc_id = var.vpc_id # Logging create_logging_configuration = var.create_logging_configuration @@ -33,10 +38,12 @@ module "policy" { source = "./modules/policy" create = var.create && var.create_policy + region = var.region # Policy description = var.policy_description encryption_configuration = var.policy_encryption_configuration + policy_variables = var.policy_variables stateful_default_actions = var.policy_stateful_default_actions stateful_engine_options = var.policy_stateful_engine_options stateful_rule_group_reference = var.policy_stateful_rule_group_reference diff --git a/modules/firewall/README.md b/modules/firewall/README.md index 54436b9..a4f85ac 100644 --- a/modules/firewall/README.md +++ b/modules/firewall/README.md @@ -62,14 +62,14 @@ module "network_firewall" { | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.2 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.5 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.2 | +| [aws](#provider\_aws) | >= 6.5 | ## Modules @@ -86,19 +86,24 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [availability\_zone\_change\_protection](#input\_availability\_zone\_change\_protection) | A setting indicating whether the firewall is protected against changes to its Availability Zone configuration. When set to true, you must first disable this protection before adding or removing Availability Zones | `bool` | `null` | no | +| [availability\_zone\_mapping](#input\_availability\_zone\_mapping) | Required when creating a transit gateway-attached firewall. Set of configuration blocks describing the avaiability availability where you want to create firewall endpoints for a transit gateway-attached firewall |
list(object({
availability_zone_id = string
}))
| `null` | no | | [create](#input\_create) | Controls if resources should be created | `bool` | `true` | no | | [create\_logging\_configuration](#input\_create\_logging\_configuration) | Controls if a Logging Configuration should be created | `bool` | `false` | no | | [delete\_protection](#input\_delete\_protection) | A boolean flag indicating whether it is possible to delete the firewall. Defaults to `true` | `bool` | `true` | no | -| [description](#input\_description) | A friendly description of the firewall | `string` | `""` | no | -| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings | `any` | `{}` | no | +| [description](#input\_description) | A friendly description of the firewall | `string` | `null` | no | +| [enabled\_analysis\_types](#input\_enabled\_analysis\_types) | Set of types for which to collect analysis metrics. Valid values: `TLS_SNI`, `HTTP_HOST`. Defaults to `[]` | `list(string)` | `[]` | no | +| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings |
object({
key_id = optional(string)
type = string
})
| `null` | no | | [firewall\_policy\_arn](#input\_firewall\_policy\_arn) | The ARN of the Firewall Policy to use | `string` | `""` | no | | [firewall\_policy\_change\_protection](#input\_firewall\_policy\_change\_protection) | A boolean flag indicating whether it is possible to change the associated firewall policy. Defaults to `false` | `bool` | `null` | no | -| [logging\_configuration\_destination\_config](#input\_logging\_configuration\_destination\_config) | A list of min 1, max 2 configuration blocks describing the destination for the logging configuration | `any` | `[]` | no | +| [logging\_configuration\_destination\_config](#input\_logging\_configuration\_destination\_config) | A list of min 1, max 2 configuration blocks describing the destination for the logging configuration |
list(object({
log_destination = map(string)
log_destination_type = string
log_type = string
}))
| `null` | no | | [name](#input\_name) | A friendly name of the firewall | `string` | `""` | no | +| [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no | | [subnet\_change\_protection](#input\_subnet\_change\_protection) | A boolean flag indicating whether it is possible to change the associated subnet(s). Defaults to `true` | `bool` | `true` | no | -| [subnet\_mapping](#input\_subnet\_mapping) | Set of configuration blocks describing the public subnets. Each subnet must belong to a different Availability Zone in the VPC. AWS Network Firewall creates a firewall endpoint in each subnet | `any` | `{}` | no | +| [subnet\_mapping](#input\_subnet\_mapping) | Set of configuration blocks describing the public subnets. Each subnet must belong to a different Availability Zone in the VPC. AWS Network Firewall creates a firewall endpoint in each subnet |
map(object({
ip_address_type = optional(string)
subnet_id = string
}))
| `null` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | The unique identifier of the VPC where AWS Network Firewall should create the firewall | `string` | `""` | no | +| [transit\_gateway\_id](#input\_transit\_gateway\_id) | The ID of the transit gateway to which the firewall is attached. Required when creating a transit gateway-attached firewall | `string` | `null` | no | +| [vpc\_id](#input\_vpc\_id) | The unique identifier of the VPC where AWS Network Firewall should create the firewall | `string` | `null` | no | ## Outputs diff --git a/modules/firewall/main.tf b/modules/firewall/main.tf index 377fda7..cb95504 100644 --- a/modules/firewall/main.tf +++ b/modules/firewall/main.tf @@ -5,14 +5,27 @@ resource "aws_networkfirewall_firewall" "this" { count = var.create ? 1 : 0 - delete_protection = var.delete_protection - description = var.description + region = var.region + + availability_zone_change_protection = var.availability_zone_change_protection + + dynamic "availability_zone_mapping" { + for_each = var.availability_zone_mapping != null ? var.availability_zone_mapping : [] + + content { + availability_zone_id = availability_zone_mapping.value.availability_zone_id + } + } + + delete_protection = var.delete_protection + description = var.description + enabled_analysis_types = var.enabled_analysis_types dynamic "encryption_configuration" { - for_each = length(var.encryption_configuration) > 0 ? [var.encryption_configuration] : [] + for_each = var.encryption_configuration != null ? [var.encryption_configuration] : [] content { - key_id = try(encryption_configuration.value.key_id, null) + key_id = encryption_configuration.value.key_id type = encryption_configuration.value.type } } @@ -23,15 +36,16 @@ resource "aws_networkfirewall_firewall" "this" { subnet_change_protection = var.subnet_change_protection dynamic "subnet_mapping" { - for_each = var.subnet_mapping + for_each = var.subnet_mapping != null ? var.subnet_mapping : {} content { - ip_address_type = try(subnet_mapping.value.ip_address_type, null) + ip_address_type = subnet_mapping.value.ip_address_type subnet_id = subnet_mapping.value.subnet_id } } - vpc_id = var.vpc_id + transit_gateway_id = var.transit_gateway_id + vpc_id = var.vpc_id tags = var.tags } @@ -43,12 +57,15 @@ resource "aws_networkfirewall_firewall" "this" { resource "aws_networkfirewall_logging_configuration" "this" { count = var.create && var.create_logging_configuration ? 1 : 0 + region = var.region + firewall_arn = aws_networkfirewall_firewall.this[0].arn logging_configuration { # At least one config, at most, only two blocks can be specified; one for `FLOW` logs and one for `ALERT` logs. dynamic "log_destination_config" { - for_each = var.logging_configuration_destination_config + for_each = var.logging_configuration_destination_config != null ? var.logging_configuration_destination_config : [] + content { log_destination = log_destination_config.value.log_destination log_destination_type = log_destination_config.value.log_destination_type diff --git a/modules/firewall/variables.tf b/modules/firewall/variables.tf index c01aafb..5f58d72 100644 --- a/modules/firewall/variables.tf +++ b/modules/firewall/variables.tf @@ -2,6 +2,13 @@ variable "create" { description = "Controls if resources should be created" type = bool default = true + nullable = false +} + +variable "region" { + description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" + type = string + default = null } variable "tags" { @@ -14,22 +21,47 @@ variable "tags" { # Firewall ################################################################################ +variable "availability_zone_change_protection" { + description = " A setting indicating whether the firewall is protected against changes to its Availability Zone configuration. When set to true, you must first disable this protection before adding or removing Availability Zones" + type = bool + default = null +} + +variable "availability_zone_mapping" { + description = "Required when creating a transit gateway-attached firewall. Set of configuration blocks describing the avaiability availability where you want to create firewall endpoints for a transit gateway-attached firewall" + type = list(object({ + availability_zone_id = string + })) + default = null +} + variable "delete_protection" { description = "A boolean flag indicating whether it is possible to delete the firewall. Defaults to `true`" type = bool default = true + nullable = false } variable "description" { description = "A friendly description of the firewall" type = string - default = "" + default = null +} + +variable "enabled_analysis_types" { + description = "Set of types for which to collect analysis metrics. Valid values: `TLS_SNI`, `HTTP_HOST`. Defaults to `[]`" + type = list(string) + default = [] + nullable = false } variable "encryption_configuration" { description = "KMS encryption configuration settings" - type = any - default = {} + type = object({ + key_id = optional(string) + type = string + }) + default = null } variable "firewall_policy_arn" { @@ -58,14 +90,23 @@ variable "subnet_change_protection" { variable "subnet_mapping" { description = "Set of configuration blocks describing the public subnets. Each subnet must belong to a different Availability Zone in the VPC. AWS Network Firewall creates a firewall endpoint in each subnet" - type = any - default = {} + type = map(object({ + ip_address_type = optional(string) + subnet_id = string + })) + default = null +} + +variable "transit_gateway_id" { + description = "The ID of the transit gateway to which the firewall is attached. Required when creating a transit gateway-attached firewall" + type = string + default = null } variable "vpc_id" { description = "The unique identifier of the VPC where AWS Network Firewall should create the firewall" type = string - default = "" + default = null } ################################################################################ @@ -76,10 +117,15 @@ variable "create_logging_configuration" { description = "Controls if a Logging Configuration should be created" type = bool default = false + nullable = false } variable "logging_configuration_destination_config" { description = "A list of min 1, max 2 configuration blocks describing the destination for the logging configuration" - type = any - default = [] + type = list(object({ + log_destination = map(string) + log_destination_type = string + log_type = string + })) + default = null } diff --git a/modules/firewall/versions.tf b/modules/firewall/versions.tf index cc22f92..1548bda 100644 --- a/modules/firewall/versions.tf +++ b/modules/firewall/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/modules/policy/README.md b/modules/policy/README.md index 462f1e2..9de49cc 100644 --- a/modules/policy/README.md +++ b/modules/policy/README.md @@ -41,14 +41,14 @@ module "network_firewall_policy" { | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.2 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.5 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.2 | +| [aws](#provider\_aws) | >= 6.5 | ## Modules @@ -71,19 +71,21 @@ No modules. | [create](#input\_create) | Controls if resources should be created | `bool` | `true` | no | | [create\_resource\_policy](#input\_create\_resource\_policy) | Controls if a resource policy should be created | `bool` | `false` | no | | [description](#input\_description) | A friendly description of the firewall policy | `string` | `null` | no | -| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings | `any` | `{}` | no | +| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings |
object({
key_id = optional(string)
type = string
})
| `null` | no | | [name](#input\_name) | A friendly name of the firewall policy | `string` | `""` | no | +| [policy\_variables](#input\_policy\_variables) | Contains variables that you can use to override default Suricata settings in your firewall policy |
object({
rule_variables = list(object({
ip_set = optional(object({
definition = list(string)
}))
key = string
}))
})
| `null` | no | | [ram\_resource\_associations](#input\_ram\_resource\_associations) | A map of RAM resource associations for the created firewall policy | `map(string)` | `{}` | no | +| [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no | | [resource\_policy](#input\_resource\_policy) | The policy JSON to use for the resource policy; required when `create_resource_policy` is `false` | `string` | `""` | no | | [resource\_policy\_actions](#input\_resource\_policy\_actions) | A list of IAM actions allowed in the resource policy | `list(string)` | `[]` | no | | [resource\_policy\_principals](#input\_resource\_policy\_principals) | A list of IAM principals allowed in the resource policy | `list(string)` | `[]` | no | | [stateful\_default\_actions](#input\_stateful\_default\_actions) | Set of actions to take on a packet if it does not match any stateful rules in the policy. This can only be specified if the policy has a `stateful_engine_options` block with a rule\_order value of `STRICT_ORDER`. You can specify one of either or neither values of `aws:drop_strict` or `aws:drop_established`, as well as any combination of `aws:alert_strict` and `aws:alert_established` | `list(string)` | `[]` | no | -| [stateful\_engine\_options](#input\_stateful\_engine\_options) | A configuration block that defines options on how the policy handles stateful rules. See [Stateful Engine Options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-engine-options) for details | `any` | `{}` | no | -| [stateful\_rule\_group\_reference](#input\_stateful\_rule\_group\_reference) | Set of configuration blocks containing references to the stateful rule groups that are used in the policy. See [Stateful Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-rule-group-reference) for details | `any` | `{}` | no | -| [stateless\_custom\_action](#input\_stateless\_custom\_action) | Set of configuration blocks describing the custom action definitions that are available for use in the firewall policy's `stateless_default_actions` | `any` | `{}` | no | +| [stateful\_engine\_options](#input\_stateful\_engine\_options) | A configuration block that defines options on how the policy handles stateful rules. See [Stateful Engine Options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-engine-options) for details |
object({
flow_timeouts = optional(object({
tcp_idle_timeout_seconds = optional(number)
}))
rule_order = optional(string)
stream_exception_policy = optional(string)
})
| `null` | no | +| [stateful\_rule\_group\_reference](#input\_stateful\_rule\_group\_reference) | Set of configuration blocks containing references to the stateful rule groups that are used in the policy. See [Stateful Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-rule-group-reference) for details |
map(object({
deep_threat_inspection = optional(bool)
override = optional(object({
action = optional(string)
}))
priority = optional(number)
resource_arn = string
}))
| `null` | no | +| [stateless\_custom\_action](#input\_stateless\_custom\_action) | Set of configuration blocks describing the custom action definitions that are available for use in the firewall policy's `stateless_default_actions` |
map(object({
action_definition = object({
publish_metric_action = optional(object({
dimension = optional(string)
}))
})
action_name = string
}))
| `null` | no | | [stateless\_default\_actions](#input\_stateless\_default\_actions) | Set of actions to take on a packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe` | `list(string)` |
[
"aws:pass"
]
| no | | [stateless\_fragment\_default\_actions](#input\_stateless\_fragment\_default\_actions) | Set of actions to take on a fragmented packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe` | `list(string)` |
[
"aws:pass"
]
| no | -| [stateless\_rule\_group\_reference](#input\_stateless\_rule\_group\_reference) | Set of configuration blocks containing references to the stateless rule groups that are used in the policy. See [Stateless Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateless-rule-group-reference) for details | `any` | `{}` | no | +| [stateless\_rule\_group\_reference](#input\_stateless\_rule\_group\_reference) | Set of configuration blocks containing references to the stateless rule groups that are used in the policy. See [Stateless Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateless-rule-group-reference) for details |
map(object({
priority = number
resource_arn = string
}))
| `null` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | ## Outputs diff --git a/modules/policy/main.tf b/modules/policy/main.tf index 9865016..52931cf 100644 --- a/modules/policy/main.tf +++ b/modules/policy/main.tf @@ -5,54 +5,86 @@ resource "aws_networkfirewall_firewall_policy" "this" { count = var.create ? 1 : 0 + region = var.region + description = var.description dynamic "encryption_configuration" { - for_each = length(var.encryption_configuration) > 0 ? [var.encryption_configuration] : [] + for_each = var.encryption_configuration != null ? [var.encryption_configuration] : [] content { - key_id = try(encryption_configuration.value.key_id, null) + key_id = encryption_configuration.value.key_id type = encryption_configuration.value.type } } firewall_policy { + dynamic "policy_variables" { + for_each = var.policy_variables != null ? [var.policy_variables] : [] + + content { + dynamic "rule_variables" { + for_each = policy_variables.value.rule_variables != null ? policy_variables.value.rule_variables : [] + + content { + dynamic "ip_set" { + for_each = rule_variables.value.ip_set != null ? [rule_variables.value.ip_set] : [] + + content { + definition = ip_set.value.definition + } + } + + key = rule_variables.value.key + } + } + } + } + # Stateful stateful_default_actions = var.stateful_default_actions dynamic "stateful_engine_options" { - for_each = length(var.stateful_engine_options) > 0 ? [var.stateful_engine_options] : [] + for_each = var.stateful_engine_options != null ? [var.stateful_engine_options] : [] content { - rule_order = try(stateful_engine_options.value.rule_order, null) - stream_exception_policy = try(stateful_engine_options.value.stream_exception_policy, null) + dynamic "flow_timeouts" { + for_each = stateful_engine_options.value.flow_timeouts != null ? [stateful_engine_options.value.flow_timeouts] : [] + + content { + tcp_idle_timeout_seconds = flow_timeouts.value.tcp_idle_timeout_seconds + } + } + + rule_order = stateful_engine_options.value.rule_order + stream_exception_policy = stateful_engine_options.value.stream_exception_policy } } dynamic "stateful_rule_group_reference" { - for_each = var.stateful_rule_group_reference + for_each = var.stateful_rule_group_reference != null ? var.stateful_rule_group_reference : {} content { + deep_threat_inspection = stateful_rule_group_reference.value.deep_threat_inspection + dynamic "override" { - for_each = try([stateful_rule_group_reference.value.override], []) + for_each = stateful_rule_group_reference.value.override != null ? [stateful_rule_group_reference.value.override] : [] content { - action = try(override.value.action, null) + action = override.value.action } } - priority = try(stateful_rule_group_reference.value.priority, null) + priority = stateful_rule_group_reference.value.priority resource_arn = stateful_rule_group_reference.value.resource_arn } } # Stateless dynamic "stateless_custom_action" { - for_each = var.stateless_custom_action + for_each = var.stateless_custom_action != null ? var.stateless_custom_action : {} content { - action_name = stateless_custom_action.value.action_name - dynamic "action_definition" { for_each = stateless_custom_action.value.action_definition @@ -72,6 +104,8 @@ resource "aws_networkfirewall_firewall_policy" "this" { } } } + + action_name = stateless_custom_action.value.action_name } } @@ -79,7 +113,7 @@ resource "aws_networkfirewall_firewall_policy" "this" { stateless_fragment_default_actions = var.stateless_fragment_default_actions dynamic "stateless_rule_group_reference" { - for_each = var.stateless_rule_group_reference + for_each = var.stateless_rule_group_reference != null ? var.stateless_rule_group_reference : {} content { priority = stateless_rule_group_reference.value.priority @@ -124,6 +158,8 @@ data "aws_iam_policy_document" "firewall_policy" { resource "aws_networkfirewall_resource_policy" "this" { count = var.create && var.attach_resource_policy ? 1 : 0 + region = var.region + resource_arn = aws_networkfirewall_firewall_policy.this[0].arn policy = var.create_resource_policy ? data.aws_iam_policy_document.firewall_policy[0].json : var.resource_policy } @@ -135,6 +171,8 @@ resource "aws_networkfirewall_resource_policy" "this" { resource "aws_ram_resource_association" "firewall_policy" { for_each = { for k, v in var.ram_resource_associations : k => v if var.create } + region = var.region + resource_arn = aws_networkfirewall_firewall_policy.this[0].arn resource_share_arn = each.value.resource_share_arn } diff --git a/modules/policy/variables.tf b/modules/policy/variables.tf index 6eb6ea6..948c781 100644 --- a/modules/policy/variables.tf +++ b/modules/policy/variables.tf @@ -2,6 +2,13 @@ variable "create" { description = "Controls if resources should be created" type = bool default = true + nullable = false +} + +variable "region" { + description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" + type = string + default = null } variable "tags" { @@ -22,50 +29,92 @@ variable "description" { variable "encryption_configuration" { description = "KMS encryption configuration settings" - type = any - default = {} + type = object({ + key_id = optional(string) + type = string + }) + default = null +} + +variable "policy_variables" { + description = "Contains variables that you can use to override default Suricata settings in your firewall policy" + type = object({ + rule_variables = list(object({ + ip_set = optional(object({ + definition = list(string) + })) + key = string + })) + }) + default = null } variable "stateful_default_actions" { description = "Set of actions to take on a packet if it does not match any stateful rules in the policy. This can only be specified if the policy has a `stateful_engine_options` block with a rule_order value of `STRICT_ORDER`. You can specify one of either or neither values of `aws:drop_strict` or `aws:drop_established`, as well as any combination of `aws:alert_strict` and `aws:alert_established`" type = list(string) default = [] + nullable = false } variable "stateful_engine_options" { description = "A configuration block that defines options on how the policy handles stateful rules. See [Stateful Engine Options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-engine-options) for details" - type = any - default = {} + type = object({ + flow_timeouts = optional(object({ + tcp_idle_timeout_seconds = optional(number) + })) + rule_order = optional(string) + stream_exception_policy = optional(string) + }) + default = null } variable "stateful_rule_group_reference" { description = "Set of configuration blocks containing references to the stateful rule groups that are used in the policy. See [Stateful Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-rule-group-reference) for details" - type = any - default = {} + type = map(object({ + deep_threat_inspection = optional(bool) + override = optional(object({ + action = optional(string) + })) + priority = optional(number) + resource_arn = string + })) + default = null } variable "stateless_custom_action" { description = "Set of configuration blocks describing the custom action definitions that are available for use in the firewall policy's `stateless_default_actions`" - type = any - default = {} + type = map(object({ + action_definition = object({ + publish_metric_action = optional(object({ + dimension = optional(string) + })) + }) + action_name = string + })) + default = null } variable "stateless_default_actions" { description = "Set of actions to take on a packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe`" type = list(string) default = ["aws:pass"] + nullable = false } variable "stateless_fragment_default_actions" { description = "Set of actions to take on a fragmented packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe`" type = list(string) default = ["aws:pass"] + nullable = false } variable "stateless_rule_group_reference" { description = "Set of configuration blocks containing references to the stateless rule groups that are used in the policy. See [Stateless Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateless-rule-group-reference) for details" - type = any - default = {} + type = map(object({ + priority = number + resource_arn = string + })) + default = null } variable "name" { @@ -82,24 +131,28 @@ variable "create_resource_policy" { description = "Controls if a resource policy should be created" type = bool default = false + nullable = false } variable "resource_policy_actions" { description = "A list of IAM actions allowed in the resource policy" type = list(string) default = [] + nullable = false } variable "resource_policy_principals" { description = "A list of IAM principals allowed in the resource policy" type = list(string) default = [] + nullable = false } variable "attach_resource_policy" { description = "Controls if a resource policy should be attached to the firewall policy" type = bool default = false + nullable = false } variable "resource_policy" { @@ -116,4 +169,5 @@ variable "ram_resource_associations" { description = "A map of RAM resource associations for the created firewall policy" type = map(string) default = {} + nullable = false } diff --git a/modules/policy/versions.tf b/modules/policy/versions.tf index cc22f92..1548bda 100644 --- a/modules/policy/versions.tf +++ b/modules/policy/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/modules/rule-group/README.md b/modules/rule-group/README.md index c2fcad9..1a25791 100644 --- a/modules/rule-group/README.md +++ b/modules/rule-group/README.md @@ -111,14 +111,14 @@ module "network_firewall_rule_group_stateless" { | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.2 | +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.5 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.2 | +| [aws](#provider\_aws) | >= 6.5 | ## Modules @@ -142,13 +142,14 @@ No modules. | [create](#input\_create) | Controls if Network Firewall resources should be created | `bool` | `true` | no | | [create\_resource\_policy](#input\_create\_resource\_policy) | Controls if a resource policy should be created | `bool` | `false` | no | | [description](#input\_description) | A friendly description of the rule group | `string` | `null` | no | -| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings | `any` | `{}` | no | +| [encryption\_configuration](#input\_encryption\_configuration) | KMS encryption configuration settings |
object({
key_id = optional(string)
type = string
})
| `null` | no | | [name](#input\_name) | A friendly name of the rule group | `string` | `""` | no | | [ram\_resource\_associations](#input\_ram\_resource\_associations) | A map of RAM resource associations for the created rule group | `map(string)` | `{}` | no | +| [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no | | [resource\_policy](#input\_resource\_policy) | The policy JSON to use for the resource policy; required when `create_resource_policy` is `false` | `string` | `""` | no | | [resource\_policy\_actions](#input\_resource\_policy\_actions) | A list of IAM actions allowed in the resource policy | `list(string)` | `[]` | no | | [resource\_policy\_principals](#input\_resource\_policy\_principals) | A list of IAM principals allowed in the resource policy | `list(string)` | `[]` | no | -| [rule\_group](#input\_rule\_group) | A configuration block that defines the rule group rules. Required unless `rules` is specified | `any` | `{}` | no | +| [rule\_group](#input\_rule\_group) | A configuration block that defines the rule group rules. Required unless `rules` is specified |
object({
reference_sets = optional(object({
ip_set_references = optional(map(object({
reference_arn = string
})))
key = string
}))
rules_source = optional(object({
rules_source_list = optional(object({
generated_rules_type = string
target_types = list(string)
targets = list(string)
}))
rules_string = optional(string)
stateful_rule = optional(list(object({
action = string
header = object({
destination = string
destination_port = string
direction = string
protocol = string
source = string
source_port = string
})
rule_option = list(object({
keyword = string
settings = optional(list(string))
}))
})))
stateless_rules_and_custom_actions = optional(object({
custom_action = optional(list(object({
action_definition = object({
publish_metric_action = object({
dimension = list(object({
value = string
}))
})
})
action_name = string
})))
stateless_rule = list(object({
priority = number
rule_definition = object({
actions = list(string)
match_attributes = object({
destination = optional(list(object({
address_definition = string
})))
destination_port = optional(list(object({
from_port = string
to_port = optional(string)
})))
protocols = optional(list(string))
source = optional(list(object({
address_definition = string
})))
source_port = optional(list(object({
from_port = string
to_port = optional(string)
})))
tcp_flag = optional(list(object({
flags = list(string)
masks = optional(list(string))
})))
})
})
rule_options = optional(list(object({
keyword = string
settings = optional(list(string))
})))
}))
}))
}))
rule_variables = optional(object({
ip_sets = optional(list(object({
key = string
ip_set = object({
defintion = list(string)
})
})))
port_sets = optional(list(object({
key = string
port_set = object({
definition = list(string)
})
})))
}))
stateful_rule_options = optional(object({
rule_order = optional(string)
}))
})
| `null` | no | | [rules](#input\_rules) | The stateful rule group rules specifications in Suricata file format, with one rule per line. Use this to import your existing Suricata compatible rule groups. Required unless `rule_group` is specified | `string` | `null` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | | [type](#input\_type) | Whether the rule group is stateless (containing stateless rules) or stateful (containing stateful rules). Valid values include: `STATEFUL` or `STATELESS` | `string` | `"STATELESS"` | no | diff --git a/modules/rule-group/main.tf b/modules/rule-group/main.tf index d5b0730..676de84 100644 --- a/modules/rule-group/main.tf +++ b/modules/rule-group/main.tf @@ -5,14 +5,16 @@ resource "aws_networkfirewall_rule_group" "this" { count = var.create ? 1 : 0 + region = var.region + capacity = var.capacity description = var.description dynamic "encryption_configuration" { - for_each = length(var.encryption_configuration) > 0 ? [var.encryption_configuration] : [] + for_each = var.encryption_configuration != null ? [var.encryption_configuration] : [] content { - key_id = try(encryption_configuration.value.key_id, null) + key_id = encryption_configuration.value.key_id type = encryption_configuration.value.type } } @@ -20,51 +22,38 @@ resource "aws_networkfirewall_rule_group" "this" { name = var.name dynamic "rule_group" { - for_each = length(var.rule_group) > 0 ? [var.rule_group] : [] + for_each = var.rule_group != null ? [var.rule_group] : [] content { + dynamic "reference_sets" { + for_each = rule_group.value.reference_sets != null ? [rule_group.value.reference_sets] : [] - dynamic "rule_variables" { - for_each = try([rule_group.value.rule_variables], []) content { + dynamic "ip_set_references" { + for_each = reference_sets.value.ip_set_references != null ? reference_sets.value.ip_set_references : [] - dynamic "ip_sets" { - # One or more - for_each = try(rule_variables.value.ip_sets, []) content { - key = ip_sets.value.key - dynamic "ip_set" { - for_each = [ip_sets.value.ip_set] - content { - definition = ip_set.value.definition - } - } - } - } + dynamic "ip_set_reference" { + for_each = ip_set_references.value != null ? ip_set_references.value : [] - dynamic "port_sets" { - # One or more - for_each = try(rule_variables.value.port_sets, []) - content { - key = port_sets.value.key - dynamic "port_set" { - for_each = [port_sets.value.port_set] content { - definition = port_set.value.definition + reference_arn = ip_set_reference.value.reference_arn } } + + key = ip_set_references.value.key } } } } dynamic "rules_source" { - for_each = [rule_group.value.rules_source] - content { - rules_string = try(rules_source.value.rules_string, null) + for_each = rule_group.value.rules_source != null ? [rule_group.value.rules_source] : [] + content { dynamic "rules_source_list" { - for_each = try([rules_source.value.rules_source_list], []) + for_each = rules_source.value.rules_source_list != null ? [rules_source.value.rules_source_list] : [] + content { generated_rules_type = rules_source_list.value.generated_rules_type target_types = rules_source_list.value.target_types @@ -72,14 +61,18 @@ resource "aws_networkfirewall_rule_group" "this" { } } + rules_string = try(rules_source.value.rules_string, null) + dynamic "stateful_rule" { # One or more - for_each = try(rules_source.value.stateful_rule, []) + for_each = rules_source.value.stateful_rule != null ? rules_source.value.stateful_rule : [] + content { action = stateful_rule.value.action dynamic "header" { - for_each = [stateful_rule.value.header] + for_each = stateful_rule.value.header != null ? [stateful_rule.value.header] : [] + content { destination = header.value.destination destination_port = header.value.destination_port @@ -92,34 +85,37 @@ resource "aws_networkfirewall_rule_group" "this" { dynamic "rule_option" { # One or more - for_each = stateful_rule.value.rule_option + for_each = stateful_rule.value.rule_option != null ? stateful_rule.value.rule_option : [] + content { keyword = rule_option.value.keyword - settings = try(rule_option.value.settings, null) + settings = rule_option.value.settings } } } } dynamic "stateless_rules_and_custom_actions" { - for_each = try([rules_source.value.stateless_rules_and_custom_actions], []) - content { + for_each = rules_source.value.stateless_rules_and_custom_actions != null ? [rules_source.value.stateless_rules_and_custom_actions] : [] + content { dynamic "custom_action" { # One or more - for_each = try(stateless_rules_and_custom_actions.value.custom_action, []) - content { - action_name = custom_action.value.action_name + for_each = stateless_rules_and_custom_actions.value.custom_action != null ? stateless_rules_and_custom_actions.value.custom_action : [] + content { dynamic "action_definition" { - for_each = [custom_action.value.action_definition] + for_each = custom_action.value.action_definition != null ? [custom_action.value.action_definition] : [] + content { dynamic "publish_metric_action" { - for_each = [action_definition.value.publish_metric_action] + for_each = action_definition.value.publish_metric_action != null ? [action_definition.value.publish_metric_action] : [] + content { dynamic "dimension" { # One or more - for_each = publish_metric_action.value.dimension + for_each = publish_metric_action.value.dimension != null ? publish_metric_action.value.dimension : [] + content { value = dimension.value.value } @@ -128,29 +124,32 @@ resource "aws_networkfirewall_rule_group" "this" { } } } + + action_name = custom_action.value.action_name } } dynamic "stateless_rule" { # One or more - for_each = stateless_rules_and_custom_actions.value.stateless_rule + for_each = stateless_rules_and_custom_actions.value.stateless_rule != null ? stateless_rules_and_custom_actions.value.stateless_rule : [] + content { priority = stateless_rule.value.priority dynamic "rule_definition" { - for_each = [stateless_rule.value.rule_definition] + for_each = stateless_rule.value.rule_definition != null ? [stateless_rule.value.rule_definition] : [] + content { actions = rule_definition.value.actions dynamic "match_attributes" { - for_each = [rule_definition.value.match_attributes] - content { - - protocols = try(match_attributes.value.protocols, []) + for_each = rule_definition.value.match_attributes != null ? [rule_definition.value.match_attributes] : [] + content { dynamic "destination" { # One or more - for_each = try(match_attributes.value.destination, []) + for_each = match_attributes.value.destination != null ? match_attributes.value.destination : [] + content { address_definition = destination.value.address_definition } @@ -158,16 +157,20 @@ resource "aws_networkfirewall_rule_group" "this" { dynamic "destination_port" { # One or more - for_each = try(match_attributes.value.destination_port, []) + for_each = match_attributes.value.destination_port != null ? match_attributes.value.destination_port : [] + content { from_port = destination_port.value.from_port - to_port = try(destination_port.value.to_port, null) + to_port = destination_port.value.to_port } } + protocols = match_attributes.value.protocols + dynamic "source" { # One or more - for_each = try(match_attributes.value.source, []) + for_each = match_attributes.value.source != null ? match_attributes.value.source : [] + content { address_definition = source.value.address_definition } @@ -175,19 +178,21 @@ resource "aws_networkfirewall_rule_group" "this" { dynamic "source_port" { # One or more - for_each = try(match_attributes.value.source_port, []) + for_each = match_attributes.value.source_port != null ? match_attributes.value.source_port : [] + content { from_port = source_port.value.from_port - to_port = try(source_port.value.to_port, null) + to_port = source_port.value.to_port } } dynamic "tcp_flag" { # One or more - for_each = try(match_attributes.value.tcp_flag, []) + for_each = match_attributes.value.tcp_flag != null ? match_attributes.value.tcp_flag : [] + content { flags = tcp_flag.value.flags - masks = try(tcp_flag.value.masks, []) + masks = tcp_flag.value.masks } } } @@ -201,8 +206,49 @@ resource "aws_networkfirewall_rule_group" "this" { } } + dynamic "rule_variables" { + for_each = rule_group.value.rule_variables != null ? [rule_group.value.rule_variables] : [] + + content { + dynamic "ip_sets" { + # One or more + for_each = rule_variables.value.ip_sets != null ? rule_variables.value.ip_sets : [] + + content { + key = ip_sets.value.key + + dynamic "ip_set" { + for_each = ip_sets.value.ip_set != null ? [ip_sets.value.ip_set] : [] + + content { + definition = ip_set.value.definition + } + } + } + } + + dynamic "port_sets" { + # One or more + for_each = rule_variables.value.port_sets != null ? rule_variables.value.port_sets : [] + + content { + key = port_sets.value.key + + dynamic "port_set" { + for_each = [port_sets.value.port_set] + + content { + definition = port_set.value.definition + } + } + } + } + } + } + dynamic "stateful_rule_options" { - for_each = try([rule_group.value.stateful_rule_options], []) + for_each = rule_group.value.stateful_rule_options != null ? [rule_group.value.stateful_rule_options] : [] + content { rule_order = stateful_rule_options.value.rule_order } @@ -245,6 +291,8 @@ data "aws_iam_policy_document" "rule_group" { resource "aws_networkfirewall_resource_policy" "this" { count = var.create && var.attach_resource_policy ? 1 : 0 + region = var.region + resource_arn = aws_networkfirewall_rule_group.this[0].arn policy = var.create_resource_policy ? data.aws_iam_policy_document.rule_group[0].json : var.resource_policy } @@ -256,6 +304,8 @@ resource "aws_networkfirewall_resource_policy" "this" { resource "aws_ram_resource_association" "this" { for_each = { for k, v in var.ram_resource_associations : k => v if var.create } + region = var.region + resource_arn = aws_networkfirewall_rule_group.this[0].arn resource_share_arn = each.value.resource_share_arn } diff --git a/modules/rule-group/variables.tf b/modules/rule-group/variables.tf index 50e4f08..fa81acc 100644 --- a/modules/rule-group/variables.tf +++ b/modules/rule-group/variables.tf @@ -4,6 +4,12 @@ variable "create" { default = true } +variable "region" { + description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" + type = string + default = null +} + variable "tags" { description = "A map of tags to add to all resources" type = map(string) @@ -28,8 +34,11 @@ variable "description" { variable "encryption_configuration" { description = "KMS encryption configuration settings" - type = any - default = {} + type = object({ + key_id = optional(string) + type = string + }) + default = null } variable "name" { @@ -40,8 +49,99 @@ variable "name" { variable "rule_group" { description = "A configuration block that defines the rule group rules. Required unless `rules` is specified" - type = any - default = {} + type = object({ + reference_sets = optional(object({ + ip_set_references = optional(map(object({ + reference_arn = string + }))) + key = string + })) + rules_source = optional(object({ + rules_source_list = optional(object({ + generated_rules_type = string + target_types = list(string) + targets = list(string) + })) + rules_string = optional(string) + stateful_rule = optional(list(object({ + action = string + header = object({ + destination = string + destination_port = string + direction = string + protocol = string + source = string + source_port = string + }) + rule_option = list(object({ + keyword = string + settings = optional(list(string)) + })) + }))) + stateless_rules_and_custom_actions = optional(object({ + custom_action = optional(list(object({ + action_definition = object({ + publish_metric_action = object({ + dimension = list(object({ + value = string + })) + }) + }) + action_name = string + }))) + stateless_rule = list(object({ + priority = number + rule_definition = object({ + actions = list(string) + match_attributes = object({ + destination = optional(list(object({ + address_definition = string + }))) + destination_port = optional(list(object({ + from_port = string + to_port = optional(string) + }))) + protocols = optional(list(string)) + source = optional(list(object({ + address_definition = string + }))) + source_port = optional(list(object({ + from_port = string + to_port = optional(string) + }))) + tcp_flag = optional(list(object({ + flags = list(string) + masks = optional(list(string)) + }))) + }) + }) + rule_options = optional(list(object({ + keyword = string + settings = optional(list(string)) + }))) + })) + })) + })) + rule_variables = optional(object({ + ip_sets = optional(list(object({ + key = string + ip_set = object({ + defintion = list(string) + }) + }))) + port_sets = optional(list(object({ + key = string + port_set = object({ + definition = list(string) + }) + }))) + })) + stateful_rule_options = optional(object({ + rule_order = optional(string) + })) + }) + + default = null } variable "rules" { diff --git a/modules/rule-group/versions.tf b/modules/rule-group/versions.tf index cc22f92..1548bda 100644 --- a/modules/rule-group/versions.tf +++ b/modules/rule-group/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/variables.tf b/variables.tf index d915a48..8e1459d 100644 --- a/variables.tf +++ b/variables.tf @@ -4,6 +4,12 @@ variable "create" { default = true } +variable "region" { + description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" + type = string + default = null +} + variable "tags" { description = "A map of tags to add to all resources" type = map(string) @@ -14,6 +20,20 @@ variable "tags" { # Firewall ################################################################################ +variable "availability_zone_change_protection" { + description = " A setting indicating whether the firewall is protected against changes to its Availability Zone configuration. When set to true, you must first disable this protection before adding or removing Availability Zones" + type = bool + default = null +} + +variable "availability_zone_mapping" { + description = "Required when creating a transit gateway-attached firewall. Set of configuration blocks describing the avaiability availability where you want to create firewall endpoints for a transit gateway-attached firewall" + type = list(object({ + availability_zone_id = string + })) + default = null +} + variable "delete_protection" { description = "A boolean flag indicating whether it is possible to delete the firewall. Defaults to `true`" type = bool @@ -26,10 +46,19 @@ variable "description" { default = "" } +variable "enabled_analysis_types" { + description = "Set of types for which to collect analysis metrics. Valid values: `TLS_SNI`, `HTTP_HOST`. Defaults to `[]`" + type = list(string) + default = null +} + variable "encryption_configuration" { description = "KMS encryption configuration settings" - type = any - default = {} + type = object({ + key_id = optional(string) + type = string + }) + default = null } variable "firewall_policy_arn" { @@ -58,14 +87,23 @@ variable "subnet_change_protection" { variable "subnet_mapping" { description = "Set of configuration blocks describing the public subnets. Each subnet must belong to a different Availability Zone in the VPC. AWS Network Firewall creates a firewall endpoint in each subnet" - type = any - default = {} + type = map(object({ + ip_address_type = optional(string) + subnet_id = string + })) + default = null +} + +variable "transit_gateway_id" { + description = "The ID of the transit gateway to which the firewall is attached. Required when creating a transit gateway-attached firewall" + type = string + default = null } variable "vpc_id" { description = "The unique identifier of the VPC where AWS Network Firewall should create the firewall" type = string - default = "" + default = null } ################################################################################ @@ -75,14 +113,19 @@ variable "vpc_id" { variable "create_logging_configuration" { description = "Controls if a Logging Configuration should be created" type = bool - default = false + default = null } variable "logging_configuration_destination_config" { description = "A list of min 1, max 2 configuration blocks describing the destination for the logging configuration" - type = any - default = [] + type = list(object({ + log_destination = map(string) + log_destination_type = string + log_type = string + })) + default = null } + ################################################################################ # Firewall Policy ################################################################################ @@ -101,50 +144,89 @@ variable "policy_description" { variable "policy_encryption_configuration" { description = "KMS encryption configuration settings" - type = any - default = {} + type = object({ + key_id = optional(string) + type = string + }) + default = null +} + +variable "policy_variables" { + description = "Contains variables that you can use to override default Suricata settings in your firewall policy" + type = object({ + rule_variables = list(object({ + ip_set = optional(object({ + definition = list(string) + })) + key = string + })) + }) + default = null } variable "policy_stateful_default_actions" { description = "Set of actions to take on a packet if it does not match any stateful rules in the policy. This can only be specified if the policy has a `stateful_engine_options` block with a rule_order value of `STRICT_ORDER`. You can specify one of either or neither values of `aws:drop_strict` or `aws:drop_established`, as well as any combination of `aws:alert_strict` and `aws:alert_established`" type = list(string) - default = [] + default = null } variable "policy_stateful_engine_options" { description = "A configuration block that defines options on how the policy handles stateful rules. See [Stateful Engine Options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-engine-options) for details" - type = any - default = {} + type = object({ + flow_timeouts = optional(object({ + tcp_idle_timeout_seconds = optional(number) + })) + rule_order = optional(string) + stream_exception_policy = optional(string) + }) + default = null } variable "policy_stateful_rule_group_reference" { description = "Set of configuration blocks containing references to the stateful rule groups that are used in the policy. See [Stateful Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateful-rule-group-reference) for details" - type = any - default = {} + type = map(object({ + deep_threat_inspection = optional(bool) + override = optional(object({ + action = optional(string) + })) + priority = optional(number) + resource_arn = string + })) + default = null } variable "policy_stateless_custom_action" { description = "Set of configuration blocks describing the custom action definitions that are available for use in the firewall policy's `stateless_default_actions`" - type = any - default = {} + type = map(object({ + action_definition = object({ + publish_metric_action = optional(object({ + dimension = optional(string) + })) + }) + action_name = string + })) + default = null } variable "policy_stateless_default_actions" { description = "Set of actions to take on a packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe`" type = list(string) - default = ["aws:pass"] + default = null } variable "policy_stateless_fragment_default_actions" { description = "Set of actions to take on a fragmented packet if it does not match any of the stateless rules in the policy. You must specify one of the standard actions including: `aws:drop`, `aws:pass`, or `aws:forward_to_sfe`" type = list(string) - default = ["aws:pass"] + default = null } variable "policy_stateless_rule_group_reference" { description = "Set of configuration blocks containing references to the stateless rule groups that are used in the policy. See [Stateless Rule Group Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/networkfirewall_firewall_policy#stateless-rule-group-reference) for details" - type = any - default = {} + type = map(object({ + priority = number + resource_arn = string + })) + default = null } variable "policy_name" { @@ -163,25 +245,25 @@ variable "policy_tags" { variable "create_policy_resource_policy" { description = "Controls if a resource policy should be created" type = bool - default = false + default = null } variable "policy_resource_policy_actions" { description = "A list of IAM actions allowed in the resource policy" type = list(string) - default = [] + default = null } variable "policy_resource_policy_principals" { description = "A list of IAM principals allowed in the resource policy" type = list(string) - default = [] + default = null } variable "policy_attach_resource_policy" { description = "Controls if a resource policy should be attached to the firewall policy" type = bool - default = false + default = null } variable "policy_resource_policy" { @@ -194,5 +276,5 @@ variable "policy_resource_policy" { variable "policy_ram_resource_associations" { description = "A map of RAM resource associations for the created firewall policy" type = map(string) - default = {} + default = null } diff --git a/versions.tf b/versions.tf index 7117131..674c6b7 100644 --- a/versions.tf +++ b/versions.tf @@ -1,3 +1,3 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" } diff --git a/wrappers/firewall/main.tf b/wrappers/firewall/main.tf index c004fe6..dcc266c 100644 --- a/wrappers/firewall/main.tf +++ b/wrappers/firewall/main.tf @@ -3,17 +3,22 @@ module "wrapper" { for_each = var.items + availability_zone_change_protection = try(each.value.availability_zone_change_protection, var.defaults.availability_zone_change_protection, null) + availability_zone_mapping = try(each.value.availability_zone_mapping, var.defaults.availability_zone_mapping, null) create = try(each.value.create, var.defaults.create, true) create_logging_configuration = try(each.value.create_logging_configuration, var.defaults.create_logging_configuration, false) delete_protection = try(each.value.delete_protection, var.defaults.delete_protection, true) - description = try(each.value.description, var.defaults.description, "") - encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, {}) + description = try(each.value.description, var.defaults.description, null) + enabled_analysis_types = try(each.value.enabled_analysis_types, var.defaults.enabled_analysis_types, []) + encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, null) firewall_policy_arn = try(each.value.firewall_policy_arn, var.defaults.firewall_policy_arn, "") firewall_policy_change_protection = try(each.value.firewall_policy_change_protection, var.defaults.firewall_policy_change_protection, null) - logging_configuration_destination_config = try(each.value.logging_configuration_destination_config, var.defaults.logging_configuration_destination_config, []) + logging_configuration_destination_config = try(each.value.logging_configuration_destination_config, var.defaults.logging_configuration_destination_config, null) name = try(each.value.name, var.defaults.name, "") + region = try(each.value.region, var.defaults.region, null) subnet_change_protection = try(each.value.subnet_change_protection, var.defaults.subnet_change_protection, true) - subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, {}) + subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, null) tags = try(each.value.tags, var.defaults.tags, {}) - vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, "") + transit_gateway_id = try(each.value.transit_gateway_id, var.defaults.transit_gateway_id, null) + vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, null) } diff --git a/wrappers/firewall/versions.tf b/wrappers/firewall/versions.tf index cc22f92..1548bda 100644 --- a/wrappers/firewall/versions.tf +++ b/wrappers/firewall/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/wrappers/main.tf b/wrappers/main.tf index 21ad738..d1dd780 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -3,35 +3,41 @@ module "wrapper" { for_each = var.items + availability_zone_change_protection = try(each.value.availability_zone_change_protection, var.defaults.availability_zone_change_protection, null) + availability_zone_mapping = try(each.value.availability_zone_mapping, var.defaults.availability_zone_mapping, null) create = try(each.value.create, var.defaults.create, true) - create_logging_configuration = try(each.value.create_logging_configuration, var.defaults.create_logging_configuration, false) + create_logging_configuration = try(each.value.create_logging_configuration, var.defaults.create_logging_configuration, null) create_policy = try(each.value.create_policy, var.defaults.create_policy, true) - create_policy_resource_policy = try(each.value.create_policy_resource_policy, var.defaults.create_policy_resource_policy, false) + create_policy_resource_policy = try(each.value.create_policy_resource_policy, var.defaults.create_policy_resource_policy, null) delete_protection = try(each.value.delete_protection, var.defaults.delete_protection, true) description = try(each.value.description, var.defaults.description, "") - encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, {}) + enabled_analysis_types = try(each.value.enabled_analysis_types, var.defaults.enabled_analysis_types, null) + encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, null) firewall_policy_arn = try(each.value.firewall_policy_arn, var.defaults.firewall_policy_arn, "") firewall_policy_change_protection = try(each.value.firewall_policy_change_protection, var.defaults.firewall_policy_change_protection, null) - logging_configuration_destination_config = try(each.value.logging_configuration_destination_config, var.defaults.logging_configuration_destination_config, []) + logging_configuration_destination_config = try(each.value.logging_configuration_destination_config, var.defaults.logging_configuration_destination_config, null) name = try(each.value.name, var.defaults.name, "") - policy_attach_resource_policy = try(each.value.policy_attach_resource_policy, var.defaults.policy_attach_resource_policy, false) + policy_attach_resource_policy = try(each.value.policy_attach_resource_policy, var.defaults.policy_attach_resource_policy, null) policy_description = try(each.value.policy_description, var.defaults.policy_description, null) - policy_encryption_configuration = try(each.value.policy_encryption_configuration, var.defaults.policy_encryption_configuration, {}) + policy_encryption_configuration = try(each.value.policy_encryption_configuration, var.defaults.policy_encryption_configuration, null) policy_name = try(each.value.policy_name, var.defaults.policy_name, "") - policy_ram_resource_associations = try(each.value.policy_ram_resource_associations, var.defaults.policy_ram_resource_associations, {}) + policy_ram_resource_associations = try(each.value.policy_ram_resource_associations, var.defaults.policy_ram_resource_associations, null) policy_resource_policy = try(each.value.policy_resource_policy, var.defaults.policy_resource_policy, "") - policy_resource_policy_actions = try(each.value.policy_resource_policy_actions, var.defaults.policy_resource_policy_actions, []) - policy_resource_policy_principals = try(each.value.policy_resource_policy_principals, var.defaults.policy_resource_policy_principals, []) - policy_stateful_default_actions = try(each.value.policy_stateful_default_actions, var.defaults.policy_stateful_default_actions, []) - policy_stateful_engine_options = try(each.value.policy_stateful_engine_options, var.defaults.policy_stateful_engine_options, {}) - policy_stateful_rule_group_reference = try(each.value.policy_stateful_rule_group_reference, var.defaults.policy_stateful_rule_group_reference, {}) - policy_stateless_custom_action = try(each.value.policy_stateless_custom_action, var.defaults.policy_stateless_custom_action, {}) - policy_stateless_default_actions = try(each.value.policy_stateless_default_actions, var.defaults.policy_stateless_default_actions, ["aws:pass"]) - policy_stateless_fragment_default_actions = try(each.value.policy_stateless_fragment_default_actions, var.defaults.policy_stateless_fragment_default_actions, ["aws:pass"]) - policy_stateless_rule_group_reference = try(each.value.policy_stateless_rule_group_reference, var.defaults.policy_stateless_rule_group_reference, {}) + policy_resource_policy_actions = try(each.value.policy_resource_policy_actions, var.defaults.policy_resource_policy_actions, null) + policy_resource_policy_principals = try(each.value.policy_resource_policy_principals, var.defaults.policy_resource_policy_principals, null) + policy_stateful_default_actions = try(each.value.policy_stateful_default_actions, var.defaults.policy_stateful_default_actions, null) + policy_stateful_engine_options = try(each.value.policy_stateful_engine_options, var.defaults.policy_stateful_engine_options, null) + policy_stateful_rule_group_reference = try(each.value.policy_stateful_rule_group_reference, var.defaults.policy_stateful_rule_group_reference, null) + policy_stateless_custom_action = try(each.value.policy_stateless_custom_action, var.defaults.policy_stateless_custom_action, null) + policy_stateless_default_actions = try(each.value.policy_stateless_default_actions, var.defaults.policy_stateless_default_actions, null) + policy_stateless_fragment_default_actions = try(each.value.policy_stateless_fragment_default_actions, var.defaults.policy_stateless_fragment_default_actions, null) + policy_stateless_rule_group_reference = try(each.value.policy_stateless_rule_group_reference, var.defaults.policy_stateless_rule_group_reference, null) policy_tags = try(each.value.policy_tags, var.defaults.policy_tags, {}) + policy_variables = try(each.value.policy_variables, var.defaults.policy_variables, null) + region = try(each.value.region, var.defaults.region, null) subnet_change_protection = try(each.value.subnet_change_protection, var.defaults.subnet_change_protection, true) - subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, {}) + subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, null) tags = try(each.value.tags, var.defaults.tags, {}) - vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, "") + transit_gateway_id = try(each.value.transit_gateway_id, var.defaults.transit_gateway_id, null) + vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, null) } diff --git a/wrappers/policy/main.tf b/wrappers/policy/main.tf index 5854bcc..15626ee 100644 --- a/wrappers/policy/main.tf +++ b/wrappers/policy/main.tf @@ -7,18 +7,20 @@ module "wrapper" { create = try(each.value.create, var.defaults.create, true) create_resource_policy = try(each.value.create_resource_policy, var.defaults.create_resource_policy, false) description = try(each.value.description, var.defaults.description, null) - encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, {}) + encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, null) name = try(each.value.name, var.defaults.name, "") + policy_variables = try(each.value.policy_variables, var.defaults.policy_variables, null) ram_resource_associations = try(each.value.ram_resource_associations, var.defaults.ram_resource_associations, {}) + region = try(each.value.region, var.defaults.region, null) resource_policy = try(each.value.resource_policy, var.defaults.resource_policy, "") resource_policy_actions = try(each.value.resource_policy_actions, var.defaults.resource_policy_actions, []) resource_policy_principals = try(each.value.resource_policy_principals, var.defaults.resource_policy_principals, []) stateful_default_actions = try(each.value.stateful_default_actions, var.defaults.stateful_default_actions, []) - stateful_engine_options = try(each.value.stateful_engine_options, var.defaults.stateful_engine_options, {}) - stateful_rule_group_reference = try(each.value.stateful_rule_group_reference, var.defaults.stateful_rule_group_reference, {}) - stateless_custom_action = try(each.value.stateless_custom_action, var.defaults.stateless_custom_action, {}) + stateful_engine_options = try(each.value.stateful_engine_options, var.defaults.stateful_engine_options, null) + stateful_rule_group_reference = try(each.value.stateful_rule_group_reference, var.defaults.stateful_rule_group_reference, null) + stateless_custom_action = try(each.value.stateless_custom_action, var.defaults.stateless_custom_action, null) stateless_default_actions = try(each.value.stateless_default_actions, var.defaults.stateless_default_actions, ["aws:pass"]) stateless_fragment_default_actions = try(each.value.stateless_fragment_default_actions, var.defaults.stateless_fragment_default_actions, ["aws:pass"]) - stateless_rule_group_reference = try(each.value.stateless_rule_group_reference, var.defaults.stateless_rule_group_reference, {}) + stateless_rule_group_reference = try(each.value.stateless_rule_group_reference, var.defaults.stateless_rule_group_reference, null) tags = try(each.value.tags, var.defaults.tags, {}) } diff --git a/wrappers/policy/versions.tf b/wrappers/policy/versions.tf index cc22f92..1548bda 100644 --- a/wrappers/policy/versions.tf +++ b/wrappers/policy/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/wrappers/rule-group/main.tf b/wrappers/rule-group/main.tf index 7c20c6d..abb0bed 100644 --- a/wrappers/rule-group/main.tf +++ b/wrappers/rule-group/main.tf @@ -8,13 +8,14 @@ module "wrapper" { create = try(each.value.create, var.defaults.create, true) create_resource_policy = try(each.value.create_resource_policy, var.defaults.create_resource_policy, false) description = try(each.value.description, var.defaults.description, null) - encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, {}) + encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, null) name = try(each.value.name, var.defaults.name, "") ram_resource_associations = try(each.value.ram_resource_associations, var.defaults.ram_resource_associations, {}) + region = try(each.value.region, var.defaults.region, null) resource_policy = try(each.value.resource_policy, var.defaults.resource_policy, "") resource_policy_actions = try(each.value.resource_policy_actions, var.defaults.resource_policy_actions, []) resource_policy_principals = try(each.value.resource_policy_principals, var.defaults.resource_policy_principals, []) - rule_group = try(each.value.rule_group, var.defaults.rule_group, {}) + rule_group = try(each.value.rule_group, var.defaults.rule_group, null) rules = try(each.value.rules, var.defaults.rules, null) tags = try(each.value.tags, var.defaults.tags, {}) type = try(each.value.type, var.defaults.type, "STATELESS") diff --git a/wrappers/rule-group/versions.tf b/wrappers/rule-group/versions.tf index cc22f92..1548bda 100644 --- a/wrappers/rule-group/versions.tf +++ b/wrappers/rule-group/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.2" + version = ">= 6.5" } } } diff --git a/wrappers/versions.tf b/wrappers/versions.tf index 7117131..674c6b7 100644 --- a/wrappers/versions.tf +++ b/wrappers/versions.tf @@ -1,3 +1,3 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.5.7" }