From a2f5711b165bc093a7a2d5166b9e7d96cd7fb60a Mon Sep 17 00:00:00 2001 From: alismx Date: Tue, 8 Oct 2024 20:54:29 -0400 Subject: [PATCH] update private subnets so they can pull from ecr --- terraform/implementation/ecs/README.md | 7 ++++--- terraform/implementation/ecs/_variable.tf | 10 ++++++++-- terraform/implementation/ecs/main.tf | 8 +++++--- terraform/implementation/setup/README.md | 6 +++--- terraform/modules/ecs/README.md | 7 +++++-- terraform/modules/ecs/_data.tf | 5 +++++ terraform/modules/ecs/_local.tf | 10 ++++++++++ terraform/modules/ecs/_variable.tf | 4 ++-- terraform/modules/ecs/alb.tf | 24 +++++++++++++++++++++-- terraform/modules/oidc/_data.tf | 1 + 10 files changed, 65 insertions(+), 17 deletions(-) diff --git a/terraform/implementation/ecs/README.md b/terraform/implementation/ecs/README.md index 42c09a7..e78e653 100644 --- a/terraform/implementation/ecs/README.md +++ b/terraform/implementation/ecs/README.md @@ -9,7 +9,7 @@ | Name | Version | |------|---------| -| [aws](#provider\_aws) | =5.56.1 | +| [aws](#provider\_aws) | 5.56.1 | ## Modules @@ -29,17 +29,18 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [availability\_zones](#input\_availability\_zones) | The availability zones to use | `list(string)` |
[
"us-east-1a",
"us-east-1b",
"us-east-1c"
]
| no | +| [create\_internet\_gateway](#input\_create\_internet\_gateway) | Flag to determine if an internet gateway should be created | `bool` | `false` | no | | [ecr\_viewer\_database\_schema](#input\_ecr\_viewer\_database\_schema) | The database schema used for the eCR data tables | `string` | `"core"` | no | | [ecr\_viewer\_database\_type](#input\_ecr\_viewer\_database\_type) | The SQL variant used for the eCR data tables | `string` | `"postgres"` | no | | [ecs\_alb\_sg](#input\_ecs\_alb\_sg) | The security group for the Application Load Balancer | `string` | `"ecs-albsg"` | no | -| [enable\_nat\_gateway](#input\_enable\_nat\_gateway) | Enable NAT Gateway | `bool` | `true` | no | +| [enable\_nat\_gateway](#input\_enable\_nat\_gateway) | Enable NAT Gateway | `bool` | `false` | no | | [owner](#input\_owner) | The owner of the infrastructure | `string` | `"skylight"` | no | | [phdi\_version](#input\_phdi\_version) | PHDI container image version | `string` | `"v1.4.4"` | no | | [private\_subnets](#input\_private\_subnets) | The private subnets | `list(string)` |
[
"176.24.1.0/24",
"176.24.3.0/24"
]
| no | | [project](#input\_project) | The project name | `string` | `"dibbs-ce"` | no | | [public\_subnets](#input\_public\_subnets) | The public subnets | `list(string)` |
[
"176.24.2.0/24",
"176.24.4.0/24"
]
| no | | [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | -| [single\_nat\_gateway](#input\_single\_nat\_gateway) | Single NAT Gateway | `bool` | `true` | no | +| [single\_nat\_gateway](#input\_single\_nat\_gateway) | Single NAT Gateway | `bool` | `false` | no | | [vpc](#input\_vpc) | The name of the VPC | `string` | `"ecs-vpc"` | no | | [vpc\_cidr](#input\_vpc\_cidr) | The CIDR block for the VPC | `string` | `"176.24.0.0/16"` | no | diff --git a/terraform/implementation/ecs/_variable.tf b/terraform/implementation/ecs/_variable.tf index fe108a8..c09f967 100644 --- a/terraform/implementation/ecs/_variable.tf +++ b/terraform/implementation/ecs/_variable.tf @@ -4,6 +4,12 @@ variable "availability_zones" { default = ["us-east-1a", "us-east-1b", "us-east-1c"] } +variable "create_internet_gateway" { + type = bool + description = "Flag to determine if an internet gateway should be created" + default = false +} + variable "ecs_alb_sg" { description = "The security group for the Application Load Balancer" type = string @@ -13,7 +19,7 @@ variable "ecs_alb_sg" { variable "enable_nat_gateway" { description = "Enable NAT Gateway" type = bool - default = true + default = false } variable "owner" { @@ -56,7 +62,7 @@ variable "region" { variable "single_nat_gateway" { description = "Single NAT Gateway" type = bool - default = true + default = false } variable "vpc" { diff --git a/terraform/implementation/ecs/main.tf b/terraform/implementation/ecs/main.tf index 254f717..858cddf 100644 --- a/terraform/implementation/ecs/main.tf +++ b/terraform/implementation/ecs/main.tf @@ -8,6 +8,7 @@ module "vpc" { public_subnets = var.public_subnets enable_nat_gateway = var.enable_nat_gateway single_nat_gateway = var.single_nat_gateway + create_igw = var.create_internet_gateway tags = local.tags } @@ -18,14 +19,15 @@ module "ecs" { private_subnet_ids = flatten(module.vpc.private_subnets) vpc_id = module.vpc.vpc_id region = var.region - alb_internal = false owner = var.owner project = var.project tags = local.tags - + # If intent is to pull from the phdi GHCR, set disable_ecr to true (default is false) # disable_ecr = true - # If intent is to use the non-integrated viewer, set non_integrated_viewer to true (default is false) + # If intent is to use the non-integrated viewer, set non_integrated_viewer to "true" (default is false) # non_integrated_viewer = "true" + # If the intent is to make the ecr-viewer availabble on the public internet, set internal to false (default is true) This requires an internet gateway to be present in the VPC. + # internal = false } diff --git a/terraform/implementation/setup/README.md b/terraform/implementation/setup/README.md index 4c2655d..1c95943 100644 --- a/terraform/implementation/setup/README.md +++ b/terraform/implementation/setup/README.md @@ -7,9 +7,9 @@ No requirements. | Name | Version | |------|---------| -| [aws](#provider\_aws) | n/a | -| [local](#provider\_local) | n/a | -| [random](#provider\_random) | n/a | +| [aws](#provider\_aws) | 5.70.0 | +| [local](#provider\_local) | 2.5.2 | +| [random](#provider\_random) | 3.6.3 | ## Modules diff --git a/terraform/modules/ecs/README.md b/terraform/modules/ecs/README.md index 996be1c..5ec2d8f 100644 --- a/terraform/modules/ecs/README.md +++ b/terraform/modules/ecs/README.md @@ -51,6 +51,8 @@ No modules. | [aws_security_group_rule.ecs_all_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_security_group_rule.ecs_ecs_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_service_discovery_private_dns_namespace.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/service_discovery_private_dns_namespace) | resource | +| [aws_vpc_endpoint.endpoints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_endpoint) | resource | +| [aws_vpc_endpoint.s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_endpoint) | resource | | [dockerless_remote_image.dibbs](https://registry.terraform.io/providers/nullstone-io/dockerless/0.1.1/docs/resources/remote_image) | resource | | [null_resource.target_groups](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [random_string.s3_viewer](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | @@ -60,12 +62,12 @@ No modules. | [aws_iam_policy.ecs_task_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source | | [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.ecr_viewer_s3](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_route_table.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route_table) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [alb\_internal](#input\_alb\_internal) | Flag to determine if the ALB is public (intended for external access) or private (only intended to be accessed within your AWS VPC). | `bool` | `true` | no | | [appmesh\_name](#input\_appmesh\_name) | Name of the AWS App Mesh | `string` | `""` | no | | [cloudmap\_namespace\_name](#input\_cloudmap\_namespace\_name) | Name of the AWS Cloud Map namespace | `string` | `""` | no | | [cloudmap\_service\_name](#input\_cloudmap\_service\_name) | Name of the AWS Cloud Map service | `string` | `""` | no | @@ -81,9 +83,10 @@ No modules. | [ecs\_cluster\_name](#input\_ecs\_cluster\_name) | Name of the ECS Cluster | `string` | `""` | no | | [ecs\_task\_execution\_role\_name](#input\_ecs\_task\_execution\_role\_name) | Name of the ECS Task Execution Role | `string` | `""` | no | | [ecs\_task\_role\_name](#input\_ecs\_task\_role\_name) | Name of the ECS Task Role | `string` | `""` | no | +| [internal](#input\_internal) | Flag to determine if the several AWS resources are public (intended for external access, public internet) or private (only intended to be accessed within your AWS VPC or avaiable with other means, a transit gateway for example). | `bool` | `true` | no | | [non\_integrated\_viewer](#input\_non\_integrated\_viewer) | A flag to determine if the viewer is the non-integrated version | `string` | `"false"` | no | | [owner](#input\_owner) | Owner of the resources | `string` | `"CDC"` | no | -| [phdi\_version](#input\_phdi\_version) | Version of the PHDI application | `string` | `"v1.6.4"` | no | +| [phdi\_version](#input\_phdi\_version) | Version of the PHDI application | `string` | `"v1.6.9"` | no | | [private\_subnet\_ids](#input\_private\_subnet\_ids) | List of private subnet IDs | `list(string)` | n/a | yes | | [project](#input\_project) | The project name | `string` | `"dibbs"` | no | | [public\_subnet\_ids](#input\_public\_subnet\_ids) | List of public subnet IDs | `list(string)` | n/a | yes | diff --git a/terraform/modules/ecs/_data.tf b/terraform/modules/ecs/_data.tf index 84b5df3..cc21fa5 100644 --- a/terraform/modules/ecs/_data.tf +++ b/terraform/modules/ecs/_data.tf @@ -33,3 +33,8 @@ data "aws_iam_policy" "ecs_task_execution" { data "aws_iam_policy" "amazon_ec2_container_service_for_ec2_role" { name = "AmazonEC2ContainerServiceforEC2Role" } + +data "aws_route_table" "this" { + for_each = { for rt in local.private_subnet_ids : rt => rt } + subnet_id = each.key +} \ No newline at end of file diff --git a/terraform/modules/ecs/_local.tf b/terraform/modules/ecs/_local.tf index af599ac..8cf3490 100644 --- a/terraform/modules/ecs/_local.tf +++ b/terraform/modules/ecs/_local.tf @@ -183,4 +183,14 @@ locals { s3_viewer_bucket_name = var.s3_viewer_bucket_name == "" ? "${local.local_name}-${random_string.s3_viewer.result}" : var.s3_viewer_bucket_name s3_viewer_bucket_role_name = var.s3_viewer_bucket_role_name == "" ? "${local.local_name}-ecrv" : var.s3_viewer_bucket_role_name tags = var.tags + vpc_endpoints = [ + "com.amazonaws.${var.region}.ecr.dkr", + "com.amazonaws.${var.region}.ecr.api", + "com.amazonaws.${var.region}.ecs", + "com.amazonaws.${var.region}.ecs-telemetry", + "com.amazonaws.${var.region}.logs", + "com.amazonaws.${var.region}.secretsmanager", + ] + s3_service_name = "com.amazonaws.${var.region}.s3" + private_subnet_ids = var.private_subnet_ids } diff --git a/terraform/modules/ecs/_variable.tf b/terraform/modules/ecs/_variable.tf index 04f8834..14ad01f 100644 --- a/terraform/modules/ecs/_variable.tf +++ b/terraform/modules/ecs/_variable.tf @@ -1,6 +1,6 @@ -variable "alb_internal" { +variable "internal" { type = bool - description = "Flag to determine if the ALB is public (intended for external access) or private (only intended to be accessed within your AWS VPC)." + description = "Flag to determine if the several AWS resources are public (intended for external access, public internet) or private (only intended to be accessed within your AWS VPC or avaiable with other means, a transit gateway for example)." default = true } variable "appmesh_name" { diff --git a/terraform/modules/ecs/alb.tf b/terraform/modules/ecs/alb.tf index 31bbe12..bbcd289 100644 --- a/terraform/modules/ecs/alb.tf +++ b/terraform/modules/ecs/alb.tf @@ -2,9 +2,9 @@ # trivy:ignore:AVD-AWS-0053 resource "aws_alb" "ecs" { name = local.ecs_alb_name - internal = var.alb_internal + internal = var.internal load_balancer_type = "application" - subnets = flatten([var.public_subnet_ids]) + subnets = var.internal == true ? flatten([var.private_subnet_ids]) : flatten([var.public_subnet_ids]) security_groups = [aws_security_group.alb.id] drop_invalid_header_fields = true @@ -36,6 +36,26 @@ resource "aws_alb_target_group" "this" { tags = local.tags } +resource "aws_vpc_endpoint" "endpoints" { + count = var.internal == true ? length(local.vpc_endpoints) : 0 + vpc_id = var.vpc_id + vpc_endpoint_type = "Interface" + private_dns_enabled = true + service_name = local.vpc_endpoints[count.index] + security_group_ids = [aws_security_group.ecs.id] + subnet_ids = flatten([var.private_subnet_ids]) + tags = local.tags +} + +resource "aws_vpc_endpoint" "s3" { + count = var.internal == true ? 1 : 0 + vpc_id = var.vpc_id + vpc_endpoint_type = "Gateway" + route_table_ids = [for rt in data.aws_route_table.this : rt.id] + service_name = local.s3_service_name + tags = local.tags +} + # The aws_alb_listener and aws_alb_listener_rule resources are not depended on by other resources so # they can be implemented via a loop or hard coded depending ease of maintenance # I've chosen the ways that reduce duplicated resource blocks: hard coded listener (i.e. http), looped listener rule (i.e. this) diff --git a/terraform/modules/oidc/_data.tf b/terraform/modules/oidc/_data.tf index 5cda2aa..61e2651 100644 --- a/terraform/modules/oidc/_data.tf +++ b/terraform/modules/oidc/_data.tf @@ -41,6 +41,7 @@ data "aws_iam_policy_document" "storage" { "${var.state_bucket_arn}", "${var.state_bucket_arn}/*", "${var.dynamodb_table_arn}", + "arn:aws:s3:::prod-region-starport-layer-bucket/*" ] } }