Skip to content

Commit

Permalink
Create infrastructure network ACL
Browse files Browse the repository at this point in the history
* Creates a network ACL with ocnfigurable rules
* If egress/ingress lockdown is enabled, all traffic will be blocked by
  default
* The ACL is applied to all the subnets created in the infrastructure
  • Loading branch information
Stretch96 committed Nov 23, 2023
1 parent 453808d commit 817222d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This project creates and manages resources within an AWS account for infrastruct
|------|------|
| [aws_athena_workgroup.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/athena_workgroup) | resource |
| [aws_cloudwatch_log_group.infrastructure_vpc_flow_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_default_network_acl.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_network_acl) | resource |
| [aws_eip.infrastructure_nat](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
| [aws_flow_log.infrastructure_vpc_flow_logs_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
| [aws_flow_log.infrastructure_vpc_flow_logs_s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
Expand All @@ -36,6 +37,13 @@ This project creates and manages resources within an AWS account for infrastruct
| [aws_kms_alias.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_key.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_nat_gateway.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource |
| [aws_network_acl.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl_association.infrastructure_private_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_association) | resource |
| [aws_network_acl_association.infrastructure_public_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_association) | resource |
| [aws_network_acl_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.egress_allow_all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.ingress_allow_all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_route.infrustructure_public_internet_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.private_nat_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route_table.infrastructure_private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
Expand Down Expand Up @@ -74,6 +82,10 @@ This project creates and manages resources within an AWS account for infrastruct
| <a name="input_infrastructure_vpc_flow_logs_s3_with_athena"></a> [infrastructure\_vpc\_flow\_logs\_s3\_with\_athena](#input\_infrastructure\_vpc\_flow\_logs\_s3\_with\_athena) | Enable VPC flow logs in infrastructure VPC to the S3 logs bucket. A compatible Glue table/database and Athena workgroup will also be created to allow querying the logs. | `bool` | n/a | yes |
| <a name="input_infrastructure_vpc_flow_logs_traffic_type"></a> [infrastructure\_vpc\_flow\_logs\_traffic\_type](#input\_infrastructure\_vpc\_flow\_logs\_traffic\_type) | Infrastructure VPC flow logs traffic type | `string` | n/a | yes |
| <a name="input_infrastructure_vpc_instance_tenancy"></a> [infrastructure\_vpc\_instance\_tenancy](#input\_infrastructure\_vpc\_instance\_tenancy) | Infrastructure VPC instance tenancy | `string` | n/a | yes |
| <a name="input_infrastructure_vpc_network_acl_egress_custom_rules"></a> [infrastructure\_vpc\_network\_acl\_egress\_custom\_rules](#input\_infrastructure\_vpc\_network\_acl\_egress\_custom\_rules) | Infrastructure vpc egress custom rules. These will be evaluated before any automatically added rules. | <pre>list(object({<br> protocol = string<br> from_port = number<br> to_port = number<br> action = string<br> cidr_block = string<br> ipv6_cidr_block = optional(string, null)<br> icmp_type = optional(number, null)<br> icmp_code = optional(number, null)<br> }))</pre> | n/a | yes |
| <a name="input_infrastructure_vpc_network_acl_egress_lockdown"></a> [infrastructure\_vpc\_network\_acl\_egress\_lockdown](#input\_infrastructure\_vpc\_network\_acl\_egress\_lockdown) | Creates a network ACL which blocks all egress traffic, except the ports required for services that are launched. | `bool` | n/a | yes |
| <a name="input_infrastructure_vpc_network_acl_ingress_custom_rules"></a> [infrastructure\_vpc\_network\_acl\_ingress\_custom\_rules](#input\_infrastructure\_vpc\_network\_acl\_ingress\_custom\_rules) | Infrastructure vpc ingress custom rules. These will be evaluated before any automatically added rules. | <pre>list(object({<br> protocol = string<br> from_port = number<br> to_port = number<br> action = string<br> cidr_block = string<br> ipv6_cidr_block = optional(string, null)<br> icmp_type = optional(number, null)<br> icmp_code = optional(number, null)<br> }))</pre> | n/a | yes |
| <a name="input_infrastructure_vpc_network_acl_ingress_lockdown"></a> [infrastructure\_vpc\_network\_acl\_ingress\_lockdown](#input\_infrastructure\_vpc\_network\_acl\_ingress\_lockdown) | Creates a network ACL which blocks all ingress traffic, except the ports required for services that are launched. | `bool` | n/a | yes |
| <a name="input_infrastructure_vpc_network_availability_zones"></a> [infrastructure\_vpc\_network\_availability\_zones](#input\_infrastructure\_vpc\_network\_availability\_zones) | A list of availability zone characters (eg. ["a", "b", "c"]) | `list(string)` | n/a | yes |
| <a name="input_infrastructure_vpc_network_enable_private"></a> [infrastructure\_vpc\_network\_enable\_private](#input\_infrastructure\_vpc\_network\_enable\_private) | Enable private networking on Infrastructure VPC. This will create subnets with a route to a NAT Gateway (If Public networking has been enabled) | `bool` | n/a | yes |
| <a name="input_infrastructure_vpc_network_enable_public"></a> [infrastructure\_vpc\_network\_enable\_public](#input\_infrastructure\_vpc\_network\_enable\_public) | Enable public networking on Infrastructure VPC. This will create subnets with a route to an Internet Gateway | `bool` | n/a | yes |
Expand Down
4 changes: 4 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ locals {
infrastructure_vpc_network_private_cidr = cidrsubnet(local.infrastructure_vpc_cidr_block, 1, 1)
infrastructure_vpc_network_private_cidr_prefix = basename(local.infrastructure_vpc_network_private_cidr)
infrastructure_vpc_network_private_cidr_newbits = 24 - local.infrastructure_vpc_network_private_cidr_prefix
infrastructure_vpc_network_acl_egress_lockdown = var.infrastructure_vpc_network_acl_egress_lockdown
infrastructure_vpc_network_acl_egress_custom_rules = var.infrastructure_vpc_network_acl_egress_custom_rules
infrastructure_vpc_network_acl_ingress_lockdown = var.infrastructure_vpc_network_acl_ingress_lockdown
infrastructure_vpc_network_acl_ingress_custom_rules = var.infrastructure_vpc_network_acl_ingress_custom_rules
infrastructure_vpc_flow_logs_cloudwatch_logs = var.infrastructure_vpc_flow_logs_cloudwatch_logs && local.infrastructure_vpc
infrastructure_vpc_flow_logs_s3_with_athena = var.infrastructure_vpc_flow_logs_s3_with_athena && local.infrastructure_vpc
infrastructure_vpc_flow_logs_s3_key_prefix = trim(var.infrastructure_vpc_flow_logs_s3_key_prefix, "/")
Expand Down
38 changes: 38 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,41 @@ variable "infrastructure_vpc_network_availability_zones" {
description = "A list of availability zone characters (eg. [\"a\", \"b\", \"c\"])"
type = list(string)
}

variable "infrastructure_vpc_network_acl_egress_lockdown" {
description = "Creates a network ACL which blocks all egress traffic, except the ports required for services that are launched."
type = bool
}

variable "infrastructure_vpc_network_acl_egress_custom_rules" {
description = "Infrastructure vpc egress custom rules. These will be evaluated before any automatically added rules."
type = list(object({
protocol = string
from_port = number
to_port = number
action = string
cidr_block = string
ipv6_cidr_block = optional(string, null)
icmp_type = optional(number, null)
icmp_code = optional(number, null)
}))
}

variable "infrastructure_vpc_network_acl_ingress_lockdown" {
description = "Creates a network ACL which blocks all ingress traffic, except the ports required for services that are launched."
type = bool
}

variable "infrastructure_vpc_network_acl_ingress_custom_rules" {
description = "Infrastructure vpc ingress custom rules. These will be evaluated before any automatically added rules."
type = list(object({
protocol = string
from_port = number
to_port = number
action = string
cidr_block = string
ipv6_cidr_block = optional(string, null)
icmp_type = optional(number, null)
icmp_code = optional(number, null)
}))
}
83 changes: 83 additions & 0 deletions vpc-infrastructure-network-acl.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
resource "aws_default_network_acl" "infrastructure" {
count = local.infrastructure_vpc ? 1 : 0

default_network_acl_id = aws_vpc.infrastructure[0].default_network_acl_id
}

resource "aws_network_acl" "infrastructure" {
count = local.infrastructure_vpc ? 1 : 0

vpc_id = aws_vpc.infrastructure[0].id

tags = {
Name = "${local.resource_prefix}-infrastructure"
}
}

resource "aws_network_acl_association" "infrastructure_public_subnets" {
for_each = local.infrastructure_vpc && local.infrastructure_vpc_network_enable_public ? aws_subnet.infrastructure_public : {}

network_acl_id = aws_network_acl.infrastructure[0].id
subnet_id = each.value.id
}

resource "aws_network_acl_association" "infrastructure_private_subnets" {
for_each = local.infrastructure_vpc && local.infrastructure_vpc_network_enable_private ? aws_subnet.infrastructure_private : {}

network_acl_id = aws_network_acl.infrastructure[0].id
subnet_id = each.value.id
}

resource "aws_network_acl_rule" "egress_allow_all" {
count = local.infrastructure_vpc && ! local.infrastructure_vpc_network_acl_egress_lockdown ? 1 : 0

network_acl_id = aws_network_acl.infrastructure[0].id
egress = true
rule_number = length(local.infrastructure_vpc_network_acl_egress_custom_rules) + 1

rule_action = "allow"
protocol = "-1"
from_port = 0
to_port = 0
cidr_block = "0.0.0.0/0"
}

resource "aws_network_acl_rule" "egress" {
count = local.infrastructure_vpc ? length(local.infrastructure_vpc_network_acl_egress_custom_rules) : 0

network_acl_id = aws_network_acl.infrastructure[0].id
rule_number = count.index + 1
egress = true
protocol = local.infrastructure_vpc_network_acl_egress_custom_rules[count.index]["protocol"]
rule_action = local.infrastructure_vpc_network_acl_egress_custom_rules[count.index]["action"]
cidr_block = local.infrastructure_vpc_network_acl_egress_custom_rules[count.index]["cidr_block"]
from_port = local.infrastructure_vpc_network_acl_egress_custom_rules[count.index]["from_port"]
to_port = local.infrastructure_vpc_network_acl_egress_custom_rules[count.index]["to_port"]
}

resource "aws_network_acl_rule" "ingress_allow_all" {
count = local.infrastructure_vpc && ! local.infrastructure_vpc_network_acl_ingress_lockdown ? 1 : 0

network_acl_id = aws_network_acl.infrastructure[0].id
egress = false
rule_number = length(local.infrastructure_vpc_network_acl_ingress_custom_rules) + 1

rule_action = "allow"
protocol = "-1"
from_port = 0
to_port = 0
cidr_block = "0.0.0.0/0"
}

resource "aws_network_acl_rule" "ingress" {
count = local.infrastructure_vpc ? length(local.infrastructure_vpc_network_acl_ingress_custom_rules) : 0

network_acl_id = aws_network_acl.infrastructure[0].id
rule_number = count.index + 1
egress = false
protocol = local.infrastructure_vpc_network_acl_ingress_custom_rules[count.index]["protocol"]
rule_action = local.infrastructure_vpc_network_acl_ingress_custom_rules[count.index]["action"]
cidr_block = local.infrastructure_vpc_network_acl_ingress_custom_rules[count.index]["cidr_block"]
from_port = local.infrastructure_vpc_network_acl_ingress_custom_rules[count.index]["from_port"]
to_port = local.infrastructure_vpc_network_acl_ingress_custom_rules[count.index]["to_port"]
}

0 comments on commit 817222d

Please sign in to comment.