diff --git a/README.md b/README.md index 66ec178..fa50155 100644 --- a/README.md +++ b/README.md @@ -323,6 +323,7 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws | [flow\_logs](#module\_flow\_logs) | ./modules/flow_logs | n/a | | [subnet\_tags](#module\_subnet\_tags) | aws-ia/label/aws | 0.0.5 | | [tags](#module\_tags) | aws-ia/label/aws | 0.0.5 | +| [vpc\_lattice\_tags](#module\_vpc\_lattice\_tags) | aws-ia/label/aws | 0.0.5 | ## Resources @@ -363,6 +364,7 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws | [aws_subnet.tgw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | | [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource | | [aws_vpc_ipv4_cidr_block_association.secondary](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipv4_cidr_block_association) | resource | +| [aws_vpclattice_service_network_vpc_association.vpc_lattice_service_network_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpclattice_service_network_vpc_association) | resource | | [aws_availability_zones.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | | [aws_vpc.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | @@ -393,6 +395,7 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws | [vpc\_ipv6\_cidr\_block](#input\_vpc\_ipv6\_cidr\_block) | IPv6 CIDR range to assign to VPC if creating VPC. You need to use `vpc_ipv6_ipam_pool_id` and set explicitly the CIDR block to use, or derived from IPAM using using `vpc_ipv6_netmask_length`. | `string` | `null` | no | | [vpc\_ipv6\_ipam\_pool\_id](#input\_vpc\_ipv6\_ipam\_pool\_id) | Set to use IPAM to get an IPv6 CIDR block. | `string` | `null` | no | | [vpc\_ipv6\_netmask\_length](#input\_vpc\_ipv6\_netmask\_length) | Set to use IPAM to get an IPv6 CIDR block using a specified netmask. Must be set with `var.vpc_ipv6_ipam_pool_id`. | `string` | `null` | no | +| [vpc\_lattice](#input\_vpc\_lattice) | Amazon VPC Lattice Service Network VPC association. You can only associate one Service Network to the VPC. This association also support Security Groups (more than 1).
This variable expects the following attributes:
- `service_network_identifier` = (Required\|string) The ID or ARN of the Service Network to associate. You must use the ARN if the Service Network and VPC resources are in different AWS Accounts.
- `security_group_ids = (Optional|list(string)) The IDs of the security groups to attach to the association.
- `tags` = = (Optional|map(string)) Tags to set on the Lattice VPC association resource.
` | `any` | `{}` | no | | [vpc\_secondary\_cidr](#input\_vpc\_secondary\_cidr) | If `true` the module will create a `aws_vpc_ipv4_cidr_block_association` and subnets for that secondary cidr. If using IPAM for both primary and secondary CIDRs, you may only call this module serially (aka using `-target`, etc). | `bool` | `false` | no | | [vpc\_secondary\_cidr\_natgw](#input\_vpc\_secondary\_cidr\_natgw) | If attaching a secondary IPv4 CIDR instead of creating a VPC, you can map private/ tgw subnets to your public NAT GW with this argument. Simply pass the output `nat_gateway_attributes_by_az`, ex: `vpc_secondary_cidr_natgw = module.vpc.natgw_id_per_az`. If you did not build your primary with this module, you must construct a map { az : { id : nat-123asdb }} for each az. | `any` | `{}` | no | @@ -413,4 +416,5 @@ Please see our [developer documentation](https://github.com/aws-ia/terraform-aws | [tgw\_subnet\_attributes\_by\_az](#output\_tgw\_subnet\_attributes\_by\_az) | Map of all tgw subnets containing their attributes.

Example:
tgw_subnet_attributes = {
"us-east-1a" = {
"arn" = "arn:aws:ec2:us-east-1:<>:subnet/subnet-04a86315c4839b519"
"assign_ipv6_address_on_creation" = false
...

}
"us-east-1b" = {...)
}
| | [transit\_gateway\_attachment\_id](#output\_transit\_gateway\_attachment\_id) | Transit gateway attachment id. | | [vpc\_attributes](#output\_vpc\_attributes) | VPC resource attributes. Full output of aws\_vpc. | +| [vpc\_lattice\_service\_network\_association](#output\_vpc\_lattice\_service\_network\_association) | VPC Lattice Service Network VPC association. Full output of aws\_vpclattice\_service\_network\_vpc\_association | \ No newline at end of file diff --git a/data.tf b/data.tf index 0146d0e..7cf5efe 100644 --- a/data.tf +++ b/data.tf @@ -112,9 +112,18 @@ locals { private_subnets_egress_routed = [for type in local.private_subnet_names : type if try(var.subnets[type].connect_to_eigw == true, false)] # private subnets with cidrs per az if connect_to_public_eigw = true ... "privatetwo/us-east-1a" private_subnet_names_egress_routed = [for subnet in local.private_per_az : subnet if contains(local.private_subnets_egress_routed, split("/", subnet)[0])] + + # VPC LATTICE ############################################################ + # If var.vpc_lattice is defined (default = {}), the VPC association is created. + lattice_association = length(keys(var.vpc_lattice)) > 0 } -data "aws_availability_zones" "current" {} +data "aws_availability_zones" "current" { + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} # search for existing vpc with var.vpc_id if not creating data "aws_vpc" "main" { @@ -140,3 +149,10 @@ module "subnet_tags" { tags = each.value } + +module "vpc_lattice_tags" { + source = "aws-ia/label/aws" + version = "0.0.5" + + tags = try(var.vpc_lattice.tags, {}) +} diff --git a/examples/vpc_lattice/.header.md b/examples/vpc_lattice/.header.md new file mode 100644 index 0000000..b3c05c6 --- /dev/null +++ b/examples/vpc_lattice/.header.md @@ -0,0 +1,9 @@ +# Creating Amazon VPC Lattice Service Network VPC Assocation + +This example shows how you can use this module to create a [VPC Lattice]() Service Network VPC association. The example creates: + +* VPC Lattice Service Network. +* Security Group (allowing HTTP and HTTPS traffic from the local CIDR). Used to attach it to the VPC Lattice association +* The VPC module creates the following: + * One set of subnets (*workload*) + * VPC Lattice Service Network VPC association. \ No newline at end of file diff --git a/examples/vpc_lattice/.terraform-docs.yaml b/examples/vpc_lattice/.terraform-docs.yaml new file mode 100644 index 0000000..6dc99de --- /dev/null +++ b/examples/vpc_lattice/.terraform-docs.yaml @@ -0,0 +1,21 @@ +formatter: markdown +header-from: .header.md +settings: + anchor: true + color: true + default: true + escape: true + html: true + indent: 2 + required: true + sensitive: true + type: true + lockfile: false + +sort: + enabled: true + by: required + +output: + file: README.md + mode: replace diff --git a/examples/vpc_lattice/README.md b/examples/vpc_lattice/README.md new file mode 100644 index 0000000..6abc4ea --- /dev/null +++ b/examples/vpc_lattice/README.md @@ -0,0 +1,49 @@ + +# Creating Amazon VPC Lattice Service Network VPC Assocation + +This example shows how you can use this module to create a [VPC Lattice]() Service Network VPC association. The example creates: + +* VPC Lattice Service Network. +* Security Group (allowing HTTP and HTTPS traffic from the local CIDR). Used to attach it to the VPC Lattice association +* The VPC module creates the following: + * One set of subnets (*workload*) + * VPC Lattice Service Network VPC association. + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0 | +| [aws](#requirement\_aws) | >= 4.65.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.65.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [vpc](#module\_vpc) | aws-ia/vpc/aws | >= 4.3.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_security_group.security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_vpclattice_service_network.service_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpclattice_service_network) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_region](#input\_aws\_region) | AWS Region. | `string` | `"eu-west-1"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [vpc\_lattice\_service\_network\_association](#output\_vpc\_lattice\_service\_network\_association) | VPC Lattice Service Network VPC association. | + \ No newline at end of file diff --git a/examples/vpc_lattice/main.tf b/examples/vpc_lattice/main.tf new file mode 100644 index 0000000..70d944e --- /dev/null +++ b/examples/vpc_lattice/main.tf @@ -0,0 +1,76 @@ + +# VPC module +module "vpc" { + source = "aws-ia/vpc/aws" + version = ">= 4.3.0" + + name = "tgw" + cidr_block = "10.0.0.0/24" + az_count = 2 + + vpc_lattice = { + service_network_identifier = aws_vpclattice_service_network.service_network.id + security_group_ids = [aws_security_group.security_group.id] + tags = { + vpc_lattice = true + } + } + + subnets = { + workload = { netmask = 28 } + } + + tags = { + vpc_module = true + } +} + +# VPC Lattice Service Network +resource "aws_vpclattice_service_network" "service_network" { + name = "example-service-network" + auth_type = "NONE" +} + +# Security Group +resource "aws_security_group" "security_group" { + name = "lattice-sg" + description = "Lattice Securigy Group." + vpc_id = module.vpc.vpc_attributes.id + + ingress { + description = "Allow HTTP" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["10.0.0.0/24"] + } + + ingress { + description = "Allow HTTPS" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["10.0.0.0/24"] + } + + egress { + description = "Allowing inter-VPC traffic." + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["10.0.0.0/24"] + } + + egress { + description = "Allowing VPC Lattice traffic." + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["169.254.171.0/24"] + } +} + + + + + diff --git a/examples/vpc_lattice/outputs.tf b/examples/vpc_lattice/outputs.tf new file mode 100644 index 0000000..35e79f5 --- /dev/null +++ b/examples/vpc_lattice/outputs.tf @@ -0,0 +1,6 @@ +## Used for Testing, do not delete + +output "vpc_lattice_service_network_association" { + description = "VPC Lattice Service Network VPC association." + value = module.vpc.vpc_lattice_service_network_association.id +} diff --git a/examples/vpc_lattice/providers.tf b/examples/vpc_lattice/providers.tf new file mode 100644 index 0000000..ae67b93 --- /dev/null +++ b/examples/vpc_lattice/providers.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.3.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.65.0" + } + } +} + +# Provider definition +provider "aws" { + region = var.aws_region +} + diff --git a/examples/vpc_lattice/variables.tf b/examples/vpc_lattice/variables.tf new file mode 100644 index 0000000..6b49389 --- /dev/null +++ b/examples/vpc_lattice/variables.tf @@ -0,0 +1,7 @@ + +variable "aws_region" { + description = "AWS Region." + type = string + + default = "eu-west-1" +} \ No newline at end of file diff --git a/main.tf b/main.tf index a99757c..5bf91a7 100644 --- a/main.tf +++ b/main.tf @@ -508,3 +508,17 @@ module "flow_logs" { tags = module.tags.tags_aws } + +# ---------- VPC LATTICE SERVICE NETWORK VPC ASSOCIATION ---------- +resource "aws_vpclattice_service_network_vpc_association" "vpc_lattice_service_network_association" { + count = local.lattice_association ? 1 : 0 + + vpc_identifier = aws_vpc.main[0].id + service_network_identifier = var.vpc_lattice.service_network_identifier + security_group_ids = try(var.vpc_lattice.security_group_ids, null) + + tags = merge( + module.tags.tags_aws, + module.vpc_lattice_tags.tags_aws + ) +} \ No newline at end of file diff --git a/outputs.tf b/outputs.tf index 96e2bf1..6f9f9e6 100644 --- a/outputs.tf +++ b/outputs.tf @@ -179,11 +179,16 @@ EOF } output "internet_gateway" { - value = try(aws_internet_gateway.main, null) + value = try(aws_internet_gateway.main[0], null) description = "Internet gateway attributes. Full output of aws_internet_gateway." } output "egress_only_internet_gateway" { - value = try(aws_egress_only_internet_gateway.eigw, null) + value = try(aws_egress_only_internet_gateway.eigw[0], null) description = "Egress-only Internet gateway attributes. Full output of aws_egress_only_internet_gateway." } + +output "vpc_lattice_service_network_association" { + value = try(aws_vpclattice_service_network_vpc_association.vpc_lattice_service_network_association[0], null) + description = "VPC Lattice Service Network VPC association. Full output of aws_vpclattice_service_network_vpc_association" +} \ No newline at end of file diff --git a/test/examples_vpc_lattice_test.go b/test/examples_vpc_lattice_test.go new file mode 100644 index 0000000..76c1260 --- /dev/null +++ b/test/examples_vpc_lattice_test.go @@ -0,0 +1,17 @@ +package test + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" +) + +func TestExamplesVPCLattice(t *testing.T) { + + terraformOptions := &terraform.Options{ + TerraformDir: "../examples/vpc_lattice", + } + + defer terraform.Destroy(t, terraformOptions) + terraform.InitAndApply(t, terraformOptions) +} \ No newline at end of file diff --git a/variables.tf b/variables.tf index 9fcf566..a6ef12e 100644 --- a/variables.tf +++ b/variables.tf @@ -371,3 +371,26 @@ EOF type = any default = {} } + +variable "vpc_lattice" { + description = <<-EOF + Amazon VPC Lattice Service Network VPC association. You can only associate one Service Network to the VPC. This association also support Security Groups (more than 1). + This variable expects the following attributes: + - `service_network_identifier` = (Required|string) The ID or ARN of the Service Network to associate. You must use the ARN if the Service Network and VPC resources are in different AWS Accounts. + - `security_group_ids = (Optional|list(string)) The IDs of the security groups to attach to the association. + - `tags` = = (Optional|map(string)) Tags to set on the Lattice VPC association resource. +EOF + type = any + + default = {} + + # All var.vpc_lattice valid keys + validation { + error_message = "Invalid key in var.vpc_lattice. Valid options include: \"service_network_identifier\", \"security_group_ids\", \"tags\"." + condition = length(setsubtract(keys(var.vpc_lattice), [ + "service_network_identifier", + "security_group_ids", + "tags" + ])) == 0 + } +}