Skip to content

Commit

Permalink
Refine nacl module
Browse files Browse the repository at this point in the history
  • Loading branch information
posquit0 committed Oct 24, 2023
1 parent 7b55fd5 commit c1cef35
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 50 deletions.
29 changes: 16 additions & 13 deletions modules/nacl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
This module creates following resources.

- `aws_network_acl`
- `aws_network_acl_association` (optional)
- `aws_network_acl_rule` (optional)

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Expand All @@ -11,13 +12,13 @@ This module creates following resources.
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.45 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.59 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.19.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.22.0 |

## Modules

Expand All @@ -37,23 +38,25 @@ This module creates following resources.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_name"></a> [name](#input\_name) | Desired name for the network ACL resources. | `string` | n/a | yes |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The ID of the associated VPC. | `string` | n/a | yes |
| <a name="input_egress_rules"></a> [egress\_rules](#input\_egress\_rules) | A map of egress rules in a network ACL. Use the key of map as the rule number. | `map(map(any))` | `{}` | no |
| <a name="input_ingress_rules"></a> [ingress\_rules](#input\_ingress\_rules) | A map of ingress rules in a network ACL. Use the key of map as the rule number. | `map(map(any))` | `{}` | no |
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
| <a name="input_resource_group_enabled"></a> [resource\_group\_enabled](#input\_resource\_group\_enabled) | Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
| <a name="input_subnets"></a> [subnets](#input\_subnets) | A list of subnet IDs to apply the ACL to. | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no |
| <a name="input_name"></a> [name](#input\_name) | (Required) Desired name for the network ACL resources. | `string` | n/a | yes |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | (Required) The ID of the VPC to associate. | `string` | n/a | yes |
| <a name="input_egress_rules"></a> [egress\_rules](#input\_egress\_rules) | (Optional) A set of egress rules in the default Network ACL. Use the key of map as the rule number (priority). If not explicitly defined, the AWS default rules are applied. Each block of `egress_rules` as defined below.<br> (Required) `priority` - The rule priority. The rule number. Used for ordering.<br> (Required) `action` - The action to indicate whether to allow or deny the traffic that matches the rule. Valid values are `ALLOW` and `DENY`.<br> (Required) `protocol` - The protocol to match. If using the `-1` 'all' protocol, you must specify a from and to port of `0`.<br> (Required) `from_port` - The from port to match.<br> (Required) `to_port` - The to port to match.<br> (Optional) `ipv4_cidr` - The IPv4 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv6_cidr`.<br> (Optional) `ipv6_cidr` - The IPv6 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv4_cidr`.<br> (Optional) `icmp_type` - The ICMP type to be used. Defaults to `0`.<br> (Optional) `icmp_code` - The ICMP code to be used. Defaults to `0`. | <pre>map(object({<br> action = string<br> protocol = string<br> from_port = number<br> to_port = number<br> ipv4_cidr = optional(string)<br> ipv6_cidr = optional(string)<br> icmp_type = optional(number, 0)<br> icmp_code = optional(number, 0)<br> }))</pre> | `{}` | no |
| <a name="input_ingress_rules"></a> [ingress\_rules](#input\_ingress\_rules) | (Optional) A map of ingress rules in the default Network ACL. Use the key of map as the rule number (priority). If not explicitly defined, the AWS default rules are applied. Each block of `ingress_rules` as defined below.<br> (Required) `priority` - The rule priority. The rule number. Used for ordering.<br> (Required) `action` - The action to indicate whether to allow or deny the traffic that matches the rule. Valid values are `ALLOW` and `DENY`.<br> (Required) `protocol` - The protocol to match. If using the `-1` `all` protocol, you must specify a from and to port of `0`.<br> (Required) `from_port` - The from port to match.<br> (Required) `to_port` - The to port to match.<br> (Optional) `ipv4_cidr` - The IPv4 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv6_cidr`.<br> (Optional) `ipv6_cidr` - The IPv6 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv4_cidr`.<br> (Optional) `icmp_type` - The ICMP type to be used. Defaults to `0`.<br> (Optional) `icmp_code` - The ICMP code to be used. Defaults to `0`. | <pre>map(object({<br> action = string<br> protocol = string<br> from_port = number<br> to_port = number<br> ipv4_cidr = optional(string)<br> ipv6_cidr = optional(string)<br> icmp_type = optional(number, 0)<br> icmp_code = optional(number, 0)<br> }))</pre> | `{}` | no |
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
| <a name="input_resource_group_enabled"></a> [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
| <a name="input_subnets"></a> [subnets](#input\_subnets) | (Optional) A list of subnet IDs to apply the ACL to. | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the network ACL. |
| <a name="output_associated_subnets"></a> [associated\_subnets](#output\_associated\_subnets) | A list of subnet IDs which is associated with the network ACL. |
| <a name="output_id"></a> [id](#output\_id) | The ID of the network ACL. |
| <a name="output_name"></a> [name](#output\_name) | The name of the network ACL. |
| <a name="output_owner_id"></a> [owner\_id](#output\_owner\_id) | The ID of the AWS account that owns the network ACL. |
| <a name="output_subnets"></a> [subnets](#output\_subnets) | A list of subnet IDs which is associated with the network ACL. |
| <a name="output_vpc_id"></a> [vpc\_id](#output\_vpc\_id) | The VPC ID of the network ACL. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
62 changes: 42 additions & 20 deletions modules/nacl/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ locals {
} : {}
}


###################################################
# Network ACL
###################################################

# INFO: Not supported attributes
# - `ingress`
# - `egress`
resource "aws_network_acl" "this" {
vpc_id = var.vpc_id
subnet_ids = var.subnets
Expand All @@ -28,6 +36,18 @@ resource "aws_network_acl" "this" {
}


###################################################
# Subnet Associations of Network ACL
###################################################

# resource "aws_network_acl_association" "this" {
# for_each = toset(var.subnets)
#
# network_acl_id = aws_network_acl.this.id
# subnet_id = each.value
# }


###################################################
# Network ACL Rules
###################################################
Expand All @@ -37,31 +57,33 @@ resource "aws_network_acl_rule" "ingress" {

network_acl_id = aws_network_acl.this.id

egress = false
rule_number = each.key
rule_action = lookup(each.value, "action", "")
protocol = lookup(each.value, "protocol", -1)
from_port = lookup(each.value, "from_port", null)
to_port = lookup(each.value, "to_port", null)
icmp_type = lookup(each.value, "icmp_type", null)
icmp_code = lookup(each.value, "icmp_code", null)
cidr_block = lookup(each.value, "cidr_block", null)
ipv6_cidr_block = lookup(each.value, "ipv6_cidr_block", null)
egress = false
rule_number = each.key

rule_action = lower(each.value.action)
protocol = each.value.protocol
from_port = each.value.from_port
to_port = each.value.to_prot
icmp_type = each.value.icmp_type
icmp_code = each.value.icmp_code
cidr_block = each.value.ipv4_cidr
ipv6_cidr_block = each.value.ipv6_cidr
}

resource "aws_network_acl_rule" "egress" {
for_each = var.egress_rules

network_acl_id = aws_network_acl.this.id

egress = true
rule_number = each.key
rule_action = lookup(each.value, "action", "")
protocol = lookup(each.value, "protocol", -1)
from_port = lookup(each.value, "from_port", null)
to_port = lookup(each.value, "to_port", null)
icmp_type = lookup(each.value, "icmp_type", null)
icmp_code = lookup(each.value, "icmp_code", null)
cidr_block = lookup(each.value, "cidr_block", null)
ipv6_cidr_block = lookup(each.value, "ipv6_cidr_block", null)
egress = true
rule_number = each.key

rule_action = lower(each.value.action)
protocol = each.value.protocol
from_port = each.value.from_port
to_port = each.value.to_prot
icmp_type = each.value.icmp_type
icmp_code = each.value.icmp_code
cidr_block = each.value.ipv4_cidr
ipv6_cidr_block = each.value.ipv6_cidr
}
14 changes: 12 additions & 2 deletions modules/nacl/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@ output "owner_id" {
value = aws_network_acl.this.owner_id
}

output "associated_subnets" {
output "name" {
description = "The name of the network ACL."
value = var.name
}

output "vpc_id" {
description = "The VPC ID of the network ACL."
value = aws_network_acl.this.vpc_id
}

output "subnets" {
description = "A list of subnet IDs which is associated with the network ACL."
value = var.subnets
value = aws_network_acl.this.subnet_ids
}
94 changes: 80 additions & 14 deletions modules/nacl/variables.tf
Original file line number Diff line number Diff line change
@@ -1,41 +1,104 @@
variable "name" {
description = "Desired name for the network ACL resources."
description = "(Required) Desired name for the network ACL resources."
type = string
nullable = false
}

variable "vpc_id" {
description = "The ID of the associated VPC."
description = "(Required) The ID of the VPC to associate."
type = string
nullable = false
}

variable "subnets" {
description = "A list of subnet IDs to apply the ACL to."
description = "(Optional) A list of subnet IDs to apply the ACL to."
type = list(string)
default = []
nullable = false
}

variable "ingress_rules" {
description = "A map of ingress rules in a network ACL. Use the key of map as the rule number."
type = map(map(any))
default = {}
description = <<EOF
(Optional) A map of ingress rules in the default Network ACL. Use the key of map as the rule number (priority). If not explicitly defined, the AWS default rules are applied. Each block of `ingress_rules` as defined below.
(Required) `priority` - The rule priority. The rule number. Used for ordering.
(Required) `action` - The action to indicate whether to allow or deny the traffic that matches the rule. Valid values are `ALLOW` and `DENY`.
(Required) `protocol` - The protocol to match. If using the `-1` `all` protocol, you must specify a from and to port of `0`.
(Required) `from_port` - The from port to match.
(Required) `to_port` - The to port to match.
(Optional) `ipv4_cidr` - The IPv4 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv6_cidr`.
(Optional) `ipv6_cidr` - The IPv6 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv4_cidr`.
(Optional) `icmp_type` - The ICMP type to be used. Defaults to `0`.
(Optional) `icmp_code` - The ICMP code to be used. Defaults to `0`.
EOF
type = map(object({
action = string
protocol = string
from_port = number
to_port = number
ipv4_cidr = optional(string)
ipv6_cidr = optional(string)
icmp_type = optional(number, 0)
icmp_code = optional(number, 0)
}))
default = {}
nullable = false

validation {
condition = alltrue([
for rule in var.ingress_rules :
contains(["ALLOW", "DENY"], rule.action)
])
error_message = "Valid values for `action` of each rules are `ALLOW` and `DENY`."
}
}

variable "egress_rules" {
description = "A map of egress rules in a network ACL. Use the key of map as the rule number."
type = map(map(any))
default = {}
description = <<EOF
(Optional) A set of egress rules in the default Network ACL. Use the key of map as the rule number (priority). If not explicitly defined, the AWS default rules are applied. Each block of `egress_rules` as defined below.
(Required) `priority` - The rule priority. The rule number. Used for ordering.
(Required) `action` - The action to indicate whether to allow or deny the traffic that matches the rule. Valid values are `ALLOW` and `DENY`.
(Required) `protocol` - The protocol to match. If using the `-1` 'all' protocol, you must specify a from and to port of `0`.
(Required) `from_port` - The from port to match.
(Required) `to_port` - The to port to match.
(Optional) `ipv4_cidr` - The IPv4 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv6_cidr`.
(Optional) `ipv6_cidr` - The IPv6 network range to allow or deny, in CIDR notation. Cannot be specified with `ipv4_cidr`.
(Optional) `icmp_type` - The ICMP type to be used. Defaults to `0`.
(Optional) `icmp_code` - The ICMP code to be used. Defaults to `0`.
EOF
type = map(object({
action = string
protocol = string
from_port = number
to_port = number
ipv4_cidr = optional(string)
ipv6_cidr = optional(string)
icmp_type = optional(number, 0)
icmp_code = optional(number, 0)
}))
default = {}
nullable = false

validation {
condition = alltrue([
for rule in var.egress_rules :
contains(["ALLOW", "DENY"], rule.action)
])
error_message = "Valid values for `action` of each rules are `ALLOW` and `DENY`."
}
}

variable "tags" {
description = "A map of tags to add to all resources."
description = "(Optional) A map of tags to add to all resources."
type = map(string)
default = {}
nullable = false
}

variable "module_tags_enabled" {
description = "Whether to create AWS Resource Tags for the module informations."
description = "(Optional) Whether to create AWS Resource Tags for the module informations."
type = bool
default = true
nullable = false
}


Expand All @@ -44,19 +107,22 @@ variable "module_tags_enabled" {
###################################################

variable "resource_group_enabled" {
description = "Whether to create Resource Group to find and group AWS resources which are created by this module."
description = "(Optional) Whether to create Resource Group to find and group AWS resources which are created by this module."
type = bool
default = true
nullable = false
}

variable "resource_group_name" {
description = "The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`."
description = "(Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`."
type = string
default = ""
nullable = false
}

variable "resource_group_description" {
description = "The description of Resource Group."
description = "(Optional) The description of Resource Group."
type = string
default = "Managed by Terraform."
nullable = false
}
2 changes: 1 addition & 1 deletion modules/nacl/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.45"
version = ">= 4.59"
}
}
}

0 comments on commit c1cef35

Please sign in to comment.