From 4fe7745ddb675af3bd50daf335ad3ffa16d08a98 Mon Sep 17 00:00:00 2001 From: drewmullen Date: Mon, 26 Sep 2022 10:48:40 -0400 Subject: [PATCH] feat: Add IPAM IPv6 support (#718) Co-authored-by: Bryant Biggs --- README.md | 7 +- examples/ipam-vpc/README.md | 4 +- examples/ipam-vpc/main.tf | 89 +++++++++++++-- examples/ipam-vpc/outputs.tf | 214 +++++++++++++++++------------------ main.tf | 23 ++-- variables.tf | 32 +++++- 6 files changed, 239 insertions(+), 130 deletions(-) diff --git a/README.md b/README.md index 0e1bc949f..77406accd 100644 --- a/README.md +++ b/README.md @@ -355,7 +355,7 @@ No modules. | [amazon\_side\_asn](#input\_amazon\_side\_asn) | The Autonomous System Number (ASN) for the Amazon side of the gateway. By default the virtual private gateway is created with the current default Amazon ASN. | `string` | `"64512"` | no | | [assign\_ipv6\_address\_on\_creation](#input\_assign\_ipv6\_address\_on\_creation) | Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map\_public\_ip\_on\_launch | `bool` | `false` | no | | [azs](#input\_azs) | A list of availability zones names or ids in the region | `list(string)` | `[]` | no | -| [cidr](#input\_cidr) | (Optional) The IPv4 CIDR block for the VPC. | `string` | `"0.0.0.0/0"` | no | +| [cidr](#input\_cidr) | (Optional) The IPv4 CIDR block for the VPC. CIDR can be explicitly set or it can be derived from IPAM using `ipv4_netmask_length` & `ipv4_ipam_pool_id` | `string` | `"0.0.0.0/0"` | no | | [create\_database\_internet\_gateway\_route](#input\_create\_database\_internet\_gateway\_route) | Controls if an internet gateway route for public database access should be created | `bool` | `false` | no | | [create\_database\_nat\_gateway\_route](#input\_create\_database\_nat\_gateway\_route) | Controls if a nat gateway route should be created to give internet access to the database subnets | `bool` | `false` | no | | [create\_database\_subnet\_group](#input\_create\_database\_subnet\_group) | Controls if database subnet group should be created (n.b. database\_subnets must also be set) | `bool` | `true` | no | @@ -455,6 +455,10 @@ No modules. | [intra\_subnet\_tags](#input\_intra\_subnet\_tags) | Additional tags for the intra subnets | `map(string)` | `{}` | no | | [intra\_subnets](#input\_intra\_subnets) | A list of intra subnets | `list(string)` | `[]` | no | | [ipv4\_ipam\_pool\_id](#input\_ipv4\_ipam\_pool\_id) | (Optional) The ID of an IPv4 IPAM pool you want to use for allocating this VPC's CIDR. | `string` | `null` | no | +| [ipv4\_netmask\_length](#input\_ipv4\_netmask\_length) | (Optional) The netmask length of the IPv4 CIDR you want to allocate to this VPC. Requires specifying a ipv4\_ipam\_pool\_id. | `number` | `null` | no | +| [ipv6\_cidr](#input\_ipv6\_cidr) | (Optional) IPv6 CIDR block to request from an IPAM Pool. Can be set explicitly or derived from IPAM using `ipv6_netmask_length`. | `string` | `null` | no | +| [ipv6\_ipam\_pool\_id](#input\_ipv6\_ipam\_pool\_id) | (Optional) IPAM Pool ID for a IPv6 pool. Conflicts with `assign_generated_ipv6_cidr_block`. | `string` | `null` | no | +| [ipv6\_netmask\_length](#input\_ipv6\_netmask\_length) | (Optional) Netmask length to request from IPAM Pool. Conflicts with `ipv6_cidr_block`. This can be omitted if IPAM pool as a `allocation_default_netmask_length` set. Valid values: `56`. | `number` | `null` | no | | [manage\_default\_network\_acl](#input\_manage\_default\_network\_acl) | Should be true to adopt and manage Default Network ACL | `bool` | `false` | no | | [manage\_default\_route\_table](#input\_manage\_default\_route\_table) | Should be true to manage default route table | `bool` | `false` | no | | [manage\_default\_security\_group](#input\_manage\_default\_security\_group) | Should be true to adopt and manage default security group | `bool` | `false` | no | @@ -516,6 +520,7 @@ No modules. | [secondary\_cidr\_blocks](#input\_secondary\_cidr\_blocks) | List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool | `list(string)` | `[]` | no | | [single\_nat\_gateway](#input\_single\_nat\_gateway) | Should be true if you want to provision a single shared NAT Gateway across all of your private networks | `bool` | `false` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [use\_ipam\_pool](#input\_use\_ipam\_pool) | Determines whether IPAM pool is used for CIDR allocation | `bool` | `false` | no | | [vpc\_flow\_log\_permissions\_boundary](#input\_vpc\_flow\_log\_permissions\_boundary) | The ARN of the Permissions Boundary for the VPC Flow Log IAM Role | `string` | `null` | no | | [vpc\_flow\_log\_tags](#input\_vpc\_flow\_log\_tags) | Additional tags for the VPC Flow Logs | `map(string)` | `{}` | no | | [vpc\_tags](#input\_vpc\_tags) | Additional tags for the VPC | `map(string)` | `{}` | no | diff --git a/examples/ipam-vpc/README.md b/examples/ipam-vpc/README.md index 3ce818a1f..78cf09ad4 100644 --- a/examples/ipam-vpc/README.md +++ b/examples/ipam-vpc/README.md @@ -42,13 +42,15 @@ Note that this example may create resources which can cost money (AWS Elastic IP | Name | Source | Version | |------|--------|---------| -| [vpc](#module\_vpc) | ../.. | n/a | +| [vpc\_ipam\_set\_cidr](#module\_vpc\_ipam\_set\_cidr) | ../.. | n/a | +| [vpc\_ipam\_set\_netmask](#module\_vpc\_ipam\_set\_netmask) | ../.. | n/a | ## Resources | Name | Type | |------|------| | [aws_vpc_ipam.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipam) | resource | +| [aws_vpc_ipam_pool.ipv6](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipam_pool) | resource | | [aws_vpc_ipam_pool.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipam_pool) | resource | | [aws_vpc_ipam_pool_cidr.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipam_pool_cidr) | resource | | [aws_vpc_ipam_preview_next_cidr.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipam_preview_next_cidr) | resource | diff --git a/examples/ipam-vpc/main.tf b/examples/ipam-vpc/main.tf index 9daadf2f0..898304583 100644 --- a/examples/ipam-vpc/main.tf +++ b/examples/ipam-vpc/main.tf @@ -6,7 +6,8 @@ locals { name = "ex-${replace(basename(path.cwd), "_", "-")}" region = "eu-west-1" - partition = cidrsubnets(aws_vpc_ipam_preview_next_cidr.this.cidr, 2, 2) + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + preview_partition = cidrsubnets(aws_vpc_ipam_preview_next_cidr.this.cidr, 2, 2, 2) tags = { Example = local.name @@ -19,21 +20,58 @@ locals { # VPC Module ################################################################################ -module "vpc" { +# IPv4 +module "vpc_ipam_set_netmask" { source = "../.." - name = local.name + name = "${local.name}-set-netmask" - private_subnets = cidrsubnets(local.partition[0], 2, 2) - public_subnets = cidrsubnets(local.partition[1], 2, 2) + use_ipam_pool = true + ipv4_ipam_pool_id = aws_vpc_ipam_pool.this.id + ipv4_netmask_length = 16 + azs = local.azs + private_subnets = cidrsubnets(local.preview_partition[0], 2, 2, 2) + public_subnets = cidrsubnets(local.preview_partition[1], 2, 2, 2) + + tags = local.tags + + depends_on = [ + aws_vpc_ipam_pool_cidr.this + ] +} + +module "vpc_ipam_set_cidr" { + source = "../.." + + name = "${local.name}-set-cidr" + + use_ipam_pool = true ipv4_ipam_pool_id = aws_vpc_ipam_pool.this.id - azs = ["${local.region}a", "${local.region}b"] - cidr = aws_vpc_ipam_preview_next_cidr.this.cidr + cidr = "10.1.0.0/16" + azs = local.azs + + private_subnets = ["10.1.1.0/24", "10.1.2.0/24", "10.1.3.0/24"] + public_subnets = ["10.1.11.0/24", "10.1.12.0/24", "10.1.13.0/24"] tags = local.tags } +# # IPv6 - Requires having a CIDR plus its message and signature (see below) +# module "vpc_ipv6_ipam_set_netmask" { +# source = "../.." + +# name = "${local.name}-ipv6-set-netmask" + +# use_ipam_pool = true +# ipv4_ipam_pool_id = aws_vpc_ipam_pool.this.id +# ipv6_ipam_pool_id = aws_vpc_ipam_pool.ipv6.id +# ipv6_netmask_length = 56 +# azs = local.azs + +# tags = local.tags +# } + ################################################################################ # Supporting Resources ################################################################################ @@ -56,25 +94,54 @@ resource "aws_vpc_ipam" "this" { operating_regions { region_name = local.region } + + tags = local.tags } +# IPv4 resource "aws_vpc_ipam_pool" "this" { + description = "IPv4 pool" address_family = "ipv4" ipam_scope_id = aws_vpc_ipam.this.private_default_scope_id locale = local.region - allocation_default_netmask_length = 24 + allocation_default_netmask_length = 16 + + tags = local.tags } resource "aws_vpc_ipam_pool_cidr" "this" { ipam_pool_id = aws_vpc_ipam_pool.this.id - cidr = "10.0.0.0/16" + cidr = "10.0.0.0/8" } resource "aws_vpc_ipam_preview_next_cidr" "this" { - ipam_pool_id = aws_vpc_ipam_pool.this.id - netmask_length = 20 + ipam_pool_id = aws_vpc_ipam_pool.this.id depends_on = [ aws_vpc_ipam_pool_cidr.this ] } + +# IPv6 +resource "aws_vpc_ipam_pool" "ipv6" { + description = "IPv6 pool" + address_family = "ipv6" + ipam_scope_id = aws_vpc_ipam.this.public_default_scope_id + locale = local.region + allocation_default_netmask_length = 56 + publicly_advertisable = false + aws_service = "ec2" + + tags = local.tags +} + +# # Requires having a CIDR plus its message and signature +# resource "aws_vpc_ipam_pool_cidr" "ipv6" { +# ipam_pool_id = aws_vpc_ipam_pool.ipv6.id +# cidr = var.ipv6_cidr + +# cidr_authorization_context { +# message = var.message +# signature = var.signature +# } +# } diff --git a/examples/ipam-vpc/outputs.tf b/examples/ipam-vpc/outputs.tf index 77f244a90..47ca2117c 100644 --- a/examples/ipam-vpc/outputs.tf +++ b/examples/ipam-vpc/outputs.tf @@ -1,535 +1,535 @@ output "vpc_id" { description = "The ID of the VPC" - value = module.vpc.vpc_id + value = module.vpc_ipam_set_netmask.vpc_id } output "vpc_arn" { description = "The ARN of the VPC" - value = module.vpc.vpc_arn + value = module.vpc_ipam_set_netmask.vpc_arn } output "vpc_cidr_block" { description = "The CIDR block of the VPC" - value = module.vpc.vpc_cidr_block + value = module.vpc_ipam_set_netmask.vpc_cidr_block } output "default_security_group_id" { description = "The ID of the security group created by default on VPC creation" - value = module.vpc.default_security_group_id + value = module.vpc_ipam_set_netmask.default_security_group_id } output "default_network_acl_id" { description = "The ID of the default network ACL" - value = module.vpc.default_network_acl_id + value = module.vpc_ipam_set_netmask.default_network_acl_id } output "default_route_table_id" { description = "The ID of the default route table" - value = module.vpc.default_route_table_id + value = module.vpc_ipam_set_netmask.default_route_table_id } output "vpc_instance_tenancy" { description = "Tenancy of instances spin up within VPC" - value = module.vpc.vpc_instance_tenancy + value = module.vpc_ipam_set_netmask.vpc_instance_tenancy } output "vpc_enable_dns_support" { description = "Whether or not the VPC has DNS support" - value = module.vpc.vpc_enable_dns_support + value = module.vpc_ipam_set_netmask.vpc_enable_dns_support } output "vpc_enable_dns_hostnames" { description = "Whether or not the VPC has DNS hostname support" - value = module.vpc.vpc_enable_dns_hostnames + value = module.vpc_ipam_set_netmask.vpc_enable_dns_hostnames } output "vpc_main_route_table_id" { description = "The ID of the main route table associated with this VPC" - value = module.vpc.vpc_main_route_table_id + value = module.vpc_ipam_set_netmask.vpc_main_route_table_id } output "vpc_ipv6_association_id" { description = "The association ID for the IPv6 CIDR block" - value = module.vpc.vpc_ipv6_association_id + value = module.vpc_ipam_set_netmask.vpc_ipv6_association_id } output "vpc_ipv6_cidr_block" { description = "The IPv6 CIDR block" - value = module.vpc.vpc_ipv6_cidr_block + value = module.vpc_ipam_set_netmask.vpc_ipv6_cidr_block } output "vpc_secondary_cidr_blocks" { description = "List of secondary CIDR blocks of the VPC" - value = module.vpc.vpc_secondary_cidr_blocks + value = module.vpc_ipam_set_netmask.vpc_secondary_cidr_blocks } output "vpc_owner_id" { description = "The ID of the AWS account that owns the VPC" - value = module.vpc.vpc_owner_id + value = module.vpc_ipam_set_netmask.vpc_owner_id } output "private_subnets" { description = "List of IDs of private subnets" - value = module.vpc.private_subnets + value = module.vpc_ipam_set_netmask.private_subnets } output "private_subnet_arns" { description = "List of ARNs of private subnets" - value = module.vpc.private_subnet_arns + value = module.vpc_ipam_set_netmask.private_subnet_arns } output "private_subnets_cidr_blocks" { description = "List of cidr_blocks of private subnets" - value = module.vpc.private_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.private_subnets_cidr_blocks } output "private_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of private subnets in an IPv6 enabled VPC" - value = module.vpc.private_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.private_subnets_ipv6_cidr_blocks } output "public_subnets" { description = "List of IDs of public subnets" - value = module.vpc.public_subnets + value = module.vpc_ipam_set_netmask.public_subnets } output "public_subnet_arns" { description = "List of ARNs of public subnets" - value = module.vpc.public_subnet_arns + value = module.vpc_ipam_set_netmask.public_subnet_arns } output "public_subnets_cidr_blocks" { description = "List of cidr_blocks of public subnets" - value = module.vpc.public_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.public_subnets_cidr_blocks } output "public_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of public subnets in an IPv6 enabled VPC" - value = module.vpc.public_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.public_subnets_ipv6_cidr_blocks } output "outpost_subnets" { description = "List of IDs of outpost subnets" - value = module.vpc.outpost_subnets + value = module.vpc_ipam_set_netmask.outpost_subnets } output "outpost_subnet_arns" { description = "List of ARNs of outpost subnets" - value = module.vpc.outpost_subnet_arns + value = module.vpc_ipam_set_netmask.outpost_subnet_arns } output "outpost_subnets_cidr_blocks" { description = "List of cidr_blocks of outpost subnets" - value = module.vpc.outpost_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.outpost_subnets_cidr_blocks } output "outpost_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of outpost subnets in an IPv6 enabled VPC" - value = module.vpc.outpost_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.outpost_subnets_ipv6_cidr_blocks } output "database_subnets" { description = "List of IDs of database subnets" - value = module.vpc.database_subnets + value = module.vpc_ipam_set_netmask.database_subnets } output "database_subnet_arns" { description = "List of ARNs of database subnets" - value = module.vpc.database_subnet_arns + value = module.vpc_ipam_set_netmask.database_subnet_arns } output "database_subnets_cidr_blocks" { description = "List of cidr_blocks of database subnets" - value = module.vpc.database_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.database_subnets_cidr_blocks } output "database_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of database subnets in an IPv6 enabled VPC" - value = module.vpc.database_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.database_subnets_ipv6_cidr_blocks } output "database_subnet_group" { description = "ID of database subnet group" - value = module.vpc.database_subnet_group + value = module.vpc_ipam_set_netmask.database_subnet_group } output "database_subnet_group_name" { description = "Name of database subnet group" - value = module.vpc.database_subnet_group_name + value = module.vpc_ipam_set_netmask.database_subnet_group_name } output "redshift_subnets" { description = "List of IDs of redshift subnets" - value = module.vpc.redshift_subnets + value = module.vpc_ipam_set_netmask.redshift_subnets } output "redshift_subnet_arns" { description = "List of ARNs of redshift subnets" - value = module.vpc.redshift_subnet_arns + value = module.vpc_ipam_set_netmask.redshift_subnet_arns } output "redshift_subnets_cidr_blocks" { description = "List of cidr_blocks of redshift subnets" - value = module.vpc.redshift_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.redshift_subnets_cidr_blocks } output "redshift_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of redshift subnets in an IPv6 enabled VPC" - value = module.vpc.redshift_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.redshift_subnets_ipv6_cidr_blocks } output "redshift_subnet_group" { description = "ID of redshift subnet group" - value = module.vpc.redshift_subnet_group + value = module.vpc_ipam_set_netmask.redshift_subnet_group } output "elasticache_subnets" { description = "List of IDs of elasticache subnets" - value = module.vpc.elasticache_subnets + value = module.vpc_ipam_set_netmask.elasticache_subnets } output "elasticache_subnet_arns" { description = "List of ARNs of elasticache subnets" - value = module.vpc.elasticache_subnet_arns + value = module.vpc_ipam_set_netmask.elasticache_subnet_arns } output "elasticache_subnets_cidr_blocks" { description = "List of cidr_blocks of elasticache subnets" - value = module.vpc.elasticache_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.elasticache_subnets_cidr_blocks } output "elasticache_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of elasticache subnets in an IPv6 enabled VPC" - value = module.vpc.elasticache_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.elasticache_subnets_ipv6_cidr_blocks } output "intra_subnets" { description = "List of IDs of intra subnets" - value = module.vpc.intra_subnets + value = module.vpc_ipam_set_netmask.intra_subnets } output "intra_subnet_arns" { description = "List of ARNs of intra subnets" - value = module.vpc.intra_subnet_arns + value = module.vpc_ipam_set_netmask.intra_subnet_arns } output "intra_subnets_cidr_blocks" { description = "List of cidr_blocks of intra subnets" - value = module.vpc.intra_subnets_cidr_blocks + value = module.vpc_ipam_set_netmask.intra_subnets_cidr_blocks } output "intra_subnets_ipv6_cidr_blocks" { description = "List of IPv6 cidr_blocks of intra subnets in an IPv6 enabled VPC" - value = module.vpc.intra_subnets_ipv6_cidr_blocks + value = module.vpc_ipam_set_netmask.intra_subnets_ipv6_cidr_blocks } output "elasticache_subnet_group" { description = "ID of elasticache subnet group" - value = module.vpc.elasticache_subnet_group + value = module.vpc_ipam_set_netmask.elasticache_subnet_group } output "elasticache_subnet_group_name" { description = "Name of elasticache subnet group" - value = module.vpc.elasticache_subnet_group_name + value = module.vpc_ipam_set_netmask.elasticache_subnet_group_name } output "public_route_table_ids" { description = "List of IDs of public route tables" - value = module.vpc.public_route_table_ids + value = module.vpc_ipam_set_netmask.public_route_table_ids } output "private_route_table_ids" { description = "List of IDs of private route tables" - value = module.vpc.private_route_table_ids + value = module.vpc_ipam_set_netmask.private_route_table_ids } output "database_route_table_ids" { description = "List of IDs of database route tables" - value = module.vpc.database_route_table_ids + value = module.vpc_ipam_set_netmask.database_route_table_ids } output "redshift_route_table_ids" { description = "List of IDs of redshift route tables" - value = module.vpc.redshift_route_table_ids + value = module.vpc_ipam_set_netmask.redshift_route_table_ids } output "elasticache_route_table_ids" { description = "List of IDs of elasticache route tables" - value = module.vpc.elasticache_route_table_ids + value = module.vpc_ipam_set_netmask.elasticache_route_table_ids } output "intra_route_table_ids" { description = "List of IDs of intra route tables" - value = module.vpc.intra_route_table_ids + value = module.vpc_ipam_set_netmask.intra_route_table_ids } output "public_internet_gateway_route_id" { description = "ID of the internet gateway route" - value = module.vpc.public_internet_gateway_route_id + value = module.vpc_ipam_set_netmask.public_internet_gateway_route_id } output "public_internet_gateway_ipv6_route_id" { description = "ID of the IPv6 internet gateway route" - value = module.vpc.public_internet_gateway_ipv6_route_id + value = module.vpc_ipam_set_netmask.public_internet_gateway_ipv6_route_id } output "database_internet_gateway_route_id" { description = "ID of the database internet gateway route" - value = module.vpc.database_internet_gateway_route_id + value = module.vpc_ipam_set_netmask.database_internet_gateway_route_id } output "database_nat_gateway_route_ids" { description = "List of IDs of the database nat gateway route" - value = module.vpc.database_nat_gateway_route_ids + value = module.vpc_ipam_set_netmask.database_nat_gateway_route_ids } output "database_ipv6_egress_route_id" { description = "ID of the database IPv6 egress route" - value = module.vpc.database_ipv6_egress_route_id + value = module.vpc_ipam_set_netmask.database_ipv6_egress_route_id } output "private_nat_gateway_route_ids" { description = "List of IDs of the private nat gateway route" - value = module.vpc.private_nat_gateway_route_ids + value = module.vpc_ipam_set_netmask.private_nat_gateway_route_ids } output "private_ipv6_egress_route_ids" { description = "List of IDs of the ipv6 egress route" - value = module.vpc.private_ipv6_egress_route_ids + value = module.vpc_ipam_set_netmask.private_ipv6_egress_route_ids } output "private_route_table_association_ids" { description = "List of IDs of the private route table association" - value = module.vpc.private_route_table_association_ids + value = module.vpc_ipam_set_netmask.private_route_table_association_ids } output "database_route_table_association_ids" { description = "List of IDs of the database route table association" - value = module.vpc.database_route_table_association_ids + value = module.vpc_ipam_set_netmask.database_route_table_association_ids } output "redshift_route_table_association_ids" { description = "List of IDs of the redshift route table association" - value = module.vpc.redshift_route_table_association_ids + value = module.vpc_ipam_set_netmask.redshift_route_table_association_ids } output "redshift_public_route_table_association_ids" { description = "List of IDs of the public redshift route table association" - value = module.vpc.redshift_public_route_table_association_ids + value = module.vpc_ipam_set_netmask.redshift_public_route_table_association_ids } output "elasticache_route_table_association_ids" { description = "List of IDs of the elasticache route table association" - value = module.vpc.elasticache_route_table_association_ids + value = module.vpc_ipam_set_netmask.elasticache_route_table_association_ids } output "intra_route_table_association_ids" { description = "List of IDs of the intra route table association" - value = module.vpc.intra_route_table_association_ids + value = module.vpc_ipam_set_netmask.intra_route_table_association_ids } output "public_route_table_association_ids" { description = "List of IDs of the public route table association" - value = module.vpc.public_route_table_association_ids + value = module.vpc_ipam_set_netmask.public_route_table_association_ids } output "dhcp_options_id" { description = "The ID of the DHCP options" - value = module.vpc.dhcp_options_id + value = module.vpc_ipam_set_netmask.dhcp_options_id } output "nat_ids" { description = "List of allocation ID of Elastic IPs created for AWS NAT Gateway" - value = module.vpc.nat_ids + value = module.vpc_ipam_set_netmask.nat_ids } output "nat_public_ips" { description = "List of public Elastic IPs created for AWS NAT Gateway" - value = module.vpc.nat_public_ips + value = module.vpc_ipam_set_netmask.nat_public_ips } output "natgw_ids" { description = "List of NAT Gateway IDs" - value = module.vpc.natgw_ids + value = module.vpc_ipam_set_netmask.natgw_ids } output "igw_id" { description = "The ID of the Internet Gateway" - value = module.vpc.igw_id + value = module.vpc_ipam_set_netmask.igw_id } output "igw_arn" { description = "The ARN of the Internet Gateway" - value = module.vpc.igw_arn + value = module.vpc_ipam_set_netmask.igw_arn } output "egress_only_internet_gateway_id" { description = "The ID of the egress only Internet Gateway" - value = module.vpc.egress_only_internet_gateway_id + value = module.vpc_ipam_set_netmask.egress_only_internet_gateway_id } output "cgw_ids" { description = "List of IDs of Customer Gateway" - value = module.vpc.cgw_ids + value = module.vpc_ipam_set_netmask.cgw_ids } output "cgw_arns" { description = "List of ARNs of Customer Gateway" - value = module.vpc.cgw_arns + value = module.vpc_ipam_set_netmask.cgw_arns } output "this_customer_gateway" { description = "Map of Customer Gateway attributes" - value = module.vpc.this_customer_gateway + value = module.vpc_ipam_set_netmask.this_customer_gateway } output "vgw_id" { description = "The ID of the VPN Gateway" - value = module.vpc.vgw_id + value = module.vpc_ipam_set_netmask.vgw_id } output "vgw_arn" { description = "The ARN of the VPN Gateway" - value = module.vpc.vgw_arn + value = module.vpc_ipam_set_netmask.vgw_arn } output "default_vpc_id" { description = "The ID of the Default VPC" - value = module.vpc.default_vpc_id + value = module.vpc_ipam_set_netmask.default_vpc_id } output "default_vpc_arn" { description = "The ARN of the Default VPC" - value = module.vpc.default_vpc_arn + value = module.vpc_ipam_set_netmask.default_vpc_arn } output "default_vpc_cidr_block" { description = "The CIDR block of the Default VPC" - value = module.vpc.default_vpc_cidr_block + value = module.vpc_ipam_set_netmask.default_vpc_cidr_block } output "default_vpc_default_security_group_id" { description = "The ID of the security group created by default on Default VPC creation" - value = module.vpc.default_vpc_default_security_group_id + value = module.vpc_ipam_set_netmask.default_vpc_default_security_group_id } output "default_vpc_default_network_acl_id" { description = "The ID of the default network ACL of the Default VPC" - value = module.vpc.default_vpc_default_network_acl_id + value = module.vpc_ipam_set_netmask.default_vpc_default_network_acl_id } output "default_vpc_default_route_table_id" { description = "The ID of the default route table of the Default VPC" - value = module.vpc.default_vpc_default_route_table_id + value = module.vpc_ipam_set_netmask.default_vpc_default_route_table_id } output "default_vpc_instance_tenancy" { description = "Tenancy of instances spin up within Default VPC" - value = module.vpc.default_vpc_instance_tenancy + value = module.vpc_ipam_set_netmask.default_vpc_instance_tenancy } output "default_vpc_enable_dns_support" { description = "Whether or not the Default VPC has DNS support" - value = module.vpc.default_vpc_enable_dns_support + value = module.vpc_ipam_set_netmask.default_vpc_enable_dns_support } output "default_vpc_enable_dns_hostnames" { description = "Whether or not the Default VPC has DNS hostname support" - value = module.vpc.default_vpc_enable_dns_hostnames + value = module.vpc_ipam_set_netmask.default_vpc_enable_dns_hostnames } output "default_vpc_main_route_table_id" { description = "The ID of the main route table associated with the Default VPC" - value = module.vpc.default_vpc_main_route_table_id + value = module.vpc_ipam_set_netmask.default_vpc_main_route_table_id } output "public_network_acl_id" { description = "ID of the public network ACL" - value = module.vpc.public_network_acl_id + value = module.vpc_ipam_set_netmask.public_network_acl_id } output "public_network_acl_arn" { description = "ARN of the public network ACL" - value = module.vpc.public_network_acl_arn + value = module.vpc_ipam_set_netmask.public_network_acl_arn } output "private_network_acl_id" { description = "ID of the private network ACL" - value = module.vpc.private_network_acl_id + value = module.vpc_ipam_set_netmask.private_network_acl_id } output "private_network_acl_arn" { description = "ARN of the private network ACL" - value = module.vpc.private_network_acl_arn + value = module.vpc_ipam_set_netmask.private_network_acl_arn } output "outpost_network_acl_id" { description = "ID of the outpost network ACL" - value = module.vpc.outpost_network_acl_id + value = module.vpc_ipam_set_netmask.outpost_network_acl_id } output "outpost_network_acl_arn" { description = "ARN of the outpost network ACL" - value = module.vpc.outpost_network_acl_arn + value = module.vpc_ipam_set_netmask.outpost_network_acl_arn } output "intra_network_acl_id" { description = "ID of the intra network ACL" - value = module.vpc.intra_network_acl_id + value = module.vpc_ipam_set_netmask.intra_network_acl_id } output "intra_network_acl_arn" { description = "ARN of the intra network ACL" - value = module.vpc.intra_network_acl_arn + value = module.vpc_ipam_set_netmask.intra_network_acl_arn } output "database_network_acl_id" { description = "ID of the database network ACL" - value = module.vpc.database_network_acl_id + value = module.vpc_ipam_set_netmask.database_network_acl_id } output "database_network_acl_arn" { description = "ARN of the database network ACL" - value = module.vpc.database_network_acl_arn + value = module.vpc_ipam_set_netmask.database_network_acl_arn } output "redshift_network_acl_id" { description = "ID of the redshift network ACL" - value = module.vpc.redshift_network_acl_id + value = module.vpc_ipam_set_netmask.redshift_network_acl_id } output "redshift_network_acl_arn" { description = "ARN of the redshift network ACL" - value = module.vpc.redshift_network_acl_arn + value = module.vpc_ipam_set_netmask.redshift_network_acl_arn } output "elasticache_network_acl_id" { description = "ID of the elasticache network ACL" - value = module.vpc.elasticache_network_acl_id + value = module.vpc_ipam_set_netmask.elasticache_network_acl_id } output "elasticache_network_acl_arn" { description = "ARN of the elasticache network ACL" - value = module.vpc.elasticache_network_acl_arn + value = module.vpc_ipam_set_netmask.elasticache_network_acl_arn } # VPC flow log output "vpc_flow_log_id" { description = "The ID of the Flow Log resource" - value = module.vpc.vpc_flow_log_id + value = module.vpc_ipam_set_netmask.vpc_flow_log_id } output "vpc_flow_log_destination_arn" { description = "The ARN of the destination for VPC Flow Logs" - value = module.vpc.vpc_flow_log_destination_arn + value = module.vpc_ipam_set_netmask.vpc_flow_log_destination_arn } output "vpc_flow_log_destination_type" { description = "The type of the destination for VPC Flow Logs" - value = module.vpc.vpc_flow_log_destination_type + value = module.vpc_ipam_set_netmask.vpc_flow_log_destination_type } output "vpc_flow_log_cloudwatch_iam_role_arn" { description = "The ARN of the IAM role used when pushing logs to Cloudwatch log group" - value = module.vpc.vpc_flow_log_cloudwatch_iam_role_arn + value = module.vpc_ipam_set_netmask.vpc_flow_log_cloudwatch_iam_role_arn } diff --git a/main.tf b/main.tf index 3fff7485a..207bf9ccf 100644 --- a/main.tf +++ b/main.tf @@ -20,15 +20,20 @@ locals { resource "aws_vpc" "this" { count = local.create_vpc ? 1 : 0 - cidr_block = var.cidr - ipv4_ipam_pool_id = var.ipv4_ipam_pool_id - - instance_tenancy = var.instance_tenancy - enable_dns_hostnames = var.enable_dns_hostnames - enable_dns_support = var.enable_dns_support - enable_classiclink = null # https://github.com/hashicorp/terraform/issues/31730 - enable_classiclink_dns_support = null # https://github.com/hashicorp/terraform/issues/31730 - assign_generated_ipv6_cidr_block = var.enable_ipv6 + cidr_block = var.use_ipam_pool ? null : var.cidr + ipv4_ipam_pool_id = var.ipv4_ipam_pool_id + ipv4_netmask_length = var.ipv4_netmask_length + + assign_generated_ipv6_cidr_block = var.enable_ipv6 && !var.use_ipam_pool ? true : null + ipv6_cidr_block = var.ipv6_cidr + ipv6_ipam_pool_id = var.ipv6_ipam_pool_id + ipv6_netmask_length = var.ipv6_netmask_length + + instance_tenancy = var.instance_tenancy + enable_dns_hostnames = var.enable_dns_hostnames + enable_dns_support = var.enable_dns_support + enable_classiclink = null # https://github.com/hashicorp/terraform/issues/31730 + enable_classiclink_dns_support = null # https://github.com/hashicorp/terraform/issues/31730 tags = merge( { "Name" = var.name }, diff --git a/variables.tf b/variables.tf index d43671c65..15f209c52 100644 --- a/variables.tf +++ b/variables.tf @@ -11,7 +11,7 @@ variable "name" { } variable "cidr" { - description = "(Optional) The IPv4 CIDR block for the VPC." + description = "(Optional) The IPv4 CIDR block for the VPC. CIDR can be explicitly set or it can be derived from IPAM using `ipv4_netmask_length` & `ipv4_ipam_pool_id`" type = string default = "0.0.0.0/0" } @@ -1190,12 +1190,42 @@ variable "flow_log_per_hour_partition" { default = false } +variable "use_ipam_pool" { + description = "Determines whether IPAM pool is used for CIDR allocation" + type = bool + default = false +} + variable "ipv4_ipam_pool_id" { description = "(Optional) The ID of an IPv4 IPAM pool you want to use for allocating this VPC's CIDR." type = string default = null } +variable "ipv4_netmask_length" { + description = "(Optional) The netmask length of the IPv4 CIDR you want to allocate to this VPC. Requires specifying a ipv4_ipam_pool_id." + type = number + default = null +} + +variable "ipv6_cidr" { + description = "(Optional) IPv6 CIDR block to request from an IPAM Pool. Can be set explicitly or derived from IPAM using `ipv6_netmask_length`." + type = string + default = null +} + +variable "ipv6_ipam_pool_id" { + description = "(Optional) IPAM Pool ID for a IPv6 pool. Conflicts with `assign_generated_ipv6_cidr_block`." + type = string + default = null +} + +variable "ipv6_netmask_length" { + description = "(Optional) Netmask length to request from IPAM Pool. Conflicts with `ipv6_cidr_block`. This can be omitted if IPAM pool as a `allocation_default_netmask_length` set. Valid values: `56`." + type = number + default = null +} + variable "putin_khuylo" { description = "Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!" type = bool