Skip to content

Commit

Permalink
Merge pull request terraform-aws-modules#92 from pablo19sc/main
Browse files Browse the repository at this point in the history
Adding Cloud WAN support
  • Loading branch information
drewmullen authored Nov 14, 2022
2 parents ff4c64f + 85ae4ef commit 079bf31
Show file tree
Hide file tree
Showing 26 changed files with 805 additions and 28 deletions.
76 changes: 74 additions & 2 deletions .header.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module "vpc" {

## Reserved Subnet Key Names

There are 2 reserved keys for subnet key names in var.subnets corresponding to types "public" and "transit_gateway". Other custom subnet key names are valid are and those subnets will be private subnets.
There are 3 reserved keys for subnet key names in var.subnets corresponding to types "public", "transit_gateway", and "core_network" [(an AWS Cloud WAN feature)](https://docs.aws.amazon.com/vpc/latest/cloudwan/cloudwan-networks-working-with.html). Other custom subnet key names are valid are and those subnets will be private subnets.

```terraform
transit_gateway_id = <>
Expand Down Expand Up @@ -86,6 +86,33 @@ subnets = {
}
```

```terraform
core_network = {
id = <>
arn = <>
}
core_network_routes = {
workload = "pl-123"
}
subnets = {
workload = {
name_prefix = "workload-private"
netmask = 24
}
core_network = {
netmask = 28
ipv6_support = false
require_acceptance = true
accept_attachment = true
tags = {
env = "prod"
}
}
```

## Updating a VPC with new or removed subnets

If using `netmask` to calculate subnets and you wish to either add or remove subnets (ex: adding / removing an AZ), you may have to change from using `netmask` for some subnets and set to explicit instead. Private subnets are always calculated before public.
Expand Down Expand Up @@ -207,6 +234,51 @@ or

`export AWS_DEFAULT_REGION=<>`

## Contributing
## Error creating routes to Core Network

Error:

> error creating Route in Route Table (rtb-xxx) with destination (YYY): InvalidCoreNetworkArn.NotFound: The core network arn 'arn:aws:networkmanager::XXXX:core-network/core-network-YYYYY' does not exist.
This happens when the Core Network's VPC attachment requires acceptance, so it's not possible to create the routes in the VPC until the attachment is accepted. Check the following:

* If the VPC attachment requires acceptance and you want the module to automatically accept it, configure `require_acceptance` and `accept_attachment` to `true`.

```terraform
subnets = {
core_network = {
netmaks = 28
require_acceptance = true
accept_attachment = true
}
}
```

* If the VPC attachment requires acceptance but you want to accept it outside the module, first configure `require_acceptance` to `true` and `accept_attachment` to `false`.

```terraform
subnets = {
core_network = {
netmaks = 28
require_acceptance = true
accept_attachment = true
}
}
```

After you apply and the attachment is accepted (outside the module), change the subnet configuration with `require_acceptance` to `false`.

```terraform
subnets = {
core_network = {
netmaks = 28
require_acceptance = false
}
}
```

* Alternatively, you can also not configure any subnet route (`var.core_network_routes`) to the Core Network until the attachment gets accepted.

# Contributing

Please see our [developer documentation](https://github.com/aws-ia/terraform-aws-vpc/blob/main/contributing.md) for guidance on contributing to this module
94 changes: 89 additions & 5 deletions README.md

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ locals {
# - subnets map contains arbitrary amount of subnet "keys" which are both defined as the subnets type and default name (unless name_prefix is provided).
# - resource name labels for subnet use the key as private subnet keys are constructed

singleton_subnet_types = ["public", "transit_gateway"]
singleton_subnet_types = ["public", "transit_gateway", "core_network"]
private_subnet_names = setsubtract(local.subnet_keys, local.singleton_subnet_types)

# constructed list of <private_subnet_key>/az
Expand All @@ -35,6 +35,14 @@ locals {
subnets_tgw_routed = keys(var.transit_gateway_routes)
private_subnet_key_names_tgw_routed = [for subnet in local.private_per_az : subnet if contains(local.subnets_tgw_routed, split("/", subnet)[0])]

# support variables for core_network_routes
subnets_cwan_routed = keys(var.core_network_routes)
private_subnet_key_names_cwan_routes = [for subnet in local.private_per_az : subnet if contains(local.subnets_cwan_routed, split("/", subnet)[0])]
require_acceptance = try(var.subnets.core_network.require_acceptance, false) # value to default
accept_attachment = try(var.subnets.core_network.accept_attachment, true) # value to default
create_acceptance = (local.require_acceptance == true && local.accept_attachment == true)
create_cwan_routes = (local.require_acceptance == false) || local.create_acceptance

##################################################################
# NAT configurations options, maps user string input to HCL usable values. selected based on nat_gateway_configuration
# null = none
Expand Down
10 changes: 10 additions & 0 deletions examples/cloud_wan/.header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Creating AWS Cloud WAN's VPC attachment

This example shows how you can use this module with `core_network` subnets, and AWS Cloud WAN's VPC attachment. This examples creates the following:

* Global Network and Core Network.
* Core Network's policy (in `cwan_policy.tf`), creating two segments (prod and nonprod) in two AWS Regions (*us-east-1* and *eu-west-1*). The *prod* segments needs acceptance for the attachments.
* The VPC module creates the following (in two AWS Regions):
* Two sets of subnets (workloads and core_network)
* Cloud WAN's VPC attachment - with attachment acceptance for the VPC to associate to the *prod* segment.
* Routing to Core Network (0.0.0.0/0) in workload subnets.
21 changes: 21 additions & 0 deletions examples/cloud_wan/.terraform-docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
formatter: markdown
header-from: .header.md
settings:
anchor: true
color: true
default: true
escape: true
html: true
indent: 2
required: true
sensitive: true
type: true
lockfile: false

sort:
enabled: true
by: required

output:
file: README.md
mode: replace
57 changes: 57 additions & 0 deletions examples/cloud_wan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!-- BEGIN_TF_DOCS -->
# Creating AWS Cloud WAN's VPC attachment

This example shows how you can use this module with `core_network` subnets, and AWS Cloud WAN's VPC attachment. This examples creates the following:

* Global Network and Core Network.
* Core Network's policy (in `cwan_policy.tf`), creating two segments (prod and nonprod) in two AWS Regions (*us-east-1* and *eu-west-1*). The *prod* segments needs acceptance for the attachments.
* The VPC module creates the following (in two AWS Regions):
* Two sets of subnets (workloads and core\_network)
* Cloud WAN's VPC attachment - with attachment acceptance for the VPC to associate to the *prod* segment.
* Routing to Core Network (0.0.0.0/0) in workload subnets.

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.27.0 |
| <a name="requirement_awscc"></a> [awscc](#requirement\_awscc) | >= 0.36.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.27.0 |
| <a name="provider_awscc.awsccnvirginia"></a> [awscc.awsccnvirginia](#provider\_awscc.awsccnvirginia) | >= 0.36.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_ireland_vpc"></a> [ireland\_vpc](#module\_ireland\_vpc) | aws-ia/vpc/aws | >= 3.0.2 |
| <a name="module_nvirginia_vpc"></a> [nvirginia\_vpc](#module\_nvirginia\_vpc) | aws-ia/vpc/aws | >= 3.0.2 |

## Resources

| Name | Type |
|------|------|
| [awscc_networkmanager_core_network.core_network](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/networkmanager_core_network) | resource |
| [awscc_networkmanager_global_network.global_network](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/networkmanager_global_network) | resource |
| [aws_networkmanager_core_network_policy_document.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/networkmanager_core_network_policy_document) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cloud_wan_regions"></a> [cloud\_wan\_regions](#input\_cloud\_wan\_regions) | AWS Regions to create in Cloud WAN's core network. | <pre>object({<br> nvirginia = string<br> ireland = string<br> })</pre> | <pre>{<br> "ireland": "eu-west-1",<br> "nvirginia": "us-east-1"<br>}</pre> | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_core_network"></a> [core\_network](#output\_core\_network) | Core Network ID. |
| <a name="output_core_network_vpc_attachments"></a> [core\_network\_vpc\_attachments](#output\_core\_network\_vpc\_attachments) | Core Network VPC attachments. |
| <a name="output_global_network"></a> [global\_network](#output\_global\_network) | Global Network ID. |
| <a name="output_vpcs"></a> [vpcs](#output\_vpcs) | VPCs created. |
<!-- END_TF_DOCS -->
63 changes: 63 additions & 0 deletions examples/cloud_wan/cwan_policy.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

data "aws_networkmanager_core_network_policy_document" "policy" {
core_network_configuration {
vpn_ecmp_support = true
asn_ranges = ["64515-64520"]

edge_locations {
location = var.cloud_wan_regions.nvirginia
asn = 64515
}

edge_locations {
location = var.cloud_wan_regions.ireland
asn = 64516
}
}

segments {
name = "prod"
description = "Segment for production traffic"
require_attachment_acceptance = true
}

segments {
name = "nonprod"
description = "Segment for non-production traffic"
require_attachment_acceptance = false
}

attachment_policies {
rule_number = 100
condition_logic = "or"

conditions {
type = "tag-value"
operator = "equals"
key = "env"
value = "prod"
}

action {
association_method = "constant"
segment = "prod"
}
}

attachment_policies {
rule_number = 200
condition_logic = "or"

conditions {
type = "tag-value"
operator = "equals"
key = "env"
value = "nonprod"
}

action {
association_method = "constant"
segment = "nonprod"
}
}
}
94 changes: 94 additions & 0 deletions examples/cloud_wan/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@

# VPC module (North Virginia)
module "nvirginia_vpc" {
source = "aws-ia/vpc/aws"
version = ">= 3.0.2"

providers = {
aws = aws.awsnvirginia
awscc = awscc.awsccnvirginia
}

name = "nvirginia-vpc"
cidr_block = "10.0.0.0/24"
az_count = 2

core_network = {
id = awscc_networkmanager_core_network.core_network.core_network_id
arn = awscc_networkmanager_core_network.core_network.core_network_arn
}
core_network_routes = {
workload = "0.0.0.0/0"
}

subnets = {
workload = { netmask = 28 }
core_network = {
netmask = 28
ipv6_support = false
require_acceptance = true
accept_attachment = true

tags = {
env = "prod"
}
}
}
}

# VPC module (Ireland)
module "ireland_vpc" {
source = "aws-ia/vpc/aws"
version = ">= 3.0.2"

providers = {
aws = aws.awsireland
awscc = awscc.awsccireland
}

name = "ireland-vpc"
cidr_block = "10.0.1.0/24"
az_count = 2

core_network = {
id = awscc_networkmanager_core_network.core_network.core_network_id
arn = awscc_networkmanager_core_network.core_network.core_network_arn
}
core_network_routes = {
workload = "0.0.0.0/0"
}

subnets = {
workload = { netmask = 28 }
core_network = {
netmask = 28
ipv6_support = false
require_acceptance = false

tags = {
env = "nonprod"
}
}
}
}

# Global Network
resource "awscc_networkmanager_global_network" "global_network" {
provider = awscc.awsccnvirginia

description = "Global Network - VPC module"
}

# Core Network
resource "awscc_networkmanager_core_network" "core_network" {
provider = awscc.awsccnvirginia

description = "Core Network - VPC module"
global_network_id = awscc_networkmanager_global_network.global_network.id
policy_document = jsonencode(jsondecode(data.aws_networkmanager_core_network_policy_document.policy.json))

tags = [{
key = "Name",
value = "Core Network - VPC module"
}]
}
Loading

0 comments on commit 079bf31

Please sign in to comment.