Skip to content

Commit 65b893a

Browse files
authored
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
1 parent b5b23cd commit 65b893a

File tree

7 files changed

+862
-0
lines changed

7 files changed

+862
-0
lines changed

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ These types of resources are supported:
1111
* [Route](https://www.terraform.io/docs/providers/aws/r/route.html)
1212
* [Route table](https://www.terraform.io/docs/providers/aws/r/route_table.html)
1313
* [Internet Gateway](https://www.terraform.io/docs/providers/aws/r/internet_gateway.html)
14+
* [Network ACL](https://www.terraform.io/docs/providers/aws/r/network_acl.html)
1415
* [NAT Gateway](https://www.terraform.io/docs/providers/aws/r/nat_gateway.html)
1516
* [VPN Gateway](https://www.terraform.io/docs/providers/aws/r/vpn_gateway.html)
1617
* [VPC Endpoint](https://www.terraform.io/docs/providers/aws/r/vpc_endpoint.html):
@@ -21,6 +22,7 @@ These types of resources are supported:
2122
* [Redshift Subnet Group](https://www.terraform.io/docs/providers/aws/r/redshift_subnet_group.html)
2223
* [DHCP Options Set](https://www.terraform.io/docs/providers/aws/r/vpc_dhcp_options.html)
2324
* [Default VPC](https://www.terraform.io/docs/providers/aws/r/default_vpc.html)
25+
* [Default Network ACL](https://www.terraform.io/docs/providers/aws/r/default_network_acl.html)
2426

2527
Sponsored by [Cloudcraft - the best way to draw AWS diagrams](https://cloudcraft.co/?utm_source=terraform-aws-vpc)
2628

@@ -165,6 +167,14 @@ Sometimes it is handy to have public access to RDS instances (it is not recommen
165167
enable_dns_support = true
166168
```
167169

170+
## Network Access Control Lists (ACL or NACL)
171+
172+
This module can manage network ACL and rules. Once VPC is created, AWS creates the default network ACL, which can be controlled using this module (`manage_default_network_acl = true`).
173+
174+
Also, each type of subnet may have its own network ACL with custom rules per subnet. Eg, set `public_dedicated_network_acl = true` to use dedicated network ACL for the public subnets; set values of `public_inbound_acl_rules` and `public_outbound_acl_rules` to specify all the NACL rules you need to have on public subnets (see `variables.tf` for default values and structures).
175+
176+
By default, all subnets are associated with the default network ACL.
177+
168178
## Public access to Redshift cluster
169179

170180
Sometimes it is handy to have public access to Redshift clusters (for example if you need to access it by Kinesis - VPC endpoint for Kinesis is not yet supported by Redshift) by specifying these arguments:
@@ -182,6 +192,7 @@ Terraform version 0.10.3 or newer is required for this module to work.
182192
* [Simple VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/simple-vpc)
183193
* [Complete VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/complete-vpc)
184194
* [Manage Default VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/manage-default-vpc)
195+
* [Network ACL](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/network-acls)
185196
* Few tests and edge cases examples: [#46](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/issue-46-no-private-subnets), [#44](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/issue-44-asymmetric-private-subnets), [#108](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/issue-108-route-already-exists)
186197

187198
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
@@ -205,11 +216,19 @@ Terraform version 0.10.3 or newer is required for this module to work.
205216
| create\_redshift\_subnet\_group | Controls if redshift subnet group should be created | string | `"true"` | no |
206217
| create\_redshift\_subnet\_route\_table | Controls if separate route table for redshift should be created | string | `"false"` | no |
207218
| create\_vpc | Controls if VPC should be created (it affects almost all resources) | string | `"true"` | no |
219+
| database\_acl\_tags | Additional tags for the database subnets network ACL | map | `{}` | no |
220+
| database\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for database subnets | string | `"false"` | no |
221+
| database\_inbound\_acl\_rules | Database subnets inbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
222+
| database\_outbound\_acl\_rules | Database subnets outbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
208223
| database\_route\_table\_tags | Additional tags for the database route tables | map | `{}` | no |
209224
| database\_subnet\_group\_tags | Additional tags for the database subnet group | map | `{}` | no |
210225
| database\_subnet\_suffix | Suffix to append to database subnets name | string | `"db"` | no |
211226
| database\_subnet\_tags | Additional tags for the database subnets | map | `{}` | no |
212227
| database\_subnets | A list of database subnets | list | `[]` | no |
228+
| default\_network\_acl\_egress | List of maps of egress rules to set on the Default Network ACL | list | `[ { "action": "allow", "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_no": 100, "to_port": 0 }, { "action": "allow", "from_port": 0, "ipv6_cidr_block": "::/0", "protocol": "-1", "rule_no": 101, "to_port": 0 } ]` | no |
229+
| default\_network\_acl\_ingress | List of maps of ingress rules to set on the Default Network ACL | list | `[ { "action": "allow", "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_no": 100, "to_port": 0 }, { "action": "allow", "from_port": 0, "ipv6_cidr_block": "::/0", "protocol": "-1", "rule_no": 101, "to_port": 0 } ]` | no |
230+
| default\_network\_acl\_name | Name to be used on the Default Network ACL | string | `""` | no |
231+
| default\_network\_acl\_tags | Additional tags for the Default Network ACL | map | `{}` | no |
213232
| default\_vpc\_enable\_classiclink | Should be true to enable ClassicLink in the Default VPC | string | `"false"` | no |
214233
| default\_vpc\_enable\_dns\_hostnames | Should be true to enable DNS hostnames in the Default VPC | string | `"false"` | no |
215234
| default\_vpc\_enable\_dns\_support | Should be true to enable DNS support in the Default VPC | string | `"true"` | no |
@@ -233,6 +252,10 @@ Terraform version 0.10.3 or newer is required for this module to work.
233252
| ecr\_dkr\_endpoint\_private\_dns\_enabled | Whether or not to associate a private hosted zone with the specified VPC for ECR DKR endpoint | string | `"false"` | no |
234253
| ecr\_dkr\_endpoint\_security\_group\_ids | The ID of one or more security groups to associate with the network interface for ECR DKR endpoint | list | `[]` | no |
235254
| ecr\_dkr\_endpoint\_subnet\_ids | The ID of one or more subnets in which to create a network interface for ECR dkr endpoint. If omitted, private subnets will be used. | list | `[]` | no |
255+
| elasticache\_acl\_tags | Additional tags for the elasticache subnets network ACL | map | `{}` | no |
256+
| elasticache\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for elasticache subnets | string | `"false"` | no |
257+
| elasticache\_inbound\_acl\_rules | Elasticache subnets inbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
258+
| elasticache\_outbound\_acl\_rules | Elasticache subnets outbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
236259
| elasticache\_route\_table\_tags | Additional tags for the elasticache route tables | map | `{}` | no |
237260
| elasticache\_subnet\_suffix | Suffix to append to elasticache subnets name | string | `"elasticache"` | no |
238261
| elasticache\_subnet\_tags | Additional tags for the elasticache subnets | map | `{}` | no |
@@ -255,26 +278,43 @@ Terraform version 0.10.3 or newer is required for this module to work.
255278
| external\_nat\_ip\_ids | List of EIP IDs to be assigned to the NAT Gateways (used in combination with reuse_nat_ips) | list | `[]` | no |
256279
| igw\_tags | Additional tags for the internet gateway | map | `{}` | no |
257280
| instance\_tenancy | A tenancy option for instances launched into the VPC | string | `"default"` | no |
281+
| intra\_acl\_tags | Additional tags for the intra subnets network ACL | map | `{}` | no |
282+
| intra\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for intra subnets | string | `"false"` | no |
283+
| intra\_inbound\_acl\_rules | Intra subnets inbound network ACLs | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
284+
| intra\_outbound\_acl\_rules | Intra subnets outbound network ACLs | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
258285
| intra\_route\_table\_tags | Additional tags for the intra route tables | map | `{}` | no |
259286
| intra\_subnet\_suffix | Suffix to append to intra subnets name | string | `"intra"` | no |
260287
| intra\_subnet\_tags | Additional tags for the intra subnets | map | `{}` | no |
261288
| intra\_subnets | A list of intra subnets | list | `[]` | no |
289+
| manage\_default\_network\_acl | Should be true to adopt and manage Default Network ACL | string | `"false"` | no |
262290
| manage\_default\_vpc | Should be true to adopt and manage Default VPC | string | `"false"` | no |
263291
| map\_public\_ip\_on\_launch | Should be false if you do not want to auto-assign public IP on launch | string | `"true"` | no |
264292
| name | Name to be used on all the resources as identifier | string | `""` | no |
265293
| nat\_eip\_tags | Additional tags for the NAT EIP | map | `{}` | no |
266294
| nat\_gateway\_tags | Additional tags for the NAT gateways | map | `{}` | no |
267295
| one\_nat\_gateway\_per\_az | Should be true if you want only one NAT Gateway per availability zone. Requires `var.azs` to be set, and the number of `public_subnets` created to be greater than or equal to the number of availability zones specified in `var.azs`. | string | `"false"` | no |
296+
| private\_acl\_tags | Additional tags for the private subnets network ACL | map | `{}` | no |
297+
| private\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for private subnets | string | `"false"` | no |
298+
| private\_inbound\_acl\_rules | Private subnets inbound network ACLs | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
299+
| private\_outbound\_acl\_rules | Private subnets outbound network ACLs | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
268300
| private\_route\_table\_tags | Additional tags for the private route tables | map | `{}` | no |
269301
| private\_subnet\_suffix | Suffix to append to private subnets name | string | `"private"` | no |
270302
| private\_subnet\_tags | Additional tags for the private subnets | map | `{}` | no |
271303
| private\_subnets | A list of private subnets inside the VPC | list | `[]` | no |
272304
| propagate\_private\_route\_tables\_vgw | Should be true if you want route table propagation | string | `"false"` | no |
273305
| propagate\_public\_route\_tables\_vgw | Should be true if you want route table propagation | string | `"false"` | no |
306+
| public\_acl\_tags | Additional tags for the public subnets network ACL | map | `{}` | no |
307+
| public\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for public subnets | string | `"false"` | no |
308+
| public\_inbound\_acl\_rules | Public subnets inbound network ACLs | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
309+
| public\_outbound\_acl\_rules | Public subnets outbound network ACLs | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
274310
| public\_route\_table\_tags | Additional tags for the public route tables | map | `{}` | no |
275311
| public\_subnet\_suffix | Suffix to append to public subnets name | string | `"public"` | no |
276312
| public\_subnet\_tags | Additional tags for the public subnets | map | `{}` | no |
277313
| public\_subnets | A list of public subnets inside the VPC | list | `[]` | no |
314+
| redshift\_acl\_tags | Additional tags for the redshift subnets network ACL | map | `{}` | no |
315+
| redshift\_dedicated\_network\_acl | Whether to use dedicated network ACL (not default) and custom rules for redshift subnets | string | `"false"` | no |
316+
| redshift\_inbound\_acl\_rules | Redshift subnets inbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
317+
| redshift\_outbound\_acl\_rules | Redshift subnets outbound network ACL rules | list | `[ { "cidr_block": "0.0.0.0/0", "from_port": 0, "protocol": "-1", "rule_action": "allow", "rule_number": 100, "to_port": 0 } ]` | no |
278318
| redshift\_route\_table\_tags | Additional tags for the redshift route tables | map | `{}` | no |
279319
| redshift\_subnet\_group\_tags | Additional tags for the redshift subnet group | map | `{}` | no |
280320
| redshift\_subnet\_suffix | Suffix to append to redshift subnets name | string | `"redshift"` | no |
@@ -299,6 +339,7 @@ Terraform version 0.10.3 or newer is required for this module to work.
299339
| Name | Description |
300340
|------|-------------|
301341
| azs | A list of availability zones specified as argument to this module |
342+
| database\_network\_acl\_id | ID of the database network ACL |
302343
| database\_route\_table\_ids | List of IDs of database route tables |
303344
| database\_subnet\_group | ID of database subnet group |
304345
| database\_subnets | List of IDs of database subnets |
@@ -315,24 +356,29 @@ Terraform version 0.10.3 or newer is required for this module to work.
315356
| default\_vpc\_id | The ID of the VPC |
316357
| default\_vpc\_instance\_tenancy | Tenancy of instances spin up within VPC |
317358
| default\_vpc\_main\_route\_table\_id | The ID of the main route table associated with this VPC |
359+
| elasticache\_network\_acl\_id | ID of the elasticache network ACL |
318360
| elasticache\_route\_table\_ids | List of IDs of elasticache route tables |
319361
| elasticache\_subnet\_group | ID of elasticache subnet group |
320362
| elasticache\_subnet\_group\_name | Name of elasticache subnet group |
321363
| elasticache\_subnets | List of IDs of elasticache subnets |
322364
| elasticache\_subnets\_cidr\_blocks | List of cidr_blocks of elasticache subnets |
323365
| igw\_id | The ID of the Internet Gateway |
366+
| intra\_network\_acl\_id | ID of the intra network ACL |
324367
| intra\_route\_table\_ids | List of IDs of intra route tables |
325368
| intra\_subnets | List of IDs of intra subnets |
326369
| intra\_subnets\_cidr\_blocks | List of cidr_blocks of intra subnets |
327370
| nat\_ids | List of allocation ID of Elastic IPs created for AWS NAT Gateway |
328371
| nat\_public\_ips | List of public Elastic IPs created for AWS NAT Gateway |
329372
| natgw\_ids | List of NAT Gateway IDs |
373+
| private\_network\_acl\_id | ID of the private network ACL |
330374
| private\_route\_table\_ids | List of IDs of private route tables |
331375
| private\_subnets | List of IDs of private subnets |
332376
| private\_subnets\_cidr\_blocks | List of cidr_blocks of private subnets |
377+
| public\_network\_acl\_id | ID of the public network ACL |
333378
| public\_route\_table\_ids | List of IDs of public route tables |
334379
| public\_subnets | List of IDs of public subnets |
335380
| public\_subnets\_cidr\_blocks | List of cidr_blocks of public subnets |
381+
| redshift\_network\_acl\_id | ID of the redshift network ACL |
336382
| redshift\_route\_table\_ids | List of IDs of redshift route tables |
337383
| redshift\_subnet\_group | ID of redshift subnet group |
338384
| redshift\_subnets | List of IDs of redshift subnets |

examples/network-acls/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Simple VPC with Network ACLs
2+
3+
Configuration in this directory creates set of VPC resources along with network ACLs for public subnets.
4+
5+
There is a public and private subnet created per availability zone in addition to single NAT Gateway shared between all 3 availability zones.
6+
7+
Network ACL rules for inbound and outbound traffic are defined as the following:
8+
1. Public subnets will have network ACL rules provided
9+
1. Private subnets will be associated with the default network ACL rules (IPV4-only ingress and egress is open for all)
10+
1. Elasticache subnets will use the default network ACL (created and managed by AWS)
11+
12+
## Usage
13+
14+
To run this example you need to execute:
15+
16+
```bash
17+
$ terraform init
18+
$ terraform plan
19+
$ terraform apply
20+
```
21+
22+
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.
23+
24+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
25+
## Outputs
26+
27+
| Name | Description |
28+
|------|-------------|
29+
| default\_network\_acl\_id | The ID of the default network ACL |
30+
| elasticache\_network\_acl\_id | ID of the elasticache network ACL |
31+
| nat\_public\_ips | List of public Elastic IPs created for AWS NAT Gateway |
32+
| private\_network\_acl\_id | ID of the private network ACL |
33+
| private\_subnets | List of IDs of private subnets |
34+
| public\_network\_acl\_id | ID of the public network ACL |
35+
| public\_subnets | List of IDs of public subnets |
36+
| vpc\_cidr\_block | The CIDR block of the VPC |
37+
| vpc\_id | The ID of the VPC |
38+
39+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

0 commit comments

Comments
 (0)