From 247fc3ced1c877d79dad32247e75fb471f3f9c45 Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Sun, 26 Jan 2025 23:13:51 +0100 Subject: [PATCH 01/15] Adjust module for 2 new resources aws_vpc_block_public_access_options, aws_vpc_block_public_access_exclusion --- README.md | 9 +++++++-- main.tf | 30 ++++++++++++++++++++++++++++++ variables.tf | 18 ++++++++++++++++++ versions.tf | 2 +- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 97d959771..c3bd2a464 100644 --- a/README.md +++ b/README.md @@ -256,13 +256,13 @@ Full contributing [guidelines are covered here](.github/contributing.md). | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.46 | +| [aws](#requirement\_aws) | >= 5.79 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.46 | +| [aws](#provider\_aws) | >= 5.79 | ## Modules @@ -341,6 +341,8 @@ No modules. | [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 | | [aws_vpc.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource | +| [aws_vpc_block_public_access_exclusion.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_block_public_access_exclusion) | resource | +| [aws_vpc_block_public_access_options.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_block_public_access_options) | resource | | [aws_vpc_dhcp_options.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_dhcp_options) | resource | | [aws_vpc_dhcp_options_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_dhcp_options_association) | resource | | [aws_vpc_ipv4_cidr_block_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipv4_cidr_block_association) | resource | @@ -470,6 +472,8 @@ No modules. | [flow\_log\_traffic\_type](#input\_flow\_log\_traffic\_type) | The type of traffic to capture. Valid values: ACCEPT, REJECT, ALL | `string` | `"ALL"` | no | | [igw\_tags](#input\_igw\_tags) | Additional tags for the internet gateway | `map(string)` | `{}` | no | | [instance\_tenancy](#input\_instance\_tenancy) | A tenancy option for instances launched into the VPC | `string` | `"default"` | no | +| [internet\_gateway\_block\_enabled](#input\_internet\_gateway\_block\_enabled) | Enable AWS VPC Block Public Access Options. Default is `false` | `bool` | `false` | no | +| [internet\_gateway\_block\_mode](#input\_internet\_gateway\_block\_mode) | Block mode. Needs to be one of `block-bidirectional`, `block-ingress`, `off`. Default is `off` | `string` | `"off"` | no | | [intra\_acl\_tags](#input\_intra\_acl\_tags) | Additional tags for the intra subnets network ACL | `map(string)` | `{}` | no | | [intra\_dedicated\_network\_acl](#input\_intra\_dedicated\_network\_acl) | Whether to use dedicated network ACL (not default) and custom rules for intra subnets | `bool` | `false` | no | | [intra\_inbound\_acl\_rules](#input\_intra\_inbound\_acl\_rules) | Intra subnets inbound network ACLs | `list(map(string))` |
[
{
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_action": "allow",
"rule_number": 100,
"to_port": 0
}
]
| no | @@ -581,6 +585,7 @@ No modules. | [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\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions | `map(any)` | `{}` | no | | [vpc\_flow\_log\_iam\_policy\_name](#input\_vpc\_flow\_log\_iam\_policy\_name) | Name of the IAM policy | `string` | `"vpc-flow-log-to-cloudwatch"` | no | | [vpc\_flow\_log\_iam\_policy\_use\_name\_prefix](#input\_vpc\_flow\_log\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`vpc_flow_log_iam_policy_name`) is used as a prefix | `bool` | `true` | no | | [vpc\_flow\_log\_iam\_role\_name](#input\_vpc\_flow\_log\_iam\_role\_name) | Name to use on the VPC Flow Log IAM role created | `string` | `"vpc-flow-log-role"` | no | diff --git a/main.tf b/main.tf index 77cba6715..6ada30947 100644 --- a/main.tf +++ b/main.tf @@ -59,6 +59,36 @@ resource "aws_vpc_ipv4_cidr_block_association" "this" { cidr_block = element(var.secondary_cidr_blocks, count.index) } +resource "aws_vpc_block_public_access_options" "this" { + count = var.internet_gateway_block_enabled ? 1 : 0 + + internet_gateway_block_mode = var.internet_gateway_block_mode +} + +resource "aws_vpc_block_public_access_exclusion" "this" { + for_each = var.vpc_block_public_access_exclusions + + vpc_id = each.value.exclude_vpc ? local.vpc_id : null + + subnet_id = each.value.exclude_subnet ? lookup( + { + private = aws_subnet.private[*].id, + public = aws_subnet.public[*].id, + database = aws_subnet.database[*].id, + redshift = aws_subnet.redshift[*].id, + elasticache = aws_subnet.elasticache[*].id, + intra = aws_subnet.intra[*].id, + outpost = aws_subnet.outpost[*].id + }, + each.value.subnet_type, + null + )[each.value.subnet_index] : null + + internet_gateway_exclusion_mode = each.value.internet_gateway_exclusion_mode + + tags = var.tags +} + ################################################################################ # DHCP Options Set ################################################################################ diff --git a/variables.tf b/variables.tf index 095cc8bdf..1535821cf 100644 --- a/variables.tf +++ b/variables.tf @@ -116,6 +116,24 @@ variable "tags" { default = {} } +variable "internet_gateway_block_enabled" { + description = "Enable AWS VPC Block Public Access Options. Default is `false`" + type = bool + default = false +} + +variable "internet_gateway_block_mode" { + description = "Block mode. Needs to be one of `block-bidirectional`, `block-ingress`, `off`. Default is `off`" + type = string + default = "off" +} + +variable "vpc_block_public_access_exclusions" { + description = "List of VPC Block Public Access Exclusions" + type = map(any) + default = {} +} + ################################################################################ # DHCP Options Set ################################################################################ diff --git a/versions.tf b/versions.tf index e1ed6107f..8dceb0cc1 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.46" + version = ">= 5.79" } } } From 849840cb85bad564134eb46477c2cafaddf6bf88 Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 00:19:54 +0100 Subject: [PATCH 02/15] Add example with block public access --- README.md | 1 + examples/block-public-access/README.md | 208 +++++++++ examples/block-public-access/main.tf | 63 +++ examples/block-public-access/outputs.tf | 540 ++++++++++++++++++++++ examples/block-public-access/variables.tf | 0 examples/block-public-access/versions.tf | 10 + main.tf | 6 +- outputs.tf | 5 + 8 files changed, 831 insertions(+), 2 deletions(-) create mode 100644 examples/block-public-access/README.md create mode 100644 examples/block-public-access/main.tf create mode 100644 examples/block-public-access/outputs.tf create mode 100644 examples/block-public-access/variables.tf create mode 100644 examples/block-public-access/versions.tf diff --git a/README.md b/README.md index c3bd2a464..b191289b3 100644 --- a/README.md +++ b/README.md @@ -704,6 +704,7 @@ No modules. | [vgw\_arn](#output\_vgw\_arn) | The ARN of the VPN Gateway | | [vgw\_id](#output\_vgw\_id) | The ID of the VPN Gateway | | [vpc\_arn](#output\_vpc\_arn) | The ARN of the VPC | +| [vpc\_block\_public\_access\_exclusions](#output\_vpc\_block\_public\_access\_exclusions) | List of VPC block public access exclusions | | [vpc\_cidr\_block](#output\_vpc\_cidr\_block) | The CIDR block of the VPC | | [vpc\_enable\_dns\_hostnames](#output\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support | | [vpc\_enable\_dns\_support](#output\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support | diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md new file mode 100644 index 000000000..d8cdd1a33 --- /dev/null +++ b/examples/block-public-access/README.md @@ -0,0 +1,208 @@ +# VPC Security with Amazon VPC Block Public Access + +The configuration in this directory creates a VPC, route tables and a private subnet per availability zone. + +In addition to standard settings, new options for blocking public access have been introduced. There are several ways to define these options: + +- configure VPC Block Public Access Options e.g.: +```hcl + internet_gateway_block_enabled = true + internet_gateway_block_mode = "block-bidirectional" +``` + +- define VPC Block Public Access Exclusion at the VPC level e.g.: +```hcl + vpc_block_public_access_exclusions = { + exclude_vpc = { + exclude_vpc = true + internet_gateway_exclusion_mode = "allow-bidirectional" + } + } +``` +- define VPC Block Public Access Exclusion at the subnet level e.g.: +```hcl + vpc_block_public_access_exclusions = { + exclude_subnet_private1 = { + exclude_subnet = true + subnet_type = "private" + subnet_index = 1 + internet_gateway_exclusion_mode = "allow-egress" + } + exclude_subnet_private2 = { + exclude_subnet = true + subnet_type = "private" + subnet_index = 2 + internet_gateway_exclusion_mode = "allow-egress" + } + } +``` + +After creating VPC Block Public Access Options, you can verify them with the following command: + +```bash +aws ec2 --region eu-west-1 describe-vpc-block-public-access-options +``` + +Similarly, you can check VPC Block Public Access Exclusions by obtaining the exclusion ID from the Terraform state and running: + +```bash +aws ec2 --region eu-west-1 describe-vpc-block-public-access-exclusions --exclusion-ids exclusion-id +``` + +[Read more about enhancing VPC Security with Amazon VPC Block Public Access](https://aws.amazon.com/blogs/networking-and-content-delivery/vpc-block-public-access/). + +## 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. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.46 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.46 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [vpc](#module\_vpc) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [cgw\_arns](#output\_cgw\_arns) | List of ARNs of Customer Gateway | +| [cgw\_ids](#output\_cgw\_ids) | List of IDs of Customer Gateway | +| [database\_internet\_gateway\_route\_id](#output\_database\_internet\_gateway\_route\_id) | ID of the database internet gateway route | +| [database\_ipv6\_egress\_route\_id](#output\_database\_ipv6\_egress\_route\_id) | ID of the database IPv6 egress route | +| [database\_nat\_gateway\_route\_ids](#output\_database\_nat\_gateway\_route\_ids) | List of IDs of the database nat gateway route | +| [database\_network\_acl\_arn](#output\_database\_network\_acl\_arn) | ARN of the database network ACL | +| [database\_network\_acl\_id](#output\_database\_network\_acl\_id) | ID of the database network ACL | +| [database\_route\_table\_association\_ids](#output\_database\_route\_table\_association\_ids) | List of IDs of the database route table association | +| [database\_route\_table\_ids](#output\_database\_route\_table\_ids) | List of IDs of database route tables | +| [database\_subnet\_arns](#output\_database\_subnet\_arns) | List of ARNs of database subnets | +| [database\_subnet\_group](#output\_database\_subnet\_group) | ID of database subnet group | +| [database\_subnet\_group\_name](#output\_database\_subnet\_group\_name) | Name of database subnet group | +| [database\_subnets](#output\_database\_subnets) | List of IDs of database subnets | +| [database\_subnets\_cidr\_blocks](#output\_database\_subnets\_cidr\_blocks) | List of cidr\_blocks of database subnets | +| [database\_subnets\_ipv6\_cidr\_blocks](#output\_database\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of database subnets in an IPv6 enabled VPC | +| [default\_network\_acl\_id](#output\_default\_network\_acl\_id) | The ID of the default network ACL | +| [default\_route\_table\_id](#output\_default\_route\_table\_id) | The ID of the default route table | +| [default\_security\_group\_id](#output\_default\_security\_group\_id) | The ID of the security group created by default on VPC creation | +| [default\_vpc\_arn](#output\_default\_vpc\_arn) | The ARN of the Default VPC | +| [default\_vpc\_cidr\_block](#output\_default\_vpc\_cidr\_block) | The CIDR block of the Default VPC | +| [default\_vpc\_default\_network\_acl\_id](#output\_default\_vpc\_default\_network\_acl\_id) | The ID of the default network ACL of the Default VPC | +| [default\_vpc\_default\_route\_table\_id](#output\_default\_vpc\_default\_route\_table\_id) | The ID of the default route table of the Default VPC | +| [default\_vpc\_default\_security\_group\_id](#output\_default\_vpc\_default\_security\_group\_id) | The ID of the security group created by default on Default VPC creation | +| [default\_vpc\_enable\_dns\_hostnames](#output\_default\_vpc\_enable\_dns\_hostnames) | Whether or not the Default VPC has DNS hostname support | +| [default\_vpc\_enable\_dns\_support](#output\_default\_vpc\_enable\_dns\_support) | Whether or not the Default VPC has DNS support | +| [default\_vpc\_id](#output\_default\_vpc\_id) | The ID of the Default VPC | +| [default\_vpc\_instance\_tenancy](#output\_default\_vpc\_instance\_tenancy) | Tenancy of instances spin up within Default VPC | +| [default\_vpc\_main\_route\_table\_id](#output\_default\_vpc\_main\_route\_table\_id) | The ID of the main route table associated with the Default VPC | +| [dhcp\_options\_id](#output\_dhcp\_options\_id) | The ID of the DHCP options | +| [egress\_only\_internet\_gateway\_id](#output\_egress\_only\_internet\_gateway\_id) | The ID of the egress only Internet Gateway | +| [elasticache\_network\_acl\_arn](#output\_elasticache\_network\_acl\_arn) | ARN of the elasticache network ACL | +| [elasticache\_network\_acl\_id](#output\_elasticache\_network\_acl\_id) | ID of the elasticache network ACL | +| [elasticache\_route\_table\_association\_ids](#output\_elasticache\_route\_table\_association\_ids) | List of IDs of the elasticache route table association | +| [elasticache\_route\_table\_ids](#output\_elasticache\_route\_table\_ids) | List of IDs of elasticache route tables | +| [elasticache\_subnet\_arns](#output\_elasticache\_subnet\_arns) | List of ARNs of elasticache subnets | +| [elasticache\_subnet\_group](#output\_elasticache\_subnet\_group) | ID of elasticache subnet group | +| [elasticache\_subnet\_group\_name](#output\_elasticache\_subnet\_group\_name) | Name of elasticache subnet group | +| [elasticache\_subnets](#output\_elasticache\_subnets) | List of IDs of elasticache subnets | +| [elasticache\_subnets\_cidr\_blocks](#output\_elasticache\_subnets\_cidr\_blocks) | List of cidr\_blocks of elasticache subnets | +| [elasticache\_subnets\_ipv6\_cidr\_blocks](#output\_elasticache\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of elasticache subnets in an IPv6 enabled VPC | +| [igw\_arn](#output\_igw\_arn) | The ARN of the Internet Gateway | +| [igw\_id](#output\_igw\_id) | The ID of the Internet Gateway | +| [intra\_network\_acl\_arn](#output\_intra\_network\_acl\_arn) | ARN of the intra network ACL | +| [intra\_network\_acl\_id](#output\_intra\_network\_acl\_id) | ID of the intra network ACL | +| [intra\_route\_table\_association\_ids](#output\_intra\_route\_table\_association\_ids) | List of IDs of the intra route table association | +| [intra\_route\_table\_ids](#output\_intra\_route\_table\_ids) | List of IDs of intra route tables | +| [intra\_subnet\_arns](#output\_intra\_subnet\_arns) | List of ARNs of intra subnets | +| [intra\_subnets](#output\_intra\_subnets) | List of IDs of intra subnets | +| [intra\_subnets\_cidr\_blocks](#output\_intra\_subnets\_cidr\_blocks) | List of cidr\_blocks of intra subnets | +| [intra\_subnets\_ipv6\_cidr\_blocks](#output\_intra\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of intra subnets in an IPv6 enabled VPC | +| [nat\_ids](#output\_nat\_ids) | List of allocation ID of Elastic IPs created for AWS NAT Gateway | +| [nat\_public\_ips](#output\_nat\_public\_ips) | List of public Elastic IPs created for AWS NAT Gateway | +| [natgw\_ids](#output\_natgw\_ids) | List of NAT Gateway IDs | +| [outpost\_network\_acl\_arn](#output\_outpost\_network\_acl\_arn) | ARN of the outpost network ACL | +| [outpost\_network\_acl\_id](#output\_outpost\_network\_acl\_id) | ID of the outpost network ACL | +| [outpost\_subnet\_arns](#output\_outpost\_subnet\_arns) | List of ARNs of outpost subnets | +| [outpost\_subnets](#output\_outpost\_subnets) | List of IDs of outpost subnets | +| [outpost\_subnets\_cidr\_blocks](#output\_outpost\_subnets\_cidr\_blocks) | List of cidr\_blocks of outpost subnets | +| [outpost\_subnets\_ipv6\_cidr\_blocks](#output\_outpost\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of outpost subnets in an IPv6 enabled VPC | +| [private\_ipv6\_egress\_route\_ids](#output\_private\_ipv6\_egress\_route\_ids) | List of IDs of the ipv6 egress route | +| [private\_nat\_gateway\_route\_ids](#output\_private\_nat\_gateway\_route\_ids) | List of IDs of the private nat gateway route | +| [private\_network\_acl\_arn](#output\_private\_network\_acl\_arn) | ARN of the private network ACL | +| [private\_network\_acl\_id](#output\_private\_network\_acl\_id) | ID of the private network ACL | +| [private\_route\_table\_association\_ids](#output\_private\_route\_table\_association\_ids) | List of IDs of the private route table association | +| [private\_route\_table\_ids](#output\_private\_route\_table\_ids) | List of IDs of private route tables | +| [private\_subnet\_arns](#output\_private\_subnet\_arns) | List of ARNs of private subnets | +| [private\_subnets](#output\_private\_subnets) | List of IDs of private subnets | +| [private\_subnets\_cidr\_blocks](#output\_private\_subnets\_cidr\_blocks) | List of cidr\_blocks of private subnets | +| [private\_subnets\_ipv6\_cidr\_blocks](#output\_private\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of private subnets in an IPv6 enabled VPC | +| [public\_internet\_gateway\_ipv6\_route\_id](#output\_public\_internet\_gateway\_ipv6\_route\_id) | ID of the IPv6 internet gateway route | +| [public\_internet\_gateway\_route\_id](#output\_public\_internet\_gateway\_route\_id) | ID of the internet gateway route | +| [public\_network\_acl\_arn](#output\_public\_network\_acl\_arn) | ARN of the public network ACL | +| [public\_network\_acl\_id](#output\_public\_network\_acl\_id) | ID of the public network ACL | +| [public\_route\_table\_association\_ids](#output\_public\_route\_table\_association\_ids) | List of IDs of the public route table association | +| [public\_route\_table\_ids](#output\_public\_route\_table\_ids) | List of IDs of public route tables | +| [public\_subnet\_arns](#output\_public\_subnet\_arns) | List of ARNs of public subnets | +| [public\_subnets](#output\_public\_subnets) | List of IDs of public subnets | +| [public\_subnets\_cidr\_blocks](#output\_public\_subnets\_cidr\_blocks) | List of cidr\_blocks of public subnets | +| [public\_subnets\_ipv6\_cidr\_blocks](#output\_public\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of public subnets in an IPv6 enabled VPC | +| [redshift\_network\_acl\_arn](#output\_redshift\_network\_acl\_arn) | ARN of the redshift network ACL | +| [redshift\_network\_acl\_id](#output\_redshift\_network\_acl\_id) | ID of the redshift network ACL | +| [redshift\_public\_route\_table\_association\_ids](#output\_redshift\_public\_route\_table\_association\_ids) | List of IDs of the public redshift route table association | +| [redshift\_route\_table\_association\_ids](#output\_redshift\_route\_table\_association\_ids) | List of IDs of the redshift route table association | +| [redshift\_route\_table\_ids](#output\_redshift\_route\_table\_ids) | List of IDs of redshift route tables | +| [redshift\_subnet\_arns](#output\_redshift\_subnet\_arns) | List of ARNs of redshift subnets | +| [redshift\_subnet\_group](#output\_redshift\_subnet\_group) | ID of redshift subnet group | +| [redshift\_subnets](#output\_redshift\_subnets) | List of IDs of redshift subnets | +| [redshift\_subnets\_cidr\_blocks](#output\_redshift\_subnets\_cidr\_blocks) | List of cidr\_blocks of redshift subnets | +| [redshift\_subnets\_ipv6\_cidr\_blocks](#output\_redshift\_subnets\_ipv6\_cidr\_blocks) | List of IPv6 cidr\_blocks of redshift subnets in an IPv6 enabled VPC | +| [this\_customer\_gateway](#output\_this\_customer\_gateway) | Map of Customer Gateway attributes | +| [vgw\_arn](#output\_vgw\_arn) | The ARN of the VPN Gateway | +| [vgw\_id](#output\_vgw\_id) | The ID of the VPN Gateway | +| [vpc\_arn](#output\_vpc\_arn) | The ARN of the VPC | +| [vpc\_block\_public\_access\_exclusions](#output\_vpc\_block\_public\_access\_exclusions) | List of VPC block public access exclusions | +| [vpc\_cidr\_block](#output\_vpc\_cidr\_block) | The CIDR block of the VPC | +| [vpc\_enable\_dns\_hostnames](#output\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support | +| [vpc\_enable\_dns\_support](#output\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support | +| [vpc\_flow\_log\_cloudwatch\_iam\_role\_arn](#output\_vpc\_flow\_log\_cloudwatch\_iam\_role\_arn) | The ARN of the IAM role used when pushing logs to Cloudwatch log group | +| [vpc\_flow\_log\_destination\_arn](#output\_vpc\_flow\_log\_destination\_arn) | The ARN of the destination for VPC Flow Logs | +| [vpc\_flow\_log\_destination\_type](#output\_vpc\_flow\_log\_destination\_type) | The type of the destination for VPC Flow Logs | +| [vpc\_flow\_log\_id](#output\_vpc\_flow\_log\_id) | The ID of the Flow Log resource | +| [vpc\_id](#output\_vpc\_id) | The ID of the VPC | +| [vpc\_instance\_tenancy](#output\_vpc\_instance\_tenancy) | Tenancy of instances spin up within VPC | +| [vpc\_ipv6\_association\_id](#output\_vpc\_ipv6\_association\_id) | The association ID for the IPv6 CIDR block | +| [vpc\_ipv6\_cidr\_block](#output\_vpc\_ipv6\_cidr\_block) | The IPv6 CIDR block | +| [vpc\_main\_route\_table\_id](#output\_vpc\_main\_route\_table\_id) | The ID of the main route table associated with this VPC | +| [vpc\_owner\_id](#output\_vpc\_owner\_id) | The ID of the AWS account that owns the VPC | +| [vpc\_secondary\_cidr\_blocks](#output\_vpc\_secondary\_cidr\_blocks) | List of secondary CIDR blocks of the VPC | + diff --git a/examples/block-public-access/main.tf b/examples/block-public-access/main.tf new file mode 100644 index 000000000..43417f3a4 --- /dev/null +++ b/examples/block-public-access/main.tf @@ -0,0 +1,63 @@ +provider "aws" { + region = local.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Example = local.name + GithubRepo = "terraform-aws-vpc" + GithubOrg = "terraform-aws-modules" + } +} + +################################################################################ +# VPC Module +################################################################################ + +module "vpc" { + source = "../../" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] + + ### VPC Block Public Access Options + # internet_gateway_block_enabled = true + # internet_gateway_block_mode = "block-bidirectional" + + ### VPC Block Public Access Exclusion at the VPC level + # vpc_block_public_access_exclusions = { + # exclude_vpc = { + # exclude_vpc = true + # internet_gateway_exclusion_mode = "allow-bidirectional" + # } + # } + + ### VPC Block Public Access Exclusion at the subnet level + vpc_block_public_access_exclusions = { + exclude_subnet_private1 = { + exclude_subnet = true + subnet_type = "private" + subnet_index = 1 + internet_gateway_exclusion_mode = "allow-egress" + } + exclude_subnet_private2 = { + exclude_subnet = true + subnet_type = "private" + subnet_index = 2 + internet_gateway_exclusion_mode = "allow-egress" + } + } + + tags = local.tags +} diff --git a/examples/block-public-access/outputs.tf b/examples/block-public-access/outputs.tf new file mode 100644 index 000000000..67375a118 --- /dev/null +++ b/examples/block-public-access/outputs.tf @@ -0,0 +1,540 @@ +output "vpc_id" { + description = "The ID of the VPC" + value = module.vpc.vpc_id +} + +output "vpc_arn" { + description = "The ARN of the VPC" + value = module.vpc.vpc_arn +} + +output "vpc_cidr_block" { + description = "The CIDR block of the VPC" + value = module.vpc.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 +} + +output "default_network_acl_id" { + description = "The ID of the default network ACL" + value = module.vpc.default_network_acl_id +} + +output "default_route_table_id" { + description = "The ID of the default route table" + value = module.vpc.default_route_table_id +} + +output "vpc_instance_tenancy" { + description = "Tenancy of instances spin up within VPC" + value = module.vpc.vpc_instance_tenancy +} + +output "vpc_enable_dns_support" { + description = "Whether or not the VPC has DNS support" + value = module.vpc.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 +} + +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 +} + +output "vpc_ipv6_association_id" { + description = "The association ID for the IPv6 CIDR block" + value = module.vpc.vpc_ipv6_association_id +} + +output "vpc_ipv6_cidr_block" { + description = "The IPv6 CIDR block" + value = module.vpc.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 +} + +output "vpc_owner_id" { + description = "The ID of the AWS account that owns the VPC" + value = module.vpc.vpc_owner_id +} + +output "vpc_block_public_access_exclusions" { + description = "List of VPC block public access exclusions" + value = module.vpc.vpc_block_public_access_exclusions +} + +output "private_subnets" { + description = "List of IDs of private subnets" + value = module.vpc.private_subnets +} + +output "private_subnet_arns" { + description = "List of ARNs of private subnets" + value = module.vpc.private_subnet_arns +} + +output "private_subnets_cidr_blocks" { + description = "List of cidr_blocks of private subnets" + value = module.vpc.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 +} + +output "public_subnets" { + description = "List of IDs of public subnets" + value = module.vpc.public_subnets +} + +output "public_subnet_arns" { + description = "List of ARNs of public subnets" + value = module.vpc.public_subnet_arns +} + +output "public_subnets_cidr_blocks" { + description = "List of cidr_blocks of public subnets" + value = module.vpc.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 +} + +output "outpost_subnets" { + description = "List of IDs of outpost subnets" + value = module.vpc.outpost_subnets +} + +output "outpost_subnet_arns" { + description = "List of ARNs of outpost subnets" + value = module.vpc.outpost_subnet_arns +} + +output "outpost_subnets_cidr_blocks" { + description = "List of cidr_blocks of outpost subnets" + value = module.vpc.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 +} + +output "database_subnets" { + description = "List of IDs of database subnets" + value = module.vpc.database_subnets +} + +output "database_subnet_arns" { + description = "List of ARNs of database subnets" + value = module.vpc.database_subnet_arns +} + +output "database_subnets_cidr_blocks" { + description = "List of cidr_blocks of database subnets" + value = module.vpc.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 +} + +output "database_subnet_group" { + description = "ID of database subnet group" + value = module.vpc.database_subnet_group +} + +output "database_subnet_group_name" { + description = "Name of database subnet group" + value = module.vpc.database_subnet_group_name +} + +output "redshift_subnets" { + description = "List of IDs of redshift subnets" + value = module.vpc.redshift_subnets +} + +output "redshift_subnet_arns" { + description = "List of ARNs of redshift subnets" + value = module.vpc.redshift_subnet_arns +} + +output "redshift_subnets_cidr_blocks" { + description = "List of cidr_blocks of redshift subnets" + value = module.vpc.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 +} + +output "redshift_subnet_group" { + description = "ID of redshift subnet group" + value = module.vpc.redshift_subnet_group +} + +output "elasticache_subnets" { + description = "List of IDs of elasticache subnets" + value = module.vpc.elasticache_subnets +} + +output "elasticache_subnet_arns" { + description = "List of ARNs of elasticache subnets" + value = module.vpc.elasticache_subnet_arns +} + +output "elasticache_subnets_cidr_blocks" { + description = "List of cidr_blocks of elasticache subnets" + value = module.vpc.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 +} + +output "intra_subnets" { + description = "List of IDs of intra subnets" + value = module.vpc.intra_subnets +} + +output "intra_subnet_arns" { + description = "List of ARNs of intra subnets" + value = module.vpc.intra_subnet_arns +} + +output "intra_subnets_cidr_blocks" { + description = "List of cidr_blocks of intra subnets" + value = module.vpc.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 +} + +output "elasticache_subnet_group" { + description = "ID of elasticache subnet group" + value = module.vpc.elasticache_subnet_group +} + +output "elasticache_subnet_group_name" { + description = "Name of elasticache subnet group" + value = module.vpc.elasticache_subnet_group_name +} + +output "public_route_table_ids" { + description = "List of IDs of public route tables" + value = module.vpc.public_route_table_ids +} + +output "private_route_table_ids" { + description = "List of IDs of private route tables" + value = module.vpc.private_route_table_ids +} + +output "database_route_table_ids" { + description = "List of IDs of database route tables" + value = module.vpc.database_route_table_ids +} + +output "redshift_route_table_ids" { + description = "List of IDs of redshift route tables" + value = module.vpc.redshift_route_table_ids +} + +output "elasticache_route_table_ids" { + description = "List of IDs of elasticache route tables" + value = module.vpc.elasticache_route_table_ids +} + +output "intra_route_table_ids" { + description = "List of IDs of intra route tables" + value = module.vpc.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 +} + +output "public_internet_gateway_ipv6_route_id" { + description = "ID of the IPv6 internet gateway route" + value = module.vpc.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 +} + +output "database_nat_gateway_route_ids" { + description = "List of IDs of the database nat gateway route" + value = module.vpc.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 +} + +output "private_nat_gateway_route_ids" { + description = "List of IDs of the private nat gateway route" + value = module.vpc.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 +} + +output "private_route_table_association_ids" { + description = "List of IDs of the private route table association" + value = module.vpc.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 +} + +output "redshift_route_table_association_ids" { + description = "List of IDs of the redshift route table association" + value = module.vpc.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 +} + +output "elasticache_route_table_association_ids" { + description = "List of IDs of the elasticache route table association" + value = module.vpc.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 +} + +output "public_route_table_association_ids" { + description = "List of IDs of the public route table association" + value = module.vpc.public_route_table_association_ids +} + +output "dhcp_options_id" { + description = "The ID of the DHCP options" + value = module.vpc.dhcp_options_id +} + +output "nat_ids" { + description = "List of allocation ID of Elastic IPs created for AWS NAT Gateway" + value = module.vpc.nat_ids +} + +output "nat_public_ips" { + description = "List of public Elastic IPs created for AWS NAT Gateway" + value = module.vpc.nat_public_ips +} + +output "natgw_ids" { + description = "List of NAT Gateway IDs" + value = module.vpc.natgw_ids +} + +output "igw_id" { + description = "The ID of the Internet Gateway" + value = module.vpc.igw_id +} + +output "igw_arn" { + description = "The ARN of the Internet Gateway" + value = module.vpc.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 +} + +output "cgw_ids" { + description = "List of IDs of Customer Gateway" + value = module.vpc.cgw_ids +} + +output "cgw_arns" { + description = "List of ARNs of Customer Gateway" + value = module.vpc.cgw_arns +} + +output "this_customer_gateway" { + description = "Map of Customer Gateway attributes" + value = module.vpc.this_customer_gateway +} + +output "vgw_id" { + description = "The ID of the VPN Gateway" + value = module.vpc.vgw_id +} + +output "vgw_arn" { + description = "The ARN of the VPN Gateway" + value = module.vpc.vgw_arn +} + +output "default_vpc_id" { + description = "The ID of the Default VPC" + value = module.vpc.default_vpc_id +} + +output "default_vpc_arn" { + description = "The ARN of the Default VPC" + value = module.vpc.default_vpc_arn +} + +output "default_vpc_cidr_block" { + description = "The CIDR block of the Default VPC" + value = module.vpc.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 +} + +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 +} + +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 +} + +output "default_vpc_instance_tenancy" { + description = "Tenancy of instances spin up within Default VPC" + value = module.vpc.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 +} + +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 +} + +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 +} + +output "public_network_acl_id" { + description = "ID of the public network ACL" + value = module.vpc.public_network_acl_id +} + +output "public_network_acl_arn" { + description = "ARN of the public network ACL" + value = module.vpc.public_network_acl_arn +} + +output "private_network_acl_id" { + description = "ID of the private network ACL" + value = module.vpc.private_network_acl_id +} + +output "private_network_acl_arn" { + description = "ARN of the private network ACL" + value = module.vpc.private_network_acl_arn +} + +output "outpost_network_acl_id" { + description = "ID of the outpost network ACL" + value = module.vpc.outpost_network_acl_id +} + +output "outpost_network_acl_arn" { + description = "ARN of the outpost network ACL" + value = module.vpc.outpost_network_acl_arn +} + +output "intra_network_acl_id" { + description = "ID of the intra network ACL" + value = module.vpc.intra_network_acl_id +} + +output "intra_network_acl_arn" { + description = "ARN of the intra network ACL" + value = module.vpc.intra_network_acl_arn +} + +output "database_network_acl_id" { + description = "ID of the database network ACL" + value = module.vpc.database_network_acl_id +} + +output "database_network_acl_arn" { + description = "ARN of the database network ACL" + value = module.vpc.database_network_acl_arn +} + +output "redshift_network_acl_id" { + description = "ID of the redshift network ACL" + value = module.vpc.redshift_network_acl_id +} + +output "redshift_network_acl_arn" { + description = "ARN of the redshift network ACL" + value = module.vpc.redshift_network_acl_arn +} + +output "elasticache_network_acl_id" { + description = "ID of the elasticache network ACL" + value = module.vpc.elasticache_network_acl_id +} + +output "elasticache_network_acl_arn" { + description = "ARN of the elasticache network ACL" + value = module.vpc.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 +} + +output "vpc_flow_log_destination_arn" { + description = "The ARN of the destination for VPC Flow Logs" + value = module.vpc.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 +} + +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 +} diff --git a/examples/block-public-access/variables.tf b/examples/block-public-access/variables.tf new file mode 100644 index 000000000..e69de29bb diff --git a/examples/block-public-access/versions.tf b/examples/block-public-access/versions.tf new file mode 100644 index 000000000..e1ed6107f --- /dev/null +++ b/examples/block-public-access/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.46" + } + } +} diff --git a/main.tf b/main.tf index 6ada30947..638e1e805 100644 --- a/main.tf +++ b/main.tf @@ -59,18 +59,20 @@ resource "aws_vpc_ipv4_cidr_block_association" "this" { cidr_block = element(var.secondary_cidr_blocks, count.index) } +# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_block_public_access_options resource "aws_vpc_block_public_access_options" "this" { count = var.internet_gateway_block_enabled ? 1 : 0 internet_gateway_block_mode = var.internet_gateway_block_mode } +# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_block_public_access_exclusion resource "aws_vpc_block_public_access_exclusion" "this" { for_each = var.vpc_block_public_access_exclusions - vpc_id = each.value.exclude_vpc ? local.vpc_id : null + vpc_id = lookup(each.value, "exclude_vpc", false) ? local.vpc_id : null - subnet_id = each.value.exclude_subnet ? lookup( + subnet_id = lookup(each.value, "exclude_subnet", false) ? lookup( { private = aws_subnet.private[*].id, public = aws_subnet.public[*].id, diff --git a/outputs.tf b/outputs.tf index c2367e210..bc1a9bf80 100644 --- a/outputs.tf +++ b/outputs.tf @@ -78,6 +78,11 @@ output "vpc_owner_id" { value = try(aws_vpc.this[0].owner_id, null) } +output "vpc_block_public_access_exclusions" { + description = "List of VPC block public access exclusions" + value = [for k, v in aws_vpc_block_public_access_exclusion.this : v.id] +} + ################################################################################ # DHCP Options Set ################################################################################ From 847fd1372d7b7e0bb71b5224778914be361d857f Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 00:24:11 +0100 Subject: [PATCH 03/15] Update README --- examples/block-public-access/README.md | 34 ++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md index d8cdd1a33..4a59e9d1d 100644 --- a/examples/block-public-access/README.md +++ b/examples/block-public-access/README.md @@ -2,7 +2,23 @@ The configuration in this directory creates a VPC, route tables and a private subnet per availability zone. -In addition to standard settings, new options for blocking public access have been introduced. There are several ways to define these options: +In addition to standard settings, new options for blocking public access have been introduced. + +[Read more about enhancing VPC Security with Amazon VPC Block Public Access](https://aws.amazon.com/blogs/networking-and-content-delivery/vpc-block-public-access/). + +## 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. + +This example defines VPC Block Public Access Exclusion at the subnet level, but other possibilities are also available and are commented on in the code. There are several ways to define these options: - configure VPC Block Public Access Options e.g.: ```hcl @@ -46,23 +62,11 @@ aws ec2 --region eu-west-1 describe-vpc-block-public-access-options Similarly, you can check VPC Block Public Access Exclusions by obtaining the exclusion ID from the Terraform state and running: ```bash -aws ec2 --region eu-west-1 describe-vpc-block-public-access-exclusions --exclusion-ids exclusion-id -``` - -[Read more about enhancing VPC Security with Amazon VPC Block Public Access](https://aws.amazon.com/blogs/networking-and-content-delivery/vpc-block-public-access/). - -## Usage - -To run this example you need to execute: +terraform output vpc_block_public_access_exclusions -```bash -$ terraform init -$ terraform plan -$ terraform apply +aws ec2 --region eu-west-1 describe-vpc-block-public-access-exclusions --exclusion-ids exclusion-id ``` -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. - ## Requirements From a1202f23dd0c6b4a49318f9fed2687a9c21f243b Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:09:42 +0100 Subject: [PATCH 04/15] Update main.tf Co-authored-by: Anton Babenko --- main.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/main.tf b/main.tf index 638e1e805..8f7459f14 100644 --- a/main.tf +++ b/main.tf @@ -59,7 +59,6 @@ resource "aws_vpc_ipv4_cidr_block_association" "this" { cidr_block = element(var.secondary_cidr_blocks, count.index) } -# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_block_public_access_options resource "aws_vpc_block_public_access_options" "this" { count = var.internet_gateway_block_enabled ? 1 : 0 From 2deaac5ef51067a04b0b92a32931b02f691a8b31 Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:09:49 +0100 Subject: [PATCH 05/15] Update main.tf Co-authored-by: Anton Babenko --- main.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/main.tf b/main.tf index 8f7459f14..e43e2b7de 100644 --- a/main.tf +++ b/main.tf @@ -65,7 +65,6 @@ resource "aws_vpc_block_public_access_options" "this" { internet_gateway_block_mode = var.internet_gateway_block_mode } -# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_block_public_access_exclusion resource "aws_vpc_block_public_access_exclusion" "this" { for_each = var.vpc_block_public_access_exclusions From 24cdacdd095677cb6dc4070c5e3e4445bf6b654c Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:10:59 +0100 Subject: [PATCH 06/15] Update examples/block-public-access/versions.tf Co-authored-by: Anton Babenko --- examples/block-public-access/versions.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/block-public-access/versions.tf b/examples/block-public-access/versions.tf index e1ed6107f..8dceb0cc1 100644 --- a/examples/block-public-access/versions.tf +++ b/examples/block-public-access/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.46" + version = ">= 5.79" } } } From 593f75593c9237a3eb67f4c1203339bc4edcaab9 Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:11:16 +0100 Subject: [PATCH 07/15] Update main.tf Co-authored-by: Anton Babenko --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index e43e2b7de..eb1fe51e3 100644 --- a/main.tf +++ b/main.tf @@ -60,7 +60,7 @@ resource "aws_vpc_ipv4_cidr_block_association" "this" { } resource "aws_vpc_block_public_access_options" "this" { - count = var.internet_gateway_block_enabled ? 1 : 0 + count = local.create_vpc && length(keys(var.vpc_block_public_access_options)) ? 1 : 0 internet_gateway_block_mode = var.internet_gateway_block_mode } From 73a3c2ef68cd7c166aabbfb927aa823e13a1ecd9 Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:12:14 +0100 Subject: [PATCH 08/15] Update main.tf Co-authored-by: Anton Babenko --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index eb1fe51e3..de10f17f4 100644 --- a/main.tf +++ b/main.tf @@ -62,7 +62,7 @@ resource "aws_vpc_ipv4_cidr_block_association" "this" { resource "aws_vpc_block_public_access_options" "this" { count = local.create_vpc && length(keys(var.vpc_block_public_access_options)) ? 1 : 0 - internet_gateway_block_mode = var.internet_gateway_block_mode + internet_gateway_block_mode = try(var.vpc_block_public_access_options["internet_gateway_block_mode"], null) } resource "aws_vpc_block_public_access_exclusion" "this" { From 608eb2acd306e5558f1e917e775f03cf41848920 Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:12:21 +0100 Subject: [PATCH 09/15] Update main.tf Co-authored-by: Anton Babenko --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index de10f17f4..0824aebf4 100644 --- a/main.tf +++ b/main.tf @@ -66,7 +66,7 @@ resource "aws_vpc_block_public_access_options" "this" { } resource "aws_vpc_block_public_access_exclusion" "this" { - for_each = var.vpc_block_public_access_exclusions + for_each = {for k, v in var.vpc_block_public_access_exclusions: k => v if local.create_vpc} vpc_id = lookup(each.value, "exclude_vpc", false) ? local.vpc_id : null From dccb97c2df86336aff160885a3a0952636cf39cd Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:23:58 +0100 Subject: [PATCH 10/15] Update variables definitions --- README.md | 3 +-- examples/block-public-access/README.md | 4 ++-- examples/block-public-access/main.tf | 5 +++-- main.tf | 4 ++-- variables.tf | 14 ++++---------- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b191289b3..66e50682b 100644 --- a/README.md +++ b/README.md @@ -472,8 +472,6 @@ No modules. | [flow\_log\_traffic\_type](#input\_flow\_log\_traffic\_type) | The type of traffic to capture. Valid values: ACCEPT, REJECT, ALL | `string` | `"ALL"` | no | | [igw\_tags](#input\_igw\_tags) | Additional tags for the internet gateway | `map(string)` | `{}` | no | | [instance\_tenancy](#input\_instance\_tenancy) | A tenancy option for instances launched into the VPC | `string` | `"default"` | no | -| [internet\_gateway\_block\_enabled](#input\_internet\_gateway\_block\_enabled) | Enable AWS VPC Block Public Access Options. Default is `false` | `bool` | `false` | no | -| [internet\_gateway\_block\_mode](#input\_internet\_gateway\_block\_mode) | Block mode. Needs to be one of `block-bidirectional`, `block-ingress`, `off`. Default is `off` | `string` | `"off"` | no | | [intra\_acl\_tags](#input\_intra\_acl\_tags) | Additional tags for the intra subnets network ACL | `map(string)` | `{}` | no | | [intra\_dedicated\_network\_acl](#input\_intra\_dedicated\_network\_acl) | Whether to use dedicated network ACL (not default) and custom rules for intra subnets | `bool` | `false` | no | | [intra\_inbound\_acl\_rules](#input\_intra\_inbound\_acl\_rules) | Intra subnets inbound network ACLs | `list(map(string))` |
[
{
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_action": "allow",
"rule_number": 100,
"to_port": 0
}
]
| no | @@ -586,6 +584,7 @@ No modules. | [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\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions | `map(any)` | `{}` | no | +| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options | `map(string)` | `{}` | no | | [vpc\_flow\_log\_iam\_policy\_name](#input\_vpc\_flow\_log\_iam\_policy\_name) | Name of the IAM policy | `string` | `"vpc-flow-log-to-cloudwatch"` | no | | [vpc\_flow\_log\_iam\_policy\_use\_name\_prefix](#input\_vpc\_flow\_log\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`vpc_flow_log_iam_policy_name`) is used as a prefix | `bool` | `true` | no | | [vpc\_flow\_log\_iam\_role\_name](#input\_vpc\_flow\_log\_iam\_role\_name) | Name to use on the VPC Flow Log IAM role created | `string` | `"vpc-flow-log-role"` | no | diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md index 4a59e9d1d..048b54b16 100644 --- a/examples/block-public-access/README.md +++ b/examples/block-public-access/README.md @@ -73,13 +73,13 @@ aws ec2 --region eu-west-1 describe-vpc-block-public-access-exclusions --exclusi | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.46 | +| [aws](#requirement\_aws) | >= 5.79 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.46 | +| [aws](#provider\_aws) | >= 5.79 | ## Modules diff --git a/examples/block-public-access/main.tf b/examples/block-public-access/main.tf index 43417f3a4..468896295 100644 --- a/examples/block-public-access/main.tf +++ b/examples/block-public-access/main.tf @@ -32,8 +32,9 @@ module "vpc" { private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] ### VPC Block Public Access Options - # internet_gateway_block_enabled = true - # internet_gateway_block_mode = "block-bidirectional" + vpc_block_public_access_options = { + internet_gateway_block_mode = "block-bidirectional" + } ### VPC Block Public Access Exclusion at the VPC level # vpc_block_public_access_exclusions = { diff --git a/main.tf b/main.tf index 0824aebf4..82faa7eee 100644 --- a/main.tf +++ b/main.tf @@ -60,13 +60,13 @@ resource "aws_vpc_ipv4_cidr_block_association" "this" { } resource "aws_vpc_block_public_access_options" "this" { - count = local.create_vpc && length(keys(var.vpc_block_public_access_options)) ? 1 : 0 + count = local.create_vpc && length(keys(var.vpc_block_public_access_options)) > 0 ? 1 : 0 internet_gateway_block_mode = try(var.vpc_block_public_access_options["internet_gateway_block_mode"], null) } resource "aws_vpc_block_public_access_exclusion" "this" { - for_each = {for k, v in var.vpc_block_public_access_exclusions: k => v if local.create_vpc} + for_each = { for k, v in var.vpc_block_public_access_exclusions : k => v if local.create_vpc } vpc_id = lookup(each.value, "exclude_vpc", false) ? local.vpc_id : null diff --git a/variables.tf b/variables.tf index 1535821cf..193f19dda 100644 --- a/variables.tf +++ b/variables.tf @@ -116,16 +116,10 @@ variable "tags" { default = {} } -variable "internet_gateway_block_enabled" { - description = "Enable AWS VPC Block Public Access Options. Default is `false`" - type = bool - default = false -} - -variable "internet_gateway_block_mode" { - description = "Block mode. Needs to be one of `block-bidirectional`, `block-ingress`, `off`. Default is `off`" - type = string - default = "off" +variable "vpc_block_public_access_options" { + description = "Map of VPC Block Public Access Options" + type = map(string) + default = {} } variable "vpc_block_public_access_exclusions" { From d50a3cb64fface7938a27e07d31a50506ad04b5d Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Mon, 27 Jan 2025 23:39:53 +0100 Subject: [PATCH 11/15] Update variables description --- README.md | 4 +-- examples/block-public-access/README.md | 5 +-- examples/block-public-access/main.tf | 38 +++++++++++----------- variables.tf | 45 ++++++++++++++++++++++++-- 4 files changed, 67 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 66e50682b..f1e22af89 100644 --- a/README.md +++ b/README.md @@ -583,8 +583,8 @@ No modules. | [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\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions | `map(any)` | `{}` | no | -| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options | `map(string)` | `{}` | no | +| [vpc\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions e.g. to exclude the VPC:

vpc\_block\_public\_access\_exclusions = {
exclude\_vpc = {
exclude\_vpc = true
internet\_gateway\_exclusion\_mode = "allow-bidirectional"
}
}

or to exclude specific subnets:

vpc\_block\_public\_access\_exclusions = {
exclude\_subnet\_private1 = {
exclude\_subnet = true
subnet\_type = "private"
subnet\_index = 1
internet\_gateway\_exclusion\_mode = "allow-egress"
}
exclude\_subnet\_private2 = {
exclude\_subnet = true
subnet\_type = "private"
subnet\_index = 2
internet\_gateway\_exclusion\_mode = "allow-egress"
}
}

One of `exclude_vpc` or `exclude_subnet` must be set to true.
Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`.
Value of `subnet_index` is the index of the subnet in the corresponding subnet list.
Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. | `map(any)` | `{}` | no | +| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options e.g.:

vpc\_block\_public\_access\_options = {
internet\_gateway\_block\_mode = "block-bidirectional"
}

Currently only `internet_gateway_block_mode` is supported, for which
valid values are `block-bidirectional`, `block-ingress` and `off`. | `map(string)` | `{}` | no | | [vpc\_flow\_log\_iam\_policy\_name](#input\_vpc\_flow\_log\_iam\_policy\_name) | Name of the IAM policy | `string` | `"vpc-flow-log-to-cloudwatch"` | no | | [vpc\_flow\_log\_iam\_policy\_use\_name\_prefix](#input\_vpc\_flow\_log\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`vpc_flow_log_iam_policy_name`) is used as a prefix | `bool` | `true` | no | | [vpc\_flow\_log\_iam\_role\_name](#input\_vpc\_flow\_log\_iam\_role\_name) | Name to use on the VPC Flow Log IAM role created | `string` | `"vpc-flow-log-role"` | no | diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md index 048b54b16..eeb1fd686 100644 --- a/examples/block-public-access/README.md +++ b/examples/block-public-access/README.md @@ -22,8 +22,9 @@ This example defines VPC Block Public Access Exclusion at the subnet level, but - configure VPC Block Public Access Options e.g.: ```hcl - internet_gateway_block_enabled = true - internet_gateway_block_mode = "block-bidirectional" + vpc_block_public_access_options = { + internet_gateway_block_mode = "block-bidirectional" + } ``` - define VPC Block Public Access Exclusion at the VPC level e.g.: diff --git a/examples/block-public-access/main.tf b/examples/block-public-access/main.tf index 468896295..6957610ee 100644 --- a/examples/block-public-access/main.tf +++ b/examples/block-public-access/main.tf @@ -37,28 +37,28 @@ module "vpc" { } ### VPC Block Public Access Exclusion at the VPC level - # vpc_block_public_access_exclusions = { - # exclude_vpc = { - # exclude_vpc = true - # internet_gateway_exclusion_mode = "allow-bidirectional" - # } - # } - - ### VPC Block Public Access Exclusion at the subnet level vpc_block_public_access_exclusions = { - exclude_subnet_private1 = { - exclude_subnet = true - subnet_type = "private" - subnet_index = 1 - internet_gateway_exclusion_mode = "allow-egress" - } - exclude_subnet_private2 = { - exclude_subnet = true - subnet_type = "private" - subnet_index = 2 - internet_gateway_exclusion_mode = "allow-egress" + exclude_vpc = { + exclude_vpc = true + internet_gateway_exclusion_mode = "allow-bidirectional" } } + ### VPC Block Public Access Exclusion at the subnet level + # vpc_block_public_access_exclusions = { + # exclude_subnet_private1 = { + # exclude_subnet = true + # subnet_type = "private" + # subnet_index = 1 + # internet_gateway_exclusion_mode = "allow-egress" + # } + # exclude_subnet_private2 = { + # exclude_subnet = true + # subnet_type = "private" + # subnet_index = 2 + # internet_gateway_exclusion_mode = "allow-egress" + # } + # } + tags = local.tags } diff --git a/variables.tf b/variables.tf index 193f19dda..49961cdfa 100644 --- a/variables.tf +++ b/variables.tf @@ -117,13 +117,54 @@ variable "tags" { } variable "vpc_block_public_access_options" { - description = "Map of VPC Block Public Access Options" + description = < Date: Mon, 27 Jan 2025 23:48:58 +0100 Subject: [PATCH 12/15] Update README --- README.md | 4 +-- examples/block-public-access/README.md | 40 ++------------------------ variables.tf | 6 ++++ 3 files changed, 10 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index f1e22af89..d6b1aedc8 100644 --- a/README.md +++ b/README.md @@ -583,8 +583,8 @@ No modules. | [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\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions e.g. to exclude the VPC:

vpc\_block\_public\_access\_exclusions = {
exclude\_vpc = {
exclude\_vpc = true
internet\_gateway\_exclusion\_mode = "allow-bidirectional"
}
}

or to exclude specific subnets:

vpc\_block\_public\_access\_exclusions = {
exclude\_subnet\_private1 = {
exclude\_subnet = true
subnet\_type = "private"
subnet\_index = 1
internet\_gateway\_exclusion\_mode = "allow-egress"
}
exclude\_subnet\_private2 = {
exclude\_subnet = true
subnet\_type = "private"
subnet\_index = 2
internet\_gateway\_exclusion\_mode = "allow-egress"
}
}

One of `exclude_vpc` or `exclude_subnet` must be set to true.
Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`.
Value of `subnet_index` is the index of the subnet in the corresponding subnet list.
Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. | `map(any)` | `{}` | no | -| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options e.g.:

vpc\_block\_public\_access\_options = {
internet\_gateway\_block\_mode = "block-bidirectional"
}

Currently only `internet_gateway_block_mode` is supported, for which
valid values are `block-bidirectional`, `block-ingress` and `off`. | `map(string)` | `{}` | no | +| [vpc\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions e.g. to exclude the VPC:
hcl
vpc_block_public_access_exclusions = {
exclude_vpc = {
exclude_vpc = true
internet_gateway_exclusion_mode = "allow-bidirectional"
}
}
or to exclude specific subnets:
hcl
vpc_block_public_access_exclusions = {
exclude_subnet_private1 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 1
internet_gateway_exclusion_mode = "allow-egress"
}
exclude_subnet_private2 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 2
internet_gateway_exclusion_mode = "allow-egress"
}
}
One of `exclude_vpc` or `exclude_subnet` must be set to true.
Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`.
Value of `subnet_index` is the index of the subnet in the corresponding subnet list.
Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. | `map(any)` | `{}` | no | +| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options e.g.:
hcl
vpc_block_public_access_options = {
internet_gateway_block_mode = "block-bidirectional"
}
Currently only `internet_gateway_block_mode` is supported, for which
valid values are `block-bidirectional`, `block-ingress` and `off`. | `map(string)` | `{}` | no | | [vpc\_flow\_log\_iam\_policy\_name](#input\_vpc\_flow\_log\_iam\_policy\_name) | Name of the IAM policy | `string` | `"vpc-flow-log-to-cloudwatch"` | no | | [vpc\_flow\_log\_iam\_policy\_use\_name\_prefix](#input\_vpc\_flow\_log\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`vpc_flow_log_iam_policy_name`) is used as a prefix | `bool` | `true` | no | | [vpc\_flow\_log\_iam\_role\_name](#input\_vpc\_flow\_log\_iam\_role\_name) | Name to use on the VPC Flow Log IAM role created | `string` | `"vpc-flow-log-role"` | no | diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md index eeb1fd686..a1c15aa2b 100644 --- a/examples/block-public-access/README.md +++ b/examples/block-public-access/README.md @@ -18,49 +18,13 @@ $ 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. -This example defines VPC Block Public Access Exclusion at the subnet level, but other possibilities are also available and are commented on in the code. There are several ways to define these options: - -- configure VPC Block Public Access Options e.g.: -```hcl - vpc_block_public_access_options = { - internet_gateway_block_mode = "block-bidirectional" - } -``` - -- define VPC Block Public Access Exclusion at the VPC level e.g.: -```hcl - vpc_block_public_access_exclusions = { - exclude_vpc = { - exclude_vpc = true - internet_gateway_exclusion_mode = "allow-bidirectional" - } - } -``` -- define VPC Block Public Access Exclusion at the subnet level e.g.: -```hcl - vpc_block_public_access_exclusions = { - exclude_subnet_private1 = { - exclude_subnet = true - subnet_type = "private" - subnet_index = 1 - internet_gateway_exclusion_mode = "allow-egress" - } - exclude_subnet_private2 = { - exclude_subnet = true - subnet_type = "private" - subnet_index = 2 - internet_gateway_exclusion_mode = "allow-egress" - } - } -``` - -After creating VPC Block Public Access Options, you can verify them with the following command: +After deployment VPC Block Public Access Options can be verified with the following command: ```bash aws ec2 --region eu-west-1 describe-vpc-block-public-access-options ``` -Similarly, you can check VPC Block Public Access Exclusions by obtaining the exclusion ID from the Terraform state and running: +Similarly, VPC Block Public Access Exclusions can be checked by obtaining the exclusion ID from the Terraform output and running commands: ```bash terraform output vpc_block_public_access_exclusions diff --git a/variables.tf b/variables.tf index 49961cdfa..413836f48 100644 --- a/variables.tf +++ b/variables.tf @@ -120,9 +120,11 @@ variable "vpc_block_public_access_options" { description = < Date: Mon, 27 Jan 2025 23:51:54 +0100 Subject: [PATCH 13/15] Update README --- README.md | 4 ++-- examples/block-public-access/README.md | 2 +- variables.tf | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d6b1aedc8..55c694aec 100644 --- a/README.md +++ b/README.md @@ -583,8 +583,8 @@ No modules. | [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\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions e.g. to exclude the VPC:
hcl
vpc_block_public_access_exclusions = {
exclude_vpc = {
exclude_vpc = true
internet_gateway_exclusion_mode = "allow-bidirectional"
}
}
or to exclude specific subnets:
hcl
vpc_block_public_access_exclusions = {
exclude_subnet_private1 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 1
internet_gateway_exclusion_mode = "allow-egress"
}
exclude_subnet_private2 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 2
internet_gateway_exclusion_mode = "allow-egress"
}
}
One of `exclude_vpc` or `exclude_subnet` must be set to true.
Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`.
Value of `subnet_index` is the index of the subnet in the corresponding subnet list.
Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. | `map(any)` | `{}` | no | -| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options e.g.:
hcl
vpc_block_public_access_options = {
internet_gateway_block_mode = "block-bidirectional"
}
Currently only `internet_gateway_block_mode` is supported, for which
valid values are `block-bidirectional`, `block-ingress` and `off`. | `map(string)` | `{}` | no | +| [vpc\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions e.g. to exclude the VPC:
vpc_block_public_access_exclusions = {
exclude_vpc = {
exclude_vpc = true
internet_gateway_exclusion_mode = "allow-bidirectional"
}
}
or to exclude specific subnets:
vpc_block_public_access_exclusions = {
exclude_subnet_private1 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 1
internet_gateway_exclusion_mode = "allow-egress"
}
exclude_subnet_private2 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 2
internet_gateway_exclusion_mode = "allow-egress"
}
}
One of `exclude_vpc` or `exclude_subnet` must be set to true.
Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`.
Value of `subnet_index` is the index of the subnet in the corresponding subnet list.
Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. | `map(any)` | `{}` | no | +| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options e.g.:
vpc_block_public_access_options = {
internet_gateway_block_mode = "block-bidirectional"
}
Currently only `internet_gateway_block_mode` is supported, for which
valid values are `block-bidirectional`, `block-ingress` and `off`. | `map(string)` | `{}` | no | | [vpc\_flow\_log\_iam\_policy\_name](#input\_vpc\_flow\_log\_iam\_policy\_name) | Name of the IAM policy | `string` | `"vpc-flow-log-to-cloudwatch"` | no | | [vpc\_flow\_log\_iam\_policy\_use\_name\_prefix](#input\_vpc\_flow\_log\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`vpc_flow_log_iam_policy_name`) is used as a prefix | `bool` | `true` | no | | [vpc\_flow\_log\_iam\_role\_name](#input\_vpc\_flow\_log\_iam\_role\_name) | Name to use on the VPC Flow Log IAM role created | `string` | `"vpc-flow-log-role"` | no | diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md index a1c15aa2b..7ed1b1199 100644 --- a/examples/block-public-access/README.md +++ b/examples/block-public-access/README.md @@ -18,7 +18,7 @@ $ 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. -After deployment VPC Block Public Access Options can be verified with the following command: +After deployment, VPC Block Public Access Options can be verified with the following command: ```bash aws ec2 --region eu-west-1 describe-vpc-block-public-access-options diff --git a/variables.tf b/variables.tf index 413836f48..df8746864 100644 --- a/variables.tf +++ b/variables.tf @@ -120,7 +120,7 @@ variable "vpc_block_public_access_options" { description = < Date: Tue, 28 Jan 2025 14:39:36 +0100 Subject: [PATCH 14/15] Extend README, refactor variables and outputs --- README.md | 6 +-- examples/block-public-access/README.md | 51 +++++++++++++++++++++++-- examples/block-public-access/outputs.tf | 2 +- outputs.tf | 4 +- variables.tf | 51 +------------------------ 5 files changed, 56 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 55c694aec..e0192cc7b 100644 --- a/README.md +++ b/README.md @@ -583,8 +583,8 @@ No modules. | [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\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | List of VPC Block Public Access Exclusions e.g. to exclude the VPC:
vpc_block_public_access_exclusions = {
exclude_vpc = {
exclude_vpc = true
internet_gateway_exclusion_mode = "allow-bidirectional"
}
}
or to exclude specific subnets:
vpc_block_public_access_exclusions = {
exclude_subnet_private1 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 1
internet_gateway_exclusion_mode = "allow-egress"
}
exclude_subnet_private2 = {
exclude_subnet = true
subnet_type = "private"
subnet_index = 2
internet_gateway_exclusion_mode = "allow-egress"
}
}
One of `exclude_vpc` or `exclude_subnet` must be set to true.
Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`.
Value of `subnet_index` is the index of the subnet in the corresponding subnet list.
Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. | `map(any)` | `{}` | no | -| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | Map of VPC Block Public Access Options e.g.:
vpc_block_public_access_options = {
internet_gateway_block_mode = "block-bidirectional"
}
Currently only `internet_gateway_block_mode` is supported, for which
valid values are `block-bidirectional`, `block-ingress` and `off`. | `map(string)` | `{}` | no | +| [vpc\_block\_public\_access\_exclusions](#input\_vpc\_block\_public\_access\_exclusions) | A map of VPC block public access exclusions | `map(any)` | `{}` | no | +| [vpc\_block\_public\_access\_options](#input\_vpc\_block\_public\_access\_options) | A map of VPC block public access options | `map(string)` | `{}` | no | | [vpc\_flow\_log\_iam\_policy\_name](#input\_vpc\_flow\_log\_iam\_policy\_name) | Name of the IAM policy | `string` | `"vpc-flow-log-to-cloudwatch"` | no | | [vpc\_flow\_log\_iam\_policy\_use\_name\_prefix](#input\_vpc\_flow\_log\_iam\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`vpc_flow_log_iam_policy_name`) is used as a prefix | `bool` | `true` | no | | [vpc\_flow\_log\_iam\_role\_name](#input\_vpc\_flow\_log\_iam\_role\_name) | Name to use on the VPC Flow Log IAM role created | `string` | `"vpc-flow-log-role"` | no | @@ -703,7 +703,7 @@ No modules. | [vgw\_arn](#output\_vgw\_arn) | The ARN of the VPN Gateway | | [vgw\_id](#output\_vgw\_id) | The ID of the VPN Gateway | | [vpc\_arn](#output\_vpc\_arn) | The ARN of the VPC | -| [vpc\_block\_public\_access\_exclusions](#output\_vpc\_block\_public\_access\_exclusions) | List of VPC block public access exclusions | +| [vpc\_block\_public\_access\_exclusions](#output\_vpc\_block\_public\_access\_exclusions) | A map of VPC block public access exclusions | | [vpc\_cidr\_block](#output\_vpc\_cidr\_block) | The CIDR block of the VPC | | [vpc\_enable\_dns\_hostnames](#output\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support | | [vpc\_enable\_dns\_support](#output\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support | diff --git a/examples/block-public-access/README.md b/examples/block-public-access/README.md index 7ed1b1199..21c6bd116 100644 --- a/examples/block-public-access/README.md +++ b/examples/block-public-access/README.md @@ -18,13 +18,58 @@ $ 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. -After deployment, VPC Block Public Access Options can be verified with the following command: +In the example below, a map of VPC block public access options is configured: + +``` +vpc_block_public_access_options = { + internet_gateway_block_mode = "block-bidirectional" +} +``` + +Currently only `internet_gateway_block_mode` is supported, for which valid values are `block-bidirectional`, `block-ingress` and `off`. + +VPC block public access exclusions can be applied at the VPC level e.g.: + +``` +vpc_block_public_access_exclusions = { + exclude_vpc = { + exclude_vpc = true + internet_gateway_exclusion_mode = "allow-bidirectional" + } +} +``` + +or at the subnet level e.g.: + +``` +vpc_block_public_access_exclusions = { + exclude_subnet_private1 = { + exclude_subnet = true + subnet_type = "private" + subnet_index = 1 + internet_gateway_exclusion_mode = "allow-egress" + } + exclude_subnet_private2 = { + exclude_subnet = true + subnet_type = "private" + subnet_index = 2 + internet_gateway_exclusion_mode = "allow-egress" + } +} +``` + +One of `exclude_vpc` or `exclude_subnet` must be set to true. +Value of `subnet_type` can be `public`, `private`, `database`, `redshift`, `elasticache`, `intra` or `custom`. +Value of `subnet_index` is the index of the subnet in the corresponding subnet list. +Value of `internet_gateway_exclusion_mode` can be `allow-egress` and `allow-bidirectional`. + +After deployment, VPC block public access options can be verified with the following command: ```bash aws ec2 --region eu-west-1 describe-vpc-block-public-access-options ``` -Similarly, VPC Block Public Access Exclusions can be checked by obtaining the exclusion ID from the Terraform output and running commands: +Similarly, VPC block public access exclusions can be checked by obtaining the exclusion ID from the Terraform output and running commands: ```bash terraform output vpc_block_public_access_exclusions @@ -159,7 +204,7 @@ No inputs. | [vgw\_arn](#output\_vgw\_arn) | The ARN of the VPN Gateway | | [vgw\_id](#output\_vgw\_id) | The ID of the VPN Gateway | | [vpc\_arn](#output\_vpc\_arn) | The ARN of the VPC | -| [vpc\_block\_public\_access\_exclusions](#output\_vpc\_block\_public\_access\_exclusions) | List of VPC block public access exclusions | +| [vpc\_block\_public\_access\_exclusions](#output\_vpc\_block\_public\_access\_exclusions) | A map of VPC block public access exclusions | | [vpc\_cidr\_block](#output\_vpc\_cidr\_block) | The CIDR block of the VPC | | [vpc\_enable\_dns\_hostnames](#output\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support | | [vpc\_enable\_dns\_support](#output\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support | diff --git a/examples/block-public-access/outputs.tf b/examples/block-public-access/outputs.tf index 67375a118..1df0278b4 100644 --- a/examples/block-public-access/outputs.tf +++ b/examples/block-public-access/outputs.tf @@ -69,7 +69,7 @@ output "vpc_owner_id" { } output "vpc_block_public_access_exclusions" { - description = "List of VPC block public access exclusions" + description = "A map of VPC block public access exclusions" value = module.vpc.vpc_block_public_access_exclusions } diff --git a/outputs.tf b/outputs.tf index bc1a9bf80..1d1d2783a 100644 --- a/outputs.tf +++ b/outputs.tf @@ -79,8 +79,8 @@ output "vpc_owner_id" { } output "vpc_block_public_access_exclusions" { - description = "List of VPC block public access exclusions" - value = [for k, v in aws_vpc_block_public_access_exclusion.this : v.id] + description = "A map of VPC block public access exclusions" + value = { for k, v in aws_vpc_block_public_access_exclusion.this : k => v.id } } ################################################################################ diff --git a/variables.tf b/variables.tf index df8746864..d8338267a 100644 --- a/variables.tf +++ b/variables.tf @@ -117,60 +117,13 @@ variable "tags" { } variable "vpc_block_public_access_options" { - description = < Date: Tue, 28 Jan 2025 19:43:35 +0100 Subject: [PATCH 15/15] Update list of examples in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e0192cc7b..ffe631e3a 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,7 @@ module "vpc_cidr_from_ipam" { - [VPC with unique route tables](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/separate-route-tables) - [Simple VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/simple) - [VPC Flow Logs](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/vpc-flow-logs) +- [VPC Block Public Access](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/block-public-access) - [Few tests and edge case examples](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/issues) ## Contributing