Commit 65b893a6 authored by Anton Babenko's avatar Anton Babenko Committed by GitHub

Network ACLs (#238)

* Add variables for network ACLs

Add variables for specifying network ACLs for public, private, and
intra subnets. The ACLs are defined in a list, with sets of seven
elements for the rule number, rule action, from port, to port,
protocol, and cidr block.

* Add variables for network ACL tags

Add variables to specify additional tags for public, private, and intra
network ACL resources.

* Add resources for network ACLs

Add aws_network_acl and aws_network_acl_rule resources to specify
inbound and outbound network ACL rules for public, private, and intra
subnets.

* Add resource for default network ACL

Add a aws_default_network_acl resource to adopt the default network ACL
in the VPC.

* Adjust spacing to match code style

Remove the empty lines after comment blocks for network ACLs to match
the style of the rest of this module.

* Copy simple-vpc example as network-acls

Copy the simple-vpc example and adapt it to demonstrate the
configuration of network ACLs. A set of inbound and outbound ACLs are
specified in main.tf.

* Rename variables from _acls to _acl_rules

Clarify the variables for specifying ACL rules by renaming them from
*_acls to *_acl_rules. The values are used to create rules, not create
ACLs.

* Add nacl resources and variables for other subnets

Add aws_network_acl and aws_network_acl_rule resources for database,
redshift, and elasticache subnets, along with corresponding variables.
This provides network ACL coverage to all subnet types produced by this
module.

* Create ACLs only if there are subnets

For each subnet type, only create ACL resources if there are subnets
defined. For example, if database_subnets is empty, then don't create
ACL resources for database subnets.

* Add missing variables for ACL tags

Add the missing variable declarations for database_acl_tags,
redshift_acl_tags, and elasticache_acl_tags.

* Make ACL singular in description for _acl_tags

A single ACL is created for each of the subnet types. Update the
variable descriptions to reflect this.

* Convert rules to nested list of maps

Convert the NACL rule specifications from a list of lists to a list of
maps, as suggested by @jczerniak. This improves the readability of
rules.

* Restructure example config to use locals

Restructure the network ACL rules in the network-acls example to use
local variables to specify the rules, split between default and custom
rules.

* Follow-up for #174
parent b5b23cdd
This diff is collapsed.
# Simple VPC with Network ACLs
Configuration in this directory creates set of VPC resources along with network ACLs for public subnets.
There is a public and private subnet created per availability zone in addition to single NAT Gateway shared between all 3 availability zones.
Network ACL rules for inbound and outbound traffic are defined as the following:
1. Public subnets will have network ACL rules provided
1. Private subnets will be associated with the default network ACL rules (IPV4-only ingress and egress is open for all)
1. Elasticache subnets will use the default network ACL (created and managed by AWS)
## Usage
To run this example you need to execute:
```bash
$ terraform init
$ terraform plan
$ terraform apply
```
Note that this example may create resources which can cost money (AWS Elastic IP, for example). Run `terraform destroy` when you don't need these resources.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Outputs
| Name | Description |
|------|-------------|
| default\_network\_acl\_id | The ID of the default network ACL |
| elasticache\_network\_acl\_id | ID of the elasticache network ACL |
| nat\_public\_ips | List of public Elastic IPs created for AWS NAT Gateway |
| private\_network\_acl\_id | ID of the private network ACL |
| private\_subnets | List of IDs of private subnets |
| public\_network\_acl\_id | ID of the public network ACL |
| public\_subnets | List of IDs of public subnets |
| vpc\_cidr\_block | The CIDR block of the VPC |
| vpc\_id | The ID of the VPC |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
provider "aws" {
region = "eu-west-1"
}
module "vpc" {
source = "../../"
name = "network-acls-example"
cidr = "10.0.0.0/16"
azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
elasticache_subnets = ["10.0.201.0/24", "10.0.202.0/24", "10.0.203.0/24"]
public_dedicated_network_acl = true
public_inbound_acl_rules = "${concat(local.network_acls["default_inbound"], local.network_acls["public_inbound"])}"
public_outbound_acl_rules = "${concat(local.network_acls["default_outbound"], local.network_acls["public_outbound"])}"
private_dedicated_network_acl = true
assign_generated_ipv6_cidr_block = true
enable_nat_gateway = false
single_nat_gateway = true
public_subnet_tags = {
Name = "overridden-name-public"
}
tags = {
Owner = "user"
Environment = "dev"
}
vpc_tags = {
Name = "vpc-name"
}
}
locals {
network_acls = {
default_inbound = [
{
rule_number = 900
rule_action = "allow"
from_port = 1024
to_port = 65535
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
]
default_outbound = [
{
rule_number = 900
rule_action = "allow"
from_port = 32768
to_port = 65535
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
]
public_inbound = [
{
rule_number = 100
rule_action = "allow"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 110
rule_action = "allow"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 120
rule_action = "allow"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 130
rule_action = "allow"
from_port = 3389
to_port = 3389
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
]
public_outbound = [
{
rule_number = 100
rule_action = "allow"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 110
rule_action = "allow"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 120
rule_action = "allow"
from_port = 1433
to_port = 1433
protocol = "tcp"
cidr_block = "10.0.100.0/22"
},
{
rule_number = 130
rule_action = "allow"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_block = "10.0.100.0/22"
},
]
}
}
# VPC
output "vpc_id" {
description = "The ID of the VPC"
value = "${module.vpc.vpc_id}"
}
# CIDR blocks
output "vpc_cidr_block" {
description = "The CIDR block of the VPC"
value = ["${module.vpc.vpc_cidr_block}"]
}
//output "vpc_ipv6_cidr_block" {
// description = "The IPv6 CIDR block"
// value = ["${module.vpc.vpc_ipv6_cidr_block}"]
//}
# Subnets
output "private_subnets" {
description = "List of IDs of private subnets"
value = ["${module.vpc.private_subnets}"]
}
output "public_subnets" {
description = "List of IDs of public subnets"
value = ["${module.vpc.public_subnets}"]
}
# NAT gateways
output "nat_public_ips" {
description = "List of public Elastic IPs created for AWS NAT Gateway"
value = ["${module.vpc.nat_public_ips}"]
}
# Network ACLs
output "public_network_acl_id" {
description = "ID of the public network ACL"
value = "${module.vpc.public_network_acl_id}"
}
output "private_network_acl_id" {
description = "ID of the private network ACL"
value = "${module.vpc.private_network_acl_id}"
}
output "elasticache_network_acl_id" {
description = "ID of the elasticache network ACL"
value = "${module.vpc.elasticache_network_acl_id}"
}
output "default_network_acl_id" {
description = "The ID of the default network ACL"
value = "${module.vpc.default_network_acl_id}"
}
This diff is collapsed.
...@@ -258,6 +258,36 @@ output "default_vpc_main_route_table_id" { ...@@ -258,6 +258,36 @@ output "default_vpc_main_route_table_id" {
// value = "${element(concat(aws_default_vpc.this.*.ipv6_cidr_block, list("")), 0)}" // value = "${element(concat(aws_default_vpc.this.*.ipv6_cidr_block, list("")), 0)}"
//} //}
output "public_network_acl_id" {
description = "ID of the public network ACL"
value = "${element(concat(aws_network_acl.public.*.id, list("")), 0)}"
}
output "private_network_acl_id" {
description = "ID of the private network ACL"
value = "${element(concat(aws_network_acl.private.*.id, list("")), 0)}"
}
output "intra_network_acl_id" {
description = "ID of the intra network ACL"
value = "${element(concat(aws_network_acl.intra.*.id, list("")), 0)}"
}
output "database_network_acl_id" {
description = "ID of the database network ACL"
value = "${element(concat(aws_network_acl.database.*.id, list("")), 0)}"
}
output "redshift_network_acl_id" {
description = "ID of the redshift network ACL"
value = "${element(concat(aws_network_acl.redshift.*.id, list("")), 0)}"
}
output "elasticache_network_acl_id" {
description = "ID of the elasticache network ACL"
value = "${element(concat(aws_network_acl.elasticache.*.id, list("")), 0)}"
}
# VPC Endpoints # VPC Endpoints
output "vpc_endpoint_s3_id" { output "vpc_endpoint_s3_id" {
description = "The ID of VPC endpoint for S3" description = "The ID of VPC endpoint for S3"
......
...@@ -443,6 +443,36 @@ variable "intra_subnet_tags" { ...@@ -443,6 +443,36 @@ variable "intra_subnet_tags" {
default = {} default = {}
} }
variable "public_acl_tags" {
description = "Additional tags for the public subnets network ACL"
default = {}
}
variable "private_acl_tags" {
description = "Additional tags for the private subnets network ACL"
default = {}
}
variable "intra_acl_tags" {
description = "Additional tags for the intra subnets network ACL"
default = {}
}
variable "database_acl_tags" {
description = "Additional tags for the database subnets network ACL"
default = {}
}
variable "redshift_acl_tags" {
description = "Additional tags for the redshift subnets network ACL"
default = {}
}
variable "elasticache_acl_tags" {
description = "Additional tags for the elasticache subnets network ACL"
default = {}
}
variable "dhcp_options_tags" { variable "dhcp_options_tags" {
description = "Additional tags for the DHCP option set" description = "Additional tags for the DHCP option set"
default = {} default = {}
...@@ -525,3 +555,272 @@ variable "default_vpc_tags" { ...@@ -525,3 +555,272 @@ variable "default_vpc_tags" {
description = "Additional tags for the Default VPC" description = "Additional tags for the Default VPC"
default = {} default = {}
} }
variable "manage_default_network_acl" {
description = "Should be true to adopt and manage Default Network ACL"
default = false
}
variable "default_network_acl_name" {
description = "Name to be used on the Default Network ACL"
default = ""
}
variable "default_network_acl_tags" {
description = "Additional tags for the Default Network ACL"
default = {}
}
variable "public_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for public subnets"
default = false
}
variable "private_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for private subnets"
default = false
}
variable "intra_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for intra subnets"
default = false
}
variable "database_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for database subnets"
default = false
}
variable "redshift_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for redshift subnets"
default = false
}
variable "elasticache_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for elasticache subnets"
default = false
}
variable "default_network_acl_ingress" {
description = "List of maps of ingress rules to set on the Default Network ACL"
default = [{
rule_no = 100
action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
{
rule_no = 101
action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
ipv6_cidr_block = "::/0"
},
]
}
variable "default_network_acl_egress" {
description = "List of maps of egress rules to set on the Default Network ACL"
default = [{
rule_no = 100
action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
{
rule_no = 101
action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
ipv6_cidr_block = "::/0"
},
]
}
variable "public_inbound_acl_rules" {
description = "Public subnets inbound network ACLs"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "public_outbound_acl_rules" {
description = "Public subnets outbound network ACLs"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "private_inbound_acl_rules" {
description = "Private subnets inbound network ACLs"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "private_outbound_acl_rules" {
description = "Private subnets outbound network ACLs"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "intra_inbound_acl_rules" {
description = "Intra subnets inbound network ACLs"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "intra_outbound_acl_rules" {
description = "Intra subnets outbound network ACLs"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "database_inbound_acl_rules" {
description = "Database subnets inbound network ACL rules"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "database_outbound_acl_rules" {
description = "Database subnets outbound network ACL rules"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "redshift_inbound_acl_rules" {
description = "Redshift subnets inbound network ACL rules"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "redshift_outbound_acl_rules" {
description = "Redshift subnets outbound network ACL rules"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "elasticache_inbound_acl_rules" {
description = "Elasticache subnets inbound network ACL rules"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "elasticache_outbound_acl_rules" {
description = "Elasticache subnets outbound network ACL rules"
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment