Skip to content

Commit be962ae

Browse files
authored
Add IPv6 support (terraform-aws-modules#317)
* IPv6 support Add variable "enable_ipv6" to allow enabling IPv6 support (resulting in passing "assign_generated_ipv6_cidr_block" to aws_vpc. Enabling IPv6 support further results in an Egress-only internet gateway being provisioned and routing tables of subnets being adjusted. Additional variables allow to choose the indices out of the /64 subnets based on the assigned /56 range. * Add example for IPv6 usage * Remove redundant parameter assign_generated_ipv6_cidr_block This is needed exactly when var.enable_ipv6 is true. * Set subnet ipv6_cidr_block to null if unused * Be picky about spelling * Revert unrelated change * More IPv6 spelling * Added IPv6 support to VPC module * Added IPv6 support to VPC module
1 parent 40821bb commit be962ae

File tree

10 files changed

+324
-54
lines changed

10 files changed

+324
-54
lines changed

README.md

Lines changed: 26 additions & 2 deletions
Large diffs are not rendered by default.

examples/ipv6/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# VPC with IPv6 enabled
2+
3+
Configuration in this directory creates set of VPC resources with IPv6 enabled on VPC and subnets.
4+
5+
## Usage
6+
7+
To run this example you need to execute:
8+
9+
```bash
10+
$ terraform init
11+
$ terraform plan
12+
$ terraform apply
13+
```
14+
15+
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.
16+
17+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
18+
## Outputs
19+
20+
| Name | Description |
21+
|------|-------------|
22+
| ipv6\_association\_id | The IPv6 CIDR block |
23+
| ipv6\_cidr\_block | The association ID for the IPv6 CIDR block |
24+
| vpc\_id | The ID of the VPC |
25+
26+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/ipv6/main.tf

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
provider "aws" {
2+
region = "eu-west-1"
3+
}
4+
5+
data "aws_availability_zones" "available" {}
6+
7+
module "vpc" {
8+
source = "../.."
9+
10+
name = "ipv6"
11+
12+
cidr = "10.0.0.0/16"
13+
14+
azs = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]]
15+
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
16+
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
17+
database_subnets = ["10.0.103.0/24", "10.0.104.0/24"]
18+
19+
enable_nat_gateway = false
20+
21+
create_database_subnet_route_table = true
22+
create_database_internet_gateway_route = true
23+
24+
enable_ipv6 = true
25+
assign_ipv6_address_on_creation = true
26+
27+
private_subnet_assign_ipv6_address_on_creation = false
28+
29+
public_subnet_ipv6_prefixes = [0, 1]
30+
private_subnet_ipv6_prefixes = [2, 3]
31+
database_subnet_ipv6_prefixes = [4, 5]
32+
33+
tags = {
34+
Owner = "user"
35+
Environment = "dev"
36+
}
37+
}

examples/ipv6/outputs.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# VPC
2+
output "vpc_id" {
3+
description = "The ID of the VPC"
4+
value = module.vpc.vpc_id
5+
}
6+
7+
output "ipv6_association_id" {
8+
description = "The IPv6 CIDR block"
9+
value = module.vpc.vpc_ipv6_cidr_block
10+
}
11+
12+
output "ipv6_cidr_block" {
13+
description = "The association ID for the IPv6 CIDR block"
14+
value = module.vpc.vpc_ipv6_association_id
15+
}

examples/network-acls/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module "vpc" {
2626

2727
private_dedicated_network_acl = true
2828

29-
assign_generated_ipv6_cidr_block = true
29+
enable_ipv6 = true
3030

3131
enable_nat_gateway = false
3232
single_nat_gateway = true

examples/secondary-cidr-blocks/main.tf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ module "vpc" {
1414
private_subnets = ["10.0.1.0/24", "10.1.2.0/24", "10.2.3.0/24"]
1515
public_subnets = ["10.0.101.0/24", "10.1.102.0/24", "10.2.103.0/24"]
1616

17-
assign_generated_ipv6_cidr_block = true
18-
enable_nat_gateway = true
19-
single_nat_gateway = true
17+
enable_ipv6 = true
18+
19+
enable_nat_gateway = true
20+
single_nat_gateway = true
2021

2122
public_subnet_tags = {
2223
Name = "overridden-name-public"

examples/simple-vpc/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module "vpc" {
1818
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
1919
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
2020

21-
assign_generated_ipv6_cidr_block = true
21+
enable_ipv6 = true
2222

2323
enable_nat_gateway = true
2424
single_nat_gateway = true

main.tf

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ resource "aws_vpc" "this" {
2828
instance_tenancy = var.instance_tenancy
2929
enable_dns_hostnames = var.enable_dns_hostnames
3030
enable_dns_support = var.enable_dns_support
31-
assign_generated_ipv6_cidr_block = var.assign_generated_ipv6_cidr_block
31+
assign_generated_ipv6_cidr_block = var.enable_ipv6
3232

3333
tags = merge(
3434
{
@@ -95,6 +95,12 @@ resource "aws_internet_gateway" "this" {
9595
)
9696
}
9797

98+
resource "aws_egress_only_internet_gateway" "this" {
99+
count = var.create_vpc && var.enable_ipv6 && local.max_subnet_length > 0 ? 1 : 0
100+
101+
vpc_id = local.vpc_id
102+
}
103+
98104
################
99105
# Publiс routes
100106
################
@@ -124,6 +130,14 @@ resource "aws_route" "public_internet_gateway" {
124130
}
125131
}
126132

133+
resource "aws_route" "public_internet_gateway_ipv6" {
134+
count = var.create_vpc && var.enable_ipv6 && length(var.public_subnets) > 0 ? 1 : 0
135+
136+
route_table_id = aws_route_table.public[0].id
137+
destination_ipv6_cidr_block = "::/0"
138+
gateway_id = aws_internet_gateway.this[0].id
139+
}
140+
127141
#################
128142
# Private routes
129143
# There are as many routing tables as the number of NAT gateways
@@ -193,6 +207,18 @@ resource "aws_route" "database_nat_gateway" {
193207
}
194208
}
195209

210+
resource "aws_route" "database_ipv6_egress" {
211+
count = var.create_vpc && var.enable_ipv6 && var.create_database_subnet_route_table && length(var.database_subnets) > 0 && var.create_database_internet_gateway_route ? 1 : 0
212+
213+
route_table_id = aws_route_table.database[0].id
214+
destination_ipv6_cidr_block = "::/0"
215+
egress_only_gateway_id = aws_egress_only_internet_gateway.this[0].id
216+
217+
timeouts {
218+
create = "5m"
219+
}
220+
}
221+
196222
#################
197223
# Redshift routes
198224
#################
@@ -250,10 +276,13 @@ resource "aws_route_table" "intra" {
250276
resource "aws_subnet" "public" {
251277
count = var.create_vpc && length(var.public_subnets) > 0 && (false == var.one_nat_gateway_per_az || length(var.public_subnets) >= length(var.azs)) ? length(var.public_subnets) : 0
252278

253-
vpc_id = local.vpc_id
254-
cidr_block = element(concat(var.public_subnets, [""]), count.index)
255-
availability_zone = element(var.azs, count.index)
256-
map_public_ip_on_launch = var.map_public_ip_on_launch
279+
vpc_id = local.vpc_id
280+
cidr_block = element(concat(var.public_subnets, [""]), count.index)
281+
availability_zone = element(var.azs, count.index)
282+
map_public_ip_on_launch = var.map_public_ip_on_launch
283+
assign_ipv6_address_on_creation = var.public_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.public_subnet_assign_ipv6_address_on_creation
284+
285+
ipv6_cidr_block = var.enable_ipv6 && length(var.public_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.public_subnet_ipv6_prefixes[count.index]) : null
257286

258287
tags = merge(
259288
{
@@ -274,9 +303,12 @@ resource "aws_subnet" "public" {
274303
resource "aws_subnet" "private" {
275304
count = var.create_vpc && length(var.private_subnets) > 0 ? length(var.private_subnets) : 0
276305

277-
vpc_id = local.vpc_id
278-
cidr_block = var.private_subnets[count.index]
279-
availability_zone = element(var.azs, count.index)
306+
vpc_id = local.vpc_id
307+
cidr_block = var.private_subnets[count.index]
308+
availability_zone = element(var.azs, count.index)
309+
assign_ipv6_address_on_creation = var.private_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.private_subnet_assign_ipv6_address_on_creation
310+
311+
ipv6_cidr_block = var.enable_ipv6 && length(var.private_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.private_subnet_ipv6_prefixes[count.index]) : null
280312

281313
tags = merge(
282314
{
@@ -297,9 +329,12 @@ resource "aws_subnet" "private" {
297329
resource "aws_subnet" "database" {
298330
count = var.create_vpc && length(var.database_subnets) > 0 ? length(var.database_subnets) : 0
299331

300-
vpc_id = local.vpc_id
301-
cidr_block = var.database_subnets[count.index]
302-
availability_zone = element(var.azs, count.index)
332+
vpc_id = local.vpc_id
333+
cidr_block = var.database_subnets[count.index]
334+
availability_zone = element(var.azs, count.index)
335+
assign_ipv6_address_on_creation = var.database_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.database_subnet_assign_ipv6_address_on_creation
336+
337+
ipv6_cidr_block = var.enable_ipv6 && length(var.database_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.database_subnet_ipv6_prefixes[count.index]) : null
303338

304339
tags = merge(
305340
{
@@ -336,9 +371,12 @@ resource "aws_db_subnet_group" "database" {
336371
resource "aws_subnet" "redshift" {
337372
count = var.create_vpc && length(var.redshift_subnets) > 0 ? length(var.redshift_subnets) : 0
338373

339-
vpc_id = local.vpc_id
340-
cidr_block = var.redshift_subnets[count.index]
341-
availability_zone = element(var.azs, count.index)
374+
vpc_id = local.vpc_id
375+
cidr_block = var.redshift_subnets[count.index]
376+
availability_zone = element(var.azs, count.index)
377+
assign_ipv6_address_on_creation = var.redshift_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.redshift_subnet_assign_ipv6_address_on_creation
378+
379+
ipv6_cidr_block = var.enable_ipv6 && length(var.redshift_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.redshift_subnet_ipv6_prefixes[count.index]) : null
342380

343381
tags = merge(
344382
{
@@ -375,9 +413,12 @@ resource "aws_redshift_subnet_group" "redshift" {
375413
resource "aws_subnet" "elasticache" {
376414
count = var.create_vpc && length(var.elasticache_subnets) > 0 ? length(var.elasticache_subnets) : 0
377415

378-
vpc_id = local.vpc_id
379-
cidr_block = var.elasticache_subnets[count.index]
380-
availability_zone = element(var.azs, count.index)
416+
vpc_id = local.vpc_id
417+
cidr_block = var.elasticache_subnets[count.index]
418+
availability_zone = element(var.azs, count.index)
419+
assign_ipv6_address_on_creation = var.elasticache_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.elasticache_subnet_assign_ipv6_address_on_creation
420+
421+
ipv6_cidr_block = var.enable_ipv6 && length(var.elasticache_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.elasticache_subnet_ipv6_prefixes[count.index]) : null
381422

382423
tags = merge(
383424
{
@@ -406,9 +447,12 @@ resource "aws_elasticache_subnet_group" "elasticache" {
406447
resource "aws_subnet" "intra" {
407448
count = var.create_vpc && length(var.intra_subnets) > 0 ? length(var.intra_subnets) : 0
408449

409-
vpc_id = local.vpc_id
410-
cidr_block = var.intra_subnets[count.index]
411-
availability_zone = element(var.azs, count.index)
450+
vpc_id = local.vpc_id
451+
cidr_block = var.intra_subnets[count.index]
452+
availability_zone = element(var.azs, count.index)
453+
assign_ipv6_address_on_creation = var.intra_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.intra_subnet_assign_ipv6_address_on_creation
454+
455+
ipv6_cidr_block = var.enable_ipv6 && length(var.intra_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.intra_subnet_ipv6_prefixes[count.index]) : null
412456

413457
tags = merge(
414458
{
@@ -824,6 +868,14 @@ resource "aws_route" "private_nat_gateway" {
824868
}
825869
}
826870

871+
resource "aws_route" "private_ipv6_egress" {
872+
count = var.enable_ipv6 ? length(var.private_subnets) : 0
873+
874+
route_table_id = element(aws_route_table.private.*.id, count.index)
875+
destination_ipv6_cidr_block = "::/0"
876+
egress_only_gateway_id = element(aws_egress_only_internet_gateway.this.*.id, 0)
877+
}
878+
827879
######################
828880
# VPC Endpoint for S3
829881
######################

0 commit comments

Comments
 (0)