Skip to content

Commit 8adf507

Browse files
authored
Merge pull request #151 from alexohima/fix-secondary-cidr-first-pass
Fix secondary cidr creation on the first pass
2 parents 7274a9b + 251f314 commit 8adf507

File tree

6 files changed

+29
-8
lines changed

6 files changed

+29
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,14 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws
373373
| Name | Description | Type | Default | Required |
374374
|------|-------------|------|---------|:--------:|
375375
| <a name="input_az_count"></a> [az\_count](#input\_az\_count) | Searches region for # of AZs to use and takes a slice based on count. Assume slice is sorted a-z. | `number` | n/a | yes |
376+
| <a name="input_azs"></a> [azs](#input\_azs) | A list of availability zones names | `list(string)` | `[]` | no | | | | | |
376377
| <a name="input_name"></a> [name](#input\_name) | Name to give VPC. Note: does not effect subnet names, which get assigned name based on name\_prefix. | `string` | n/a | yes |
377378
| <a name="input_subnets"></a> [subnets](#input\_subnets) | Configuration of subnets to build in VPC. 1 Subnet per AZ is created. Subnet types are defined as maps with the available keys: "private", "public", "transit\_gateway", "core\_network". Each Subnet type offers its own set of available arguments detailed below.<br><br>**Attributes shared across subnet types:**<br>- `cidrs` = (Optional\|list(string)) **Cannot set if `netmask` is set.** List of IPv4 CIDRs to set to subnets. Count of CIDRs defined must match quantity of azs in `az_count`.<br>- `netmask` = (Optional\|Int) **Cannot set if `cidrs` is set.** Netmask of the `var.cidr_block` to calculate for each subnet.<br>- `assign_ipv6_cidr` = (Optional\|bool) **Cannot set if `ipv6_cidrs` is set.** If true, it will calculate a /64 block from the IPv6 VPC CIDR to set in the subnets.<br>- `ipv6_cidrs` = (Optional\|list(string)) **Cannot set if `assign_ipv6_cidr` is set.** List of IPv6 CIDRs to set to subnets. The subnet size must use a /64 prefix length. Count of CIDRs defined must match quantity of azs in `az_count`.<br>- `name_prefix` = (Optional\|String) A string prefix to use for the name of your subnet and associated resources. Subnet type key name is used if omitted (aka private, public, transit\_gateway). Example `name_prefix = "private"` for `var.subnets.private` is redundant.<br>- `tags` = (Optional\|map(string)) Tags to set on the subnet and associated resources.<br><br>**Any private subnet type options:**<br>- All shared keys above<br>- `connect_to_public_natgw` = (Optional\|bool) Determines if routes to NAT Gateways should be created. Must also set `var.subnets.public.nat_gateway_configuration` in public subnets.<br>- `ipv6_native` = (Optional\|bool) Indicates whether to create an IPv6-ony subnet. Either `var.assign_ipv6_cidr` or `var.ipv6_cidrs` should be defined to allocate an IPv6 CIDR block.<br>- `connect_to_eigw` = (Optional\|bool) Determines if routes to the Egress-only Internet gateway should be created. Must also set `var.vpc_egress_only_internet_gateway`.<br><br>**public subnet type options:**<br>- All shared keys above<br>- `nat_gateway_configuration` = (Optional\|string) Determines if NAT Gateways should be created and in how many AZs. Valid values = `"none"`, `"single_az"`, `"all_azs"`. Default = "none". Must also set `var.subnets.private.connect_to_public_natgw = true`.<br>- `connect_to_igw` = (Optional\|bool) Determines if the default route (0.0.0.0/0 or ::/0) is created in the public subnets with destination the Internet gateway. Defaults to `true`.<br>- `ipv6_native` = (Optional\|bool) Indicates whether to create an IPv6-ony subnet. Either `var.assign_ipv6_cidr` or `var.ipv6_cidrs` should be defined to allocate an IPv6 CIDR block.<br>- `map_public_ip_on_launch` = (Optional\|bool) Specify true to indicate that instances launched into the subnet should be assigned a public IP address. Default to `false`.<br><br>**transit\_gateway subnet type options:**<br>- All shared keys above<br>- `connect_to_public_natgw` = (Optional\|string) Determines if routes to NAT Gateways should be created. Specify the CIDR range or a prefix-list-id that you want routed to nat gateway. Usually `0.0.0.0/0`. Must also set `var.subnets.public.nat_gateway_configuration`.<br>- `transit_gateway_default_route_table_association` = (Optional\|bool) Boolean whether the VPC Attachment should be associated with the EC2 Transit Gateway association default route table. This cannot be configured or perform drift detection with Resource Access Manager shared EC2 Transit Gateways.<br>- `transit_gateway_default_route_table_propagation` = (Optional\|bool) Boolean whether the VPC Attachment should propagate routes with the EC2 Transit Gateway propagation default route table. This cannot be configured or perform drift detection with Resource Access Manager shared EC2 Transit Gateways.<br>- `transit_gateway_appliance_mode_support` = (Optional\|string) Whether Appliance Mode is enabled. If enabled, a traffic flow between a source and a destination uses the same Availability Zone for the VPC attachment for the lifetime of that flow. Valid values: `disable` (default) and `enable`.<br>- `transit_gateway_dns_support` = (Optional\|string) DNS Support is used if you need the VPC to resolve public IPv4 DNS host names to private IPv4 addresses when queried from instances in another VPC attached to the transit gateway. Valid values: `enable` (default) and `disable`.<br><br>**core\_network subnet type options:**<br>- All shared keys abovce<br>- `connect_to_public_natgw` = (Optional\|string) Determines if routes to NAT Gateways should be created. Specify the CIDR range or a prefix-list-id that you want routed to nat gateway. Usually `0.0.0.0/0`. Must also set `var.subnets.public.nat_gateway_configuration`.<br>- `appliance_mode_support` = (Optional\|bool) Indicates whether appliance mode is supported. If enabled, traffic flow between a source and destination use the same Availability Zone for the VPC attachment for the lifetime of that flow. Defaults to `false`.<br>- `require_acceptance` = (Optional\|bool) Boolean whether the core network VPC attachment to create requires acceptance or not. Defaults to `false`.<br>- `accept_attachment` = (Optional\|bool) Boolean whether the core network VPC attachment is accepted or not in the segment. Only valid if `require_acceptance` is set to `true`. Defaults to `true`.<br><br>Example:<pre>subnets = {<br> # Dual-stack subnet<br> public = {<br> netmask = 24<br> assign_ipv6_cidr = true<br> nat_gateway_configuration = "single_az"<br> }<br> # IPv4 only subnet<br> private = {<br> netmask = 24<br> connect_to_public_natgw = true<br> }<br> # IPv6 only subnet<br> ipv6 = {<br> ipv6_native = true<br> assign_ipv6_cidr = true<br> connect_to_eigw = true<br> }<br> # Transit gateway subnets (dual-stack)<br> transit_gateway = {<br> netmask = 24<br> assign_ipv6_cidr = true<br> connect_to_public_natgw = true<br> transit_gateway_default_route_table_association = true<br> transit_gateway_default_route_table_propagation = true<br> }<br> # Core Network subnets (dual-stack)<br> core_network = {<br> netmask = 24<br> assign_ipv6_cidr = true<br> connect_to_public_natgw = true<br> appliance_mode_support = true<br> require_acceptance = true<br> accept_attachment = true<br> }<br>}</pre> | `any` | n/a | yes |
378379
| <a name="input_cidr_block"></a> [cidr\_block](#input\_cidr\_block) | IPv4 CIDR range to assign to VPC if creating VPC or to associate as a secondary IPv6 CIDR. Overridden by var.vpc\_id output from data.aws\_vpc. | `string` | `null` | no |
379380
| <a name="input_core_network"></a> [core\_network](#input\_core\_network) | AWS Cloud WAN's core network information - to create a VPC attachment. Required when `cloud_wan` subnet is defined. Two attributes are required: the `id` and `arn` of the resource. | <pre>object({<br> id = string<br> arn = string<br> })</pre> | <pre>{<br> "arn": null,<br> "id": null<br>}</pre> | no |
380381
| <a name="input_core_network_ipv6_routes"></a> [core\_network\_ipv6\_routes](#input\_core\_network\_ipv6\_routes) | Configuration of IPv6 route(s) to AWS Cloud WAN's core network.<br>For each `public` and/or `private` subnets named in the `subnets` variable, optionally create routes from the subnet to the core network.<br>You can specify either a CIDR range or a prefix-list-id that you want routed to the core network.<br>Example:<pre>core_network_ivp6_routes = {<br> public = "::/0"<br> private = "pl-123"<br>}</pre> | `any` | `{}` | no |
381382
| <a name="input_core_network_routes"></a> [core\_network\_routes](#input\_core\_network\_routes) | Configuration of route(s) to AWS Cloud WAN's core network.<br>For each `public` and/or `private` subnets named in the `subnets` variable, optionally create routes from the subnet to the core network.<br>You can specify either a CIDR range or a prefix-list-id that you want routed to the core network.<br>Example:<pre>core_network_routes = {<br> public = "10.0.0.0/8"<br> private = "pl-123"<br>}</pre> | `any` | `{}` | no |
383+
| <a name="input_create_vpc"></a> [create\_vpc](#input\_create\_vpc) | Determines whether to create the VPC or not; defaults to enabling the creation. | `bool` | `true` | no |
382384
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to all resources. | `map(string)` | `{}` | no |
383385
| <a name="input_transit_gateway_id"></a> [transit\_gateway\_id](#input\_transit\_gateway\_id) | Transit gateway id to attach the VPC to. Required when `transit_gateway` subnet is defined. | `string` | `null` | no |
384386
| <a name="input_transit_gateway_ipv6_routes"></a> [transit\_gateway\_ipv6\_routes](#input\_transit\_gateway\_ipv6\_routes) | Configuration of IPv6 route(s) to transit gateway.<br>For each `public` and/or `private` subnets named in the `subnets` variable,<br>Optionally create routes from the subnet to transit gateway. Specify the CIDR range or a prefix-list-id that you want routed to the transit gateway.<br>Example:<pre>transit_gateway_ipv6_routes = {<br> public = "::/0"<br> private = "pl-123"<br>}</pre> | `any` | `{}` | no |

data.tf

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
locals {
2-
azs = slice(data.aws_availability_zones.current.names, 0, var.az_count)
2+
azs = length(var.azs) == 0 ? slice(data.aws_availability_zones.current.names, 0, var.az_count) : var.azs
33

44
# references to module.calculate_subnets output
55
calculated_subnets = module.calculate_subnets.subnets_by_type
@@ -89,9 +89,7 @@ locals {
8989
# - get cidr block value from AWS IPAM
9090
# - create flow logs
9191

92-
# # if var.vpc_id is passed, assume create = `false` and cidr comes from data.aws_vpc
93-
create_vpc = var.vpc_id == null ? true : false
94-
vpc = local.create_vpc ? aws_vpc.main[0] : data.aws_vpc.main[0]
92+
vpc = var.create_vpc ? aws_vpc.main[0] : data.aws_vpc.main[0]
9593
cidr_block = var.cidr_block == null ? local.vpc.cidr_block : var.cidr_block
9694

9795
create_flow_logs = (var.vpc_flow_logs == null || var.vpc_flow_logs.log_destination_type == "none") ? false : true
@@ -129,7 +127,7 @@ data "aws_availability_zones" "current" {
129127

130128
# search for existing vpc with var.vpc_id if not creating
131129
data "aws_vpc" "main" {
132-
count = local.create_vpc ? 0 : 1
130+
count = var.create_vpc ? 0 : 1
133131
id = var.vpc_id
134132
}
135133

examples/secondary_cidr/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ No requirements.
2929

3030
| Name | Type |
3131
|------|------|
32+
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
3233
| [aws_nat_gateway.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/nat_gateway) | data source |
3334
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
3435
| [aws_vpc.selected](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |

examples/secondary_cidr/main.tf

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
data "aws_region" "current" {}
22

3+
data "aws_availability_zones" "available" {}
4+
35
data "aws_vpc" "selected" {
46
tags = {
57
Name = "primary-az-vpc"
@@ -18,7 +20,12 @@ module "secondary" {
1820
source = "../.."
1921

2022
name = "secondary-cidr"
21-
az_count = var.az_count
23+
create_vpc = false
24+
25+
# If the AZ calculation is done in the module when creating a secondary CIDR, it will not
26+
# be known until after applying, resulting in an error. Hence, we need to pass it here.
27+
azs = slice(data.aws_availability_zones.available.names, 0, var.az_count)
28+
2229
cidr_block = "10.2.0.0/16"
2330

2431
vpc_secondary_cidr = true

main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module "calculate_subnets_ipv6" {
2323
# flow logs optionally enabled by standalone resource
2424
#tfsec:ignore:aws-ec2-require-vpc-flow-logs-for-all-vpcs
2525
resource "aws_vpc" "main" {
26-
count = local.create_vpc ? 1 : 0
26+
count = var.create_vpc ? 1 : 0
2727

2828
cidr_block = var.cidr_block
2929
ipv4_ipam_pool_id = var.vpc_ipv4_ipam_pool_id
@@ -45,7 +45,7 @@ resource "aws_vpc" "main" {
4545

4646
# ---------- SECONDARY IPv4 CIDR BLOCK (if configured) ----------
4747
resource "aws_vpc_ipv4_cidr_block_association" "secondary" {
48-
count = (var.vpc_secondary_cidr && !local.create_vpc) ? 1 : 0
48+
count = (var.vpc_secondary_cidr && !var.create_vpc) ? 1 : 0
4949

5050
vpc_id = var.vpc_id
5151
cidr_block = local.cidr_block

variables.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,24 @@ variable "vpc_id" {
1515
type = string
1616
}
1717

18+
variable "create_vpc" {
19+
description = "Determines whether to create the VPC or not; defaults to enabling the creation."
20+
default = true
21+
type = bool
22+
}
23+
1824
variable "az_count" {
1925
type = number
26+
default = 0
2027
description = "Searches region for # of AZs to use and takes a slice based on count. Assume slice is sorted a-z."
2128
}
2229

30+
variable "azs" {
31+
description = "A list of availability zones names"
32+
type = list(string)
33+
default = []
34+
}
35+
2336
variable "vpc_enable_dns_hostnames" {
2437
type = bool
2538
description = "Indicates whether the instances launched in the VPC get DNS hostnames. If enabled, instances in the VPC get DNS hostnames; otherwise, they do not. Disabled by default for nondefault VPCs."

0 commit comments

Comments
 (0)