diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 22e198e..7af6085 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -8,6 +8,12 @@ ":floppy_disk: dx-private-virtual-interface": - modules/dx-private-virtual-interface/**/* +":floppy_disk: lattice-service-network": +- modules/lattice-service-network/**/* + +":floppy_disk: lattice-service": +- modules/lattice-service/**/* + ":floppy_disk: reachability-analyzer-path": - modules/reachability-analyzer-path/**/* diff --git a/.github/labels.yaml b/.github/labels.yaml index 270f0ca..6b1e07f 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -49,6 +49,12 @@ - color: "fbca04" description: "This issue or pull request is related to dx-private-virtual-interface module." name: ":floppy_disk: dx-private-virtual-interface" +- color: "fbca04" + description: "This issue or pull request is related to lattice-service-network module." + name: ":floppy_disk: lattice-service-network" +- color: "fbca04" + description: "This issue or pull request is related to lattice-service module." + name: ":floppy_disk: lattice-service" - color: "fbca04" description: "This issue or pull request is related to reachability-analyzer-path module." name: ":floppy_disk: reachability-analyzer-path" diff --git a/README.md b/README.md index bf6b938..3d05537 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Terraform module which creates VPC Connectivity related resources (VPC Peering, - [dx-connection](./modules/dx-connection) - [dx-gateway](./modules/dx-gateway) - [dx-private-virtual-interface](./modules/dx-private-virtual-interface) +- [lattice-service-network](./modules/lattice-service-network) +- [lattice-service](./modules/lattice-service) - [reachability-analyzer-path](./modules/reachability-analyzer-path) - [vpc-endpoint-service](./modules/vpc-endpoint-service) - [vpc-gateway-endpoint](./modules/vpc-gateway-endpoint) @@ -28,6 +30,10 @@ Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws- - Endpoint Service - Gateway Endpoint - Interface Endpoint +- **AWS VPC Lattice** + - Service Network + - Service + - Target Group - **AWS DX (Direct Connect)** - Connection - Gateway @@ -41,6 +47,10 @@ Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws- ## Examples +### VPC Lattice + +- [lattice-service-network-simple](./examples/lattice-service-network-simple) + ### Network Manager - [reachability-analyzer](./examples/reachability-analyzer) diff --git a/examples/lattice-service-network-simple/main.tf b/examples/lattice-service-network-simple/main.tf new file mode 100644 index 0000000..e344deb --- /dev/null +++ b/examples/lattice-service-network-simple/main.tf @@ -0,0 +1,21 @@ +provider "aws" { + region = "us-east-1" +} + + +################################################### +# Service Network of VPC Lattice +################################################### + +module "service_network" { + source = "../../modules/lattice-service-network" + # source = "tedilabs/vpc-connectivity/aws//modules/lattice-service-network" + # version = "~> 0.2.0" + + name = "test" + auth_type = "NONE" + + tags = { + "project" = "terraform-aws-vpc-connectivity-examples" + } +} diff --git a/examples/lattice-service-network-simple/outputs.tf b/examples/lattice-service-network-simple/outputs.tf new file mode 100644 index 0000000..2edc0ec --- /dev/null +++ b/examples/lattice-service-network-simple/outputs.tf @@ -0,0 +1,4 @@ +output "service_network" { + description = "The service network of VPC Lattice." + value = module.service_network +} diff --git a/examples/lattice-service-network-simple/versions.tf b/examples/lattice-service-network-simple/versions.tf new file mode 100644 index 0000000..59c42e8 --- /dev/null +++ b/examples/lattice-service-network-simple/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 1.5" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} diff --git a/modules/lattice-service-network/README.md b/modules/lattice-service-network/README.md new file mode 100644 index 0000000..8550f3e --- /dev/null +++ b/modules/lattice-service-network/README.md @@ -0,0 +1,65 @@ +# lattice-service-network + +This module creates following resources. + +- `aws_vpclattice_service_network` +- `aws_vpclattice_auth_policy` (optional) +- `aws_vpclattice_resource_policy` (optional) +- `aws_vpclattice_service_network_vpc_association` (optional) +- `aws_vpclattice_service_network_service_association` (optional) +- `aws_vpclattice_access_log_subscription` (optional) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3 | +| [aws](#requirement\_aws) | >= 4.58 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.17.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_ec2_network_insights_analysis.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_network_insights_analysis) | resource | +| [aws_ec2_network_insights_path.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_network_insights_path) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [destination\_network](#input\_destination\_network) | (Required) The configuration of destination network for analysis. `destination_network` as defined below.
(Required) `id` - The ID of resource which is the destination of the path. Can be an Instance, Internet Gateway, Network Interface, Transit Gateway, Transit Gateway Attachment, VPC Endpoint Service, VPC Endpoint, VPC Peering Connection or VPN Gateway.
(Optional) `ip_address` - The IP address of the destination resource.
(Optional) `port` - The port number of destination to analyze access to. |
object({
id = string
ip_address = optional(string)
port = optional(number)
})
| n/a | yes | +| [name](#input\_name) | (Required) The name of the reachability analyzer path. | `string` | n/a | yes | +| [source\_network](#input\_source\_network) | (Required) The configuration of source network for analysis. `source_network` as defined below.
(Required) `id` - The ID of resource which is the source of the path. Can be an Instance, Internet Gateway, Network Interface, Transit Gateway, Transit Gateway Attachment, VPC Endpoint Service, VPC Endpoint, VPC Peering Connection or VPN Gateway.
(Optional) `ip_address` - The IP address of the source resource. |
object({
id = string
ip_address = optional(string)
})
| n/a | yes | +| [analyses](#input\_analyses) | (Optional) The configuration of analyses to run with the reachability analyzer path. Each block of `analyses` as defined below.
(Required) `name` - A name of the analysis with the reachability analyzer path.
(Optional) `required_intermediate_components` - A list of ARNs for resources the path must traverse. Intermediate components include Load Balancers, NAT Gateways, and Network Firewall, Transit Gateways, Transit Gateway Attachments, VPC Peering Connections. You cannot use security groups, network access control lists, network interfaces, or route tables as intermediate components.
(Optional) `wait_for_completion` - Whether to wait for the analysis status to change to `succeeded` or `failed`. Setting this to `false` will skip the process. Defaults to `true`. |
list(object({
name = string

required_intermediate_components = optional(list(string), [])
wait_for_completion = optional(bool, true)
}))
| `[]` | no | +| [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | +| [protocol](#input\_protocol) | (Optional) The protocol to use for analysis. Valid values are `TCP` or `UDP`. | `string` | `"TCP"` | no | +| [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | +| [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | +| [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | +| [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [analyses](#output\_analyses) | A list of histories of the analysis with the reachability analyzer path. | +| [arn](#output\_arn) | The ARN of the reachability analyzer path. | +| [destination\_network](#output\_destination\_network) | The configuration of destination network for analysis. | +| [id](#output\_id) | The ID of the reachability analyzer path. | +| [name](#output\_name) | The name of the reachability analyzer path. | +| [protocol](#output\_protocol) | The protocol to use for analysis. | +| [source\_network](#output\_source\_network) | The configuration of source network for analysis. | + diff --git a/modules/lattice-service-network/logging.tf b/modules/lattice-service-network/logging.tf new file mode 100644 index 0000000..7db9eda --- /dev/null +++ b/modules/lattice-service-network/logging.tf @@ -0,0 +1,48 @@ +################################################### +# Access Logs for Service Network +################################################### + +resource "aws_vpclattice_access_log_subscription" "cloudwatch" { + count = var.logging_to_cloudwatch.enabled ? 1 : 0 + + resource_identifier = aws_vpclattice_service_network.this.id + destination_arn = var.logging_to_cloudwatch.log_group + + tags = merge( + { + "Name" = "${var.name}/cloudwatch" + }, + local.module_tags, + var.tags, + ) +} + +resource "aws_vpclattice_access_log_subscription" "kinesis_data_firehose" { + count = var.logging_to_kinesis_data_firehose.enabled ? 1 : 0 + + resource_identifier = aws_vpclattice_service_network.this.id + destination_arn = var.logging_to_kinesis_data_firehose.delivery_stream + + tags = merge( + { + "Name" = "${var.name}/kinesis-data-firehose" + }, + local.module_tags, + var.tags, + ) +} + +resource "aws_vpclattice_access_log_subscription" "s3" { + count = var.logging_to_s3.enabled ? 1 : 0 + + resource_identifier = aws_vpclattice_service_network.this.id + destination_arn = var.logging_to_s3.bucket + + tags = merge( + { + "Name" = "${var.name}/s3" + }, + local.module_tags, + var.tags, + ) +} diff --git a/modules/lattice-service-network/main.tf b/modules/lattice-service-network/main.tf new file mode 100644 index 0000000..897302b --- /dev/null +++ b/modules/lattice-service-network/main.tf @@ -0,0 +1,84 @@ +locals { + metadata = { + package = "terraform-aws-vpc-connectivity" + version = trimspace(file("${path.module}/../../VERSION")) + module = basename(path.module) + name = var.name + } + module_tags = var.module_tags_enabled ? { + "module.terraform.io/package" = local.metadata.package + "module.terraform.io/version" = local.metadata.version + "module.terraform.io/name" = local.metadata.module + "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" + "module.terraform.io/instance" = local.metadata.name + } : {} +} + + +################################################### +# Service Network for VPC Lattice +################################################### + +resource "aws_vpclattice_service_network" "this" { + name = var.name + auth_type = var.auth_type + + tags = merge( + { + "Name" = local.metadata.name + }, + local.module_tags, + var.tags, + ) +} + + +################################################### +# VPC Associations of Service Network +################################################### + +resource "aws_vpclattice_service_network_vpc_association" "this" { + for_each = { + for association in var.vpc_associations : + association.vpc => association + } + + service_network_identifier = aws_vpclattice_service_network.this.id + + vpc_identifier = each.key + security_group_ids = each.value.security_groups + + tags = merge( + { + "Name" = "${var.name}/${each.key}" + }, + local.module_tags, + var.tags, + each.value.tags, + ) +} + + +################################################### +# Service Associations of Service Network +################################################### + +resource "aws_vpclattice_service_network_service_association" "this" { + for_each = { + for association in var.service_associations : + association.name => association + } + + service_network_identifier = aws_vpclattice_service_network.this.id + + service_identifier = each.value.service + + tags = merge( + { + "Name" = "${var.name}/${each.key}" + }, + local.module_tags, + var.tags, + each.value.tags, + ) +} diff --git a/modules/lattice-service-network/outputs.tf b/modules/lattice-service-network/outputs.tf new file mode 100644 index 0000000..0cb6ccc --- /dev/null +++ b/modules/lattice-service-network/outputs.tf @@ -0,0 +1,122 @@ +output "id" { + description = "The ID of the service network." + value = aws_vpclattice_service_network.this.id +} + +output "arn" { + description = "The ARN of the service network." + value = aws_vpclattice_service_network.this.arn +} + +output "name" { + description = "The name of the service network." + value = aws_vpclattice_service_network.this.name +} + +output "auth_type" { + description = "The type of authentication and authorization that manages client access to the service network." + value = aws_vpclattice_service_network.this.auth_type +} + +output "vpc_associations" { + description = < { + id = association.id + arn = association.arn + status = association.status + created_by = association.created_by + + vpc = vpc + security_groups = association.security_group_ids + } + } +} + +output "service_associations" { + description = < { + id = association.id + arn = association.arn + status = association.status + created_by = association.created_by + + service = association.service + } + } +} + +output "logging" { + description = < 0 ? "SHARED_BY_ME" : "NOT_SHARED" + shares = module.share + } +} diff --git a/modules/lattice-service-network/policies.tf b/modules/lattice-service-network/policies.tf new file mode 100644 index 0000000..905cdfc --- /dev/null +++ b/modules/lattice-service-network/policies.tf @@ -0,0 +1,10 @@ +################################################### +# Auth Policy of Service Network +################################################### + +resource "aws_vpclattice_auth_policy" "this" { + count = var.auth_policy != null ? 1 : 0 + + resource_identifier = aws_vpclattice_service_network.this.arn + policy = var.auth_policy +} diff --git a/modules/lattice-service-network/ram-share.tf b/modules/lattice-service-network/ram-share.tf new file mode 100644 index 0000000..9a7e318 --- /dev/null +++ b/modules/lattice-service-network/ram-share.tf @@ -0,0 +1,32 @@ +################################################### +# Resource Sharing by RAM (Resource Access Manager) +################################################### + +module "share" { + source = "tedilabs/account/aws//modules/ram-share" + version = "~> 0.27.0" + + for_each = { + for share in var.shares : + share.name => share + } + + name = "vpc-lattice.service-network.${var.name}.${each.key}" + + resources = [ + aws_vpclattice_service_network.this.arn + ] + permissions = each.value.permissions + + external_principals_allowed = each.value.external_principals_allowed + principals = each.value.principals + + resource_group_enabled = false + module_tags_enabled = false + + tags = merge( + local.module_tags, + var.tags, + each.value.tags, + ) +} diff --git a/modules/lattice-service-network/resource-group.tf b/modules/lattice-service-network/resource-group.tf new file mode 100644 index 0000000..7487ba0 --- /dev/null +++ b/modules/lattice-service-network/resource-group.tf @@ -0,0 +1,31 @@ +locals { + resource_group_name = (var.resource_group_name != "" + ? var.resource_group_name + : join(".", [ + local.metadata.package, + local.metadata.module, + replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), + ]) + ) +} + + +module "resource_group" { + source = "tedilabs/misc/aws//modules/resource-group" + version = "~> 0.10.0" + + count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0 + + name = local.resource_group_name + description = var.resource_group_description + + query = { + resource_tags = local.module_tags + } + + module_tags_enabled = false + tags = merge( + local.module_tags, + var.tags, + ) +} diff --git a/modules/lattice-service-network/variables.tf b/modules/lattice-service-network/variables.tf new file mode 100644 index 0000000..a3acb86 --- /dev/null +++ b/modules/lattice-service-network/variables.tf @@ -0,0 +1,172 @@ +variable "name" { + description = "(Required) The name of the service network." + type = string + nullable = false +} + +variable "auth_type" { + description = <