Commit 2c034240 authored by Alex Bryant's avatar Alex Bryant Committed by GitHub

feat: Add outpost support (subnet, NACL, IPv6) (#542)

parent 0c2db005
......@@ -7,30 +7,30 @@ on:
- master
jobs:
# Min Terraform version(s)
# Min Terraform version(s)
getDirectories:
name: Get root directories
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Python
uses: actions/setup-python@v2
- name: Build matrix
id: matrix
run: |
DIRS=$(python -c "import json; import glob; print(json.dumps([x.replace('/versions.tf', '') for x in glob.glob('./**/versions.tf', recursive=True)]))")
echo "::set-output name=directories::$DIRS"
outputs:
directories: ${{ steps.matrix.outputs.directories }}
name: Get root directories
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Python
uses: actions/setup-python@v2
- name: Build matrix
id: matrix
run: |
DIRS=$(python -c "import json; import glob; print(json.dumps([x.replace('/versions.tf', '') for x in glob.glob('./**/versions.tf', recursive=True)]))")
echo "::set-output name=directories::$DIRS"
outputs:
directories: ${{ steps.matrix.outputs.directories }}
preCommitMinVersions:
name: Min TF validate
needs: getDirectories
runs-on: ubuntu-latest
strategy:
matrix:
directory: ${{ fromJson(needs.getDirectories.outputs.directories) }}
matrix:
directory: ${{ fromJson(needs.getDirectories.outputs.directories) }}
steps:
- name: Checkout
uses: actions/checkout@v2
......@@ -59,7 +59,7 @@ jobs:
pre-commit run terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)
# Max Terraform version
# Max Terraform version
getBaseVersion:
name: Module max TF version
runs-on: ubuntu-latest
......@@ -94,7 +94,7 @@ jobs:
- name: Install pre-commit dependencies
run: |
pip install pre-commit
curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E "https://.+?-v0.12.0-linux-amd64" | head -n1)" > terraform-docs && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/
curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E "https://.+?-v0.12\..+?-linux-amd64" | head -n1)" > terraform-docs && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/
curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/
- name: Execute pre-commit
# Run all pre-commit checks on max version supported
......
......@@ -220,6 +220,7 @@ It is possible to integrate this VPC module with [terraform-aws-transit-gateway
* [VPC with IPv6 enabled](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/ipv6)
* [Network ACL](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/network-acls)
* [VPC Flow Logs](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/vpc-flow-logs)
* [VPC with Outpost](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/outpost)
* [Manage Default VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/manage-default-vpc)
* 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)
......@@ -264,6 +265,7 @@ No modules.
| [aws_network_acl.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl.elasticache](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl.intra](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl.outpost](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
| [aws_network_acl.redshift](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource |
......@@ -273,6 +275,8 @@ No modules.
| [aws_network_acl_rule.elasticache_outbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.intra_inbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.intra_outbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.outpost_inbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.outpost_outbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.private_inbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.private_outbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
| [aws_network_acl_rule.public_inbound](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule) | resource |
......@@ -296,6 +300,7 @@ No modules.
| [aws_route_table_association.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.elasticache](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.intra](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.outpost](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.redshift](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
......@@ -303,6 +308,7 @@ No modules.
| [aws_subnet.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.elasticache](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.intra](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.outpost](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.redshift](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
......@@ -799,6 +805,17 @@ No modules.
| <a name="input_nat_eip_tags"></a> [nat\_eip\_tags](#input\_nat\_eip\_tags) | Additional tags for the NAT EIP | `map(string)` | `{}` | no |
| <a name="input_nat_gateway_tags"></a> [nat\_gateway\_tags](#input\_nat\_gateway\_tags) | Additional tags for the NAT gateways | `map(string)` | `{}` | no |
| <a name="input_one_nat_gateway_per_az"></a> [one\_nat\_gateway\_per\_az](#input\_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`. | `bool` | `false` | no |
| <a name="input_outpost_acl_tags"></a> [outpost\_acl\_tags](#input\_outpost\_acl\_tags) | Additional tags for the outpost subnets network ACL | `map(string)` | `{}` | no |
| <a name="input_outpost_arn"></a> [outpost\_arn](#input\_outpost\_arn) | ARN of Outpost you want to create a subnet in. | `string` | `null` | no |
| <a name="input_outpost_az"></a> [outpost\_az](#input\_outpost\_az) | AZ where Outpost is anchored. | `string` | `null` | no |
| <a name="input_outpost_dedicated_network_acl"></a> [outpost\_dedicated\_network\_acl](#input\_outpost\_dedicated\_network\_acl) | Whether to use dedicated network ACL (not default) and custom rules for outpost subnets | `bool` | `false` | no |
| <a name="input_outpost_inbound_acl_rules"></a> [outpost\_inbound\_acl\_rules](#input\_outpost\_inbound\_acl\_rules) | Outpost subnets inbound network ACLs | `list(map(string))` | <pre>[<br> {<br> "cidr_block": "0.0.0.0/0",<br> "from_port": 0,<br> "protocol": "-1",<br> "rule_action": "allow",<br> "rule_number": 100,<br> "to_port": 0<br> }<br>]</pre> | no |
| <a name="input_outpost_outbound_acl_rules"></a> [outpost\_outbound\_acl\_rules](#input\_outpost\_outbound\_acl\_rules) | Outpost subnets outbound network ACLs | `list(map(string))` | <pre>[<br> {<br> "cidr_block": "0.0.0.0/0",<br> "from_port": 0,<br> "protocol": "-1",<br> "rule_action": "allow",<br> "rule_number": 100,<br> "to_port": 0<br> }<br>]</pre> | no |
| <a name="input_outpost_subnet_assign_ipv6_address_on_creation"></a> [outpost\_subnet\_assign\_ipv6\_address\_on\_creation](#input\_outpost\_subnet\_assign\_ipv6\_address\_on\_creation) | Assign IPv6 address on outpost subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map\_public\_ip\_on\_launch | `bool` | `null` | no |
| <a name="input_outpost_subnet_ipv6_prefixes"></a> [outpost\_subnet\_ipv6\_prefixes](#input\_outpost\_subnet\_ipv6\_prefixes) | Assigns IPv6 outpost subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list | `list(string)` | `[]` | no |
| <a name="input_outpost_subnet_suffix"></a> [outpost\_subnet\_suffix](#input\_outpost\_subnet\_suffix) | Suffix to append to outpost subnets name | `string` | `"outpost"` | no |
| <a name="input_outpost_subnet_tags"></a> [outpost\_subnet\_tags](#input\_outpost\_subnet\_tags) | Additional tags for the outpost subnets | `map(string)` | `{}` | no |
| <a name="input_outpost_subnets"></a> [outpost\_subnets](#input\_outpost\_subnets) | A list of outpost subnets inside the VPC | `list(string)` | `[]` | no |
| <a name="input_private_acl_tags"></a> [private\_acl\_tags](#input\_private\_acl\_tags) | Additional tags for the private subnets network ACL | `map(string)` | `{}` | no |
| <a name="input_private_dedicated_network_acl"></a> [private\_dedicated\_network\_acl](#input\_private\_dedicated\_network\_acl) | Whether to use dedicated network ACL (not default) and custom rules for private subnets | `bool` | `false` | no |
| <a name="input_private_inbound_acl_rules"></a> [private\_inbound\_acl\_rules](#input\_private\_inbound\_acl\_rules) | Private subnets inbound network ACLs | `list(map(string))` | <pre>[<br> {<br> "cidr_block": "0.0.0.0/0",<br> "from_port": 0,<br> "protocol": "-1",<br> "rule_action": "allow",<br> "rule_number": 100,<br> "to_port": 0<br> }<br>]</pre> | no |
......@@ -982,6 +999,12 @@ No modules.
| <a name="output_nat_ids"></a> [nat\_ids](#output\_nat\_ids) | List of allocation ID of Elastic IPs created for AWS NAT Gateway |
| <a name="output_nat_public_ips"></a> [nat\_public\_ips](#output\_nat\_public\_ips) | List of public Elastic IPs created for AWS NAT Gateway |
| <a name="output_natgw_ids"></a> [natgw\_ids](#output\_natgw\_ids) | List of NAT Gateway IDs |
| <a name="output_outpost_network_acl_arn"></a> [outpost\_network\_acl\_arn](#output\_outpost\_network\_acl\_arn) | ARN of the outpost network ACL |
| <a name="output_outpost_network_acl_id"></a> [outpost\_network\_acl\_id](#output\_outpost\_network\_acl\_id) | ID of the outpost network ACL |
| <a name="output_outpost_subnet_arns"></a> [outpost\_subnet\_arns](#output\_outpost\_subnet\_arns) | List of ARNs of outpost subnets |
| <a name="output_outpost_subnets"></a> [outpost\_subnets](#output\_outpost\_subnets) | List of IDs of outpost subnets |
| <a name="output_outpost_subnets_cidr_blocks"></a> [outpost\_subnets\_cidr\_blocks](#output\_outpost\_subnets\_cidr\_blocks) | List of cidr\_blocks of outpost subnets |
| <a name="output_outpost_subnets_ipv6_cidr_blocks"></a> [outpost\_subnets\_ipv6\_cidr\_blocks](#output\_outpost\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of outpost subnets in an IPv6 enabled VPC |
| <a name="output_private_ipv6_egress_route_ids"></a> [private\_ipv6\_egress\_route\_ids](#output\_private\_ipv6\_egress\_route\_ids) | List of IDs of the ipv6 egress route. |
| <a name="output_private_nat_gateway_route_ids"></a> [private\_nat\_gateway\_route\_ids](#output\_private\_nat\_gateway\_route\_ids) | List of IDs of the private nat gateway route. |
| <a name="output_private_network_acl_arn"></a> [private\_network\_acl\_arn](#output\_private\_network\_acl\_arn) | ARN of the private network ACL |
......
# VPC with Outpost Subnet
Configuration in this directory creates a VPC with public, private, and private outpost subnets.
This configuration uses data-source to find an available Outpost by name. Change it according to your needs in order to run this example.
[Read more about AWS regions, availability zones and local zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-regions-availability-zones).
## Usage
To run this example you need to execute:
```bash
$ terraform init
$ terraform plan
$ terraform apply
```
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.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.21 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.5.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.5.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_vpc"></a> [vpc](#module\_vpc) | ../../ | |
## Resources
| Name | Type |
|------|------|
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_outposts_outpost.shared](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/outposts_outpost) | data source |
## Inputs
No inputs.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_azs"></a> [azs](#output\_azs) | A list of availability zones specified as argument to this module |
| <a name="output_nat_public_ips"></a> [nat\_public\_ips](#output\_nat\_public\_ips) | List of public Elastic IPs created for AWS NAT Gateway |
| <a name="output_outpost_subnets"></a> [outpost\_subnets](#output\_outpost\_subnets) | List of IDs of private subnets |
| <a name="output_private_subnets"></a> [private\_subnets](#output\_private\_subnets) | List of IDs of private subnets |
| <a name="output_public_subnets"></a> [public\_subnets](#output\_public\_subnets) | List of IDs of public subnets |
| <a name="output_vpc_cidr_block"></a> [vpc\_cidr\_block](#output\_vpc\_cidr\_block) | The CIDR block of the VPC |
| <a name="output_vpc_id"></a> [vpc\_id](#output\_vpc\_id) | The ID of the VPC |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
provider "aws" {
region = "us-west-2"
assume_role {
role_arn = "arn:aws:iam::562806027032:role/outpost-shared-anton"
}
}
data "aws_outposts_outpost" "shared" {
name = "SEA19.07"
}
data "aws_availability_zones" "available" {}
module "vpc" {
source = "../../"
name = "outpost-example"
cidr = "10.0.0.0/16"
azs = [
data.aws_availability_zones.available.names[0],
data.aws_availability_zones.available.names[1],
data.aws_availability_zones.available.names[2],
]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
# Outpost is using single AZ specified in `outpost_az`
outpost_subnets = ["10.0.50.0/24", "10.0.51.0/24"]
outpost_arn = data.aws_outposts_outpost.shared.arn
outpost_az = data.aws_outposts_outpost.shared.availability_zone
# IPv6
enable_ipv6 = true
outpost_subnet_assign_ipv6_address_on_creation = true
outpost_subnet_ipv6_prefixes = [2, 3, 4]
# NAT Gateway
enable_nat_gateway = true
single_nat_gateway = true
# Network ACLs
outpost_dedicated_network_acl = true
outpost_inbound_acl_rules = local.network_acls["outpost_inbound"]
outpost_outbound_acl_rules = local.network_acls["outpost_outbound"]
tags = {
Owner = "user"
Environment = "dev"
}
}
locals {
network_acls = {
outpost_inbound = [
{
rule_number = 100
rule_action = "allow"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 110
rule_action = "allow"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 120
rule_action = "allow"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 130
rule_action = "allow"
from_port = 3389
to_port = 3389
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 140
rule_action = "allow"
from_port = 80
to_port = 80
protocol = "tcp"
ipv6_cidr_block = "::/0"
},
]
outpost_outbound = [
{
rule_number = 100
rule_action = "allow"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 110
rule_action = "allow"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_block = "0.0.0.0/0"
},
{
rule_number = 120
rule_action = "allow"
from_port = 1433
to_port = 1433
protocol = "tcp"
cidr_block = "10.0.100.0/22"
},
{
rule_number = 130
rule_action = "allow"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_block = "10.0.100.0/22"
},
{
rule_number = 140
rule_action = "allow"
icmp_code = -1
icmp_type = 8
protocol = "icmp"
cidr_block = "10.0.0.0/22"
},
{
rule_number = 150
rule_action = "allow"
from_port = 90
to_port = 90
protocol = "tcp"
ipv6_cidr_block = "::/0"
},
]
}
}
# VPC
output "vpc_id" {
description = "The ID of the VPC"
value = module.vpc.vpc_id
}
# CIDR blocks
output "vpc_cidr_block" {
description = "The CIDR block of the VPC"
value = module.vpc.vpc_cidr_block
}
# Subnets
output "private_subnets" {
description = "List of IDs of private subnets"
value = module.vpc.private_subnets
}
output "public_subnets" {
description = "List of IDs of public subnets"
value = module.vpc.public_subnets
}
output "outpost_subnets" {
description = "List of IDs of private subnets"
value = module.vpc.outpost_subnets
}
# NAT gateways
output "nat_public_ips" {
description = "List of public Elastic IPs created for AWS NAT Gateway"
value = module.vpc.nat_public_ips
}
# AZs
output "azs" {
description = "A list of availability zones specified as argument to this module"
value = module.vpc.azs
}
terraform {
required_version = ">= 0.12.21"
required_providers {
aws = ">= 3.5.0"
}
}
......@@ -419,6 +419,34 @@ resource "aws_subnet" "private" {
)
}
#################
# Outpost subnet
#################
resource "aws_subnet" "outpost" {
count = var.create_vpc && length(var.outpost_subnets) > 0 ? length(var.outpost_subnets) : 0
vpc_id = local.vpc_id
cidr_block = var.outpost_subnets[count.index]
availability_zone = var.outpost_az
assign_ipv6_address_on_creation = var.outpost_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.outpost_subnet_assign_ipv6_address_on_creation
ipv6_cidr_block = var.enable_ipv6 && length(var.outpost_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.outpost_subnet_ipv6_prefixes[count.index]) : null
outpost_arn = var.outpost_arn
tags = merge(
{
"Name" = format(
"%s-${var.outpost_subnet_suffix}-%s",
var.name,
var.outpost_az,
)
},
var.tags,
var.outpost_subnet_tags,
)
}
##################
# Database subnet
##################
......@@ -585,6 +613,7 @@ resource "aws_default_network_acl" "this" {
aws_subnet.database.*.id,
aws_subnet.redshift.*.id,
aws_subnet.elasticache.*.id,
aws_subnet.outpost.*.id,
])),
compact(flatten([
aws_network_acl.public.*.subnet_ids,
......@@ -593,6 +622,7 @@ resource "aws_default_network_acl" "this" {
aws_network_acl.database.*.subnet_ids,
aws_network_acl.redshift.*.subnet_ids,
aws_network_acl.elasticache.*.subnet_ids,
aws_network_acl.outpost.*.subnet_ids,
]))
)
......@@ -738,6 +768,58 @@ resource "aws_network_acl_rule" "private_outbound" {
ipv6_cidr_block = lookup(var.private_outbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
#######################
# Outpost Network ACLs
#######################
resource "aws_network_acl" "outpost" {
count = var.create_vpc && var.outpost_dedicated_network_acl && length(var.outpost_subnets) > 0 ? 1 : 0
vpc_id = element(concat(aws_vpc.this.*.id, [""]), 0)
subnet_ids = aws_subnet.outpost.*.id
tags = merge(
{
"Name" = format("%s-${var.outpost_subnet_suffix}", var.name)
},
var.tags,
var.outpost_acl_tags,
)
}
resource "aws_network_acl_rule" "outpost_inbound" {
count = var.create_vpc && var.outpost_dedicated_network_acl && length(var.outpost_subnets) > 0 ? length(var.outpost_inbound_acl_rules) : 0
network_acl_id = aws_network_acl.outpost[0].id
egress = false
rule_number = var.outpost_inbound_acl_rules[count.index]["rule_number"]
rule_action = var.outpost_inbound_acl_rules[count.index]["rule_action"]
from_port = lookup(var.outpost_inbound_acl_rules[count.index], "from_port", null)
to_port = lookup(var.outpost_inbound_acl_rules[count.index], "to_port", null)
icmp_code = lookup(var.outpost_inbound_acl_rules[count.index], "icmp_code", null)
icmp_type = lookup(var.outpost_inbound_acl_rules[count.index], "icmp_type", null)
protocol = var.outpost_inbound_acl_rules[count.index]["protocol"]
cidr_block = lookup(var.outpost_inbound_acl_rules[count.index], "cidr_block", null)
ipv6_cidr_block = lookup(var.outpost_inbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
resource "aws_network_acl_rule" "outpost_outbound" {
count = var.create_vpc && var.outpost_dedicated_network_acl && length(var.outpost_subnets) > 0 ? length(var.outpost_outbound_acl_rules) : 0
network_acl_id = aws_network_acl.outpost[0].id
egress = true
rule_number = var.outpost_outbound_acl_rules[count.index]["rule_number"]
rule_action = var.outpost_outbound_acl_rules[count.index]["rule_action"]
from_port = lookup(var.outpost_outbound_acl_rules[count.index], "from_port", null)
to_port = lookup(var.outpost_outbound_acl_rules[count.index], "to_port", null)
icmp_code = lookup(var.outpost_outbound_acl_rules[count.index], "icmp_code", null)
icmp_type = lookup(var.outpost_outbound_acl_rules[count.index], "icmp_type", null)
protocol = var.outpost_outbound_acl_rules[count.index]["protocol"]
cidr_block = lookup(var.outpost_outbound_acl_rules[count.index], "cidr_block", null)
ipv6_cidr_block = lookup(var.outpost_outbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
########################
# Intra Network ACLs
########################
......@@ -1042,6 +1124,16 @@ resource "aws_route_table_association" "private" {
)
}
resource "aws_route_table_association" "outpost" {
count = var.create_vpc && length(var.outpost_subnets) > 0 ? length(var.outpost_subnets) : 0
subnet_id = element(aws_subnet.outpost.*.id, count.index)
route_table_id = element(
aws_route_table.private.*.id,
var.single_nat_gateway ? 0 : count.index,
)
}
resource "aws_route_table_association" "database" {
count = var.create_vpc && length(var.database_subnets) > 0 ? length(var.database_subnets) : 0
......@@ -1201,3 +1293,4 @@ resource "aws_default_vpc" "this" {
var.default_vpc_tags,
)
}
......@@ -108,6 +108,26 @@ output "public_subnets_ipv6_cidr_blocks" {
value = aws_subnet.public.*.ipv6_cidr_block
}
output "outpost_subnets" {
description = "List of IDs of outpost subnets"
value = aws_subnet.outpost.*.id
}
output "outpost_subnet_arns" {
description = "List of ARNs of outpost subnets"
value = aws_subnet.outpost.*.arn
}
output "outpost_subnets_cidr_blocks" {
description = "List of cidr_blocks of outpost subnets"
value = aws_subnet.outpost.*.cidr_block
}
output "outpost_subnets_ipv6_cidr_blocks" {
description = "List of IPv6 cidr_blocks of outpost subnets in an IPv6 enabled VPC"
value = aws_subnet.outpost.*.ipv6_cidr_block
}
output "database_subnets" {
description = "List of IDs of database subnets"
value = aws_subnet.database.*.id
......@@ -442,6 +462,16 @@ output "private_network_acl_arn" {
value = concat(aws_network_acl.private.*.arn, [""])[0]
}
output "outpost_network_acl_id" {
description = "ID of the outpost network ACL"
value = concat(aws_network_acl.outpost.*.id, [""])[0]
}
output "outpost_network_acl_arn" {
description = "ARN of the outpost network ACL"
value = concat(aws_network_acl.outpost.*.arn, [""])[0]
}
output "intra_network_acl_id" {
description = "ID of the intra network ACL"
value = concat(aws_network_acl.intra.*.id, [""])[0]
......
......@@ -34,6 +34,12 @@ variable "public_subnet_ipv6_prefixes" {
default = []
}
variable "outpost_subnet_ipv6_prefixes" {
description = "Assigns IPv6 outpost subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list"
type = list(string)
default = []
}
variable "database_subnet_ipv6_prefixes" {
description = "Assigns IPv6 database subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list"
type = list(string)
......@@ -76,6 +82,12 @@ variable "public_subnet_assign_ipv6_address_on_creation" {
default = null
}
variable "outpost_subnet_assign_ipv6_address_on_creation" {
description = "Assign IPv6 address on outpost subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
type = bool
default = null
}
variable "database_subnet_assign_ipv6_address_on_creation" {
description = "Assign IPv6 address on database subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
type = bool
......@@ -124,6 +136,12 @@ variable "private_subnet_suffix" {
default = "private"
}
variable "outpost_subnet_suffix" {
description = "Suffix to append to outpost subnets name"
type = string
default = "outpost"
}
variable "intra_subnet_suffix" {
description = "Suffix to append to intra subnets name"
type = string
......@@ -160,6 +178,12 @@ variable "private_subnets" {
default = []
}
variable "outpost_subnets" {
description = "A list of outpost subnets inside the VPC"
type = list(string)
default = []
}
variable "database_subnets" {
description = "A list of database subnets"
type = list(string)
......@@ -2267,6 +2291,12 @@ variable "private_subnet_tags" {
default = {}
}
variable "outpost_subnet_tags" {
description = "Additional tags for the outpost subnets"
type = map(string)
default = {}
}
variable "public_route_table_tags" {
description = "Additional tags for the public route tables"
type = map(string)
......@@ -2351,6 +2381,12 @@ variable "private_acl_tags" {
default = {}
}
variable "outpost_acl_tags" {
description = "Additional tags for the outpost subnets network ACL"
type = map(string)
default = {}
}
variable "intra_acl_tags" {
description = "Additional tags for the intra subnets network ACL"
type = map(string)
......@@ -2525,6 +2561,12 @@ variable "private_dedicated_network_acl" {
default = false
}
variable "outpost_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for outpost subnets"
type = bool
default = false
}
variable "intra_dedicated_network_acl" {
description = "Whether to use dedicated network ACL (not default) and custom rules for intra subnets"
type = bool
......@@ -2661,6 +2703,38 @@ variable "private_outbound_acl_rules" {
]
}
variable "outpost_inbound_acl_rules" {
description = "Outpost subnets inbound network ACLs"
type = list(map(string))
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "outpost_outbound_acl_rules" {
description = "Outpost subnets outbound network ACLs"
type = list(map(string))
default = [
{
rule_number = 100
rule_action = "allow"
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = "0.0.0.0/0"
},
]
}
variable "intra_inbound_acl_rules" {
description = "Intra subnets inbound network ACLs"
type = list(map(string))
......@@ -2902,3 +2976,15 @@ variable "create_egress_only_igw" {
type = bool
default = true
}
variable "outpost_arn" {
description = "ARN of Outpost you want to create a subnet in."
type = string
default = null
}
variable "outpost_az" {
description = "AZ where Outpost is anchored."
type = string
default = null
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment