diff --git a/CHANGELOG.md b/CHANGELOG.md index 3719fbf5..780d84c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ BREAKING CHANGES - Adds a new container named `consul-ecs-health-sync` to the task definition which will be responsible for syncing back ECS container health checks into Consul. This container will wait for a successful exit of `consul-ecs-mesh-init` container before starting. FEATURES +* Add support for transparent proxy in ECS tasks based on EC2 launch types. Following are the changes made to the `mesh-task` submodule [[GH-264](https://github.com/hashicorp/terraform-aws-consul-ecs/pull/264)] + - Adds the following variables [[GH-209](https://github.com/hashicorp/terraform-aws-consul-ecs/pull/209)] + - `enable_transparent_proxy` - Defaults to `true`. Fargate based tasks should explicitly pass `false` to avoid validation errors during terraform planning phase. + - `enable_consul_dns` - Defaults to `false`. Indicates whether Consul DNS should be configured for this task. Enabling this makes Consul dataplane start up a proxy DNS server that forwards requests to the Consul DNS server. `var.enable_transparent_proxy` should be `true` to enable this setting. + - `exclude_inbound_ports` - List of inbound ports to exclude from traffic redirection. + - `exclude_outbound_ports` - List of outbound ports to exclude from traffic redirection. + - `exclude_outbound_cidrs` - List of additional IP CIDRs to exclude from outbound traffic redirection. + - `exclude_outbound_uids` - List of additional process UIDs to exclude from traffic redirection. + - Adds the `CAP_NET_ADMIN` linux capability to the `mesh-init` container when `var.enable_transaparent_proxy` is set to `true`. This is needed to modify iptable rules within the ECS task. + - `mesh-init` container is run as a `root` user. + - Assign a UID of `5995` for the `consul-dataplane` container and `5996` for the `health-sync` container. This is done to selectively exclude the traffic flowing through these containers from the redirection rules. + * Add support for provisioning API gateways as ECS tasks [[GH-234](https://github.com/hashicorp/terraform-aws-consul-ecs/pull/234)] - Add `api-gateway` as an acceptable `kind` input. - Add `custom_load_balancer_config` input variable which can be used to feed in custom load balancer target group config that can be attached to the gateway's ECS task. diff --git a/modules/mesh-task/validation.tf b/modules/mesh-task/validation.tf index 39ac1ca1..15a82249 100644 --- a/modules/mesh-task/validation.tf +++ b/modules/mesh-task/validation.tf @@ -9,4 +9,5 @@ locals { require_no_additional_task_policies_with_passed_role = (!var.create_task_role && length(var.additional_task_role_policies) > 0) ? file("ERROR: cannot set additional_task_role_policies when create_task_role=false") : null require_no_additional_execution_policies_with_passed_role = (!var.create_execution_role && length(var.additional_execution_role_policies) > 0) ? file("ERROR: cannot set additional_execution_role_policies when create_execution_role=false") : null require_ec2_compability_for_tproxy_support = var.enable_transparent_proxy && (length(var.requires_compatibilities) != 1 || var.requires_compatibilities[0] != "EC2") ? file("ERROR: transparent proxy is supported only in ECS EC2 mode") : null + require_tproxy_enabled_for_consul_dns = var.enable_consul_dns && !var.enable_transparent_proxy ? file("ERROR: var.enable_transparent_proxy must be set to true for Consul DNS to be enabled") : null } \ No newline at end of file diff --git a/test/acceptance/tests/hcp/terraform/ap-tproxy/main.tf b/test/acceptance/tests/hcp/terraform/ap-tproxy/main.tf index d72a7b44..43b51c38 100644 --- a/test/acceptance/tests/hcp/terraform/ap-tproxy/main.tf +++ b/test/acceptance/tests/hcp/terraform/ap-tproxy/main.tf @@ -26,7 +26,7 @@ module "ecs_controller_1" { consul_server_hosts = var.consul_server_address ecs_cluster_arn = local.ecs_cluster_1_arn region = var.region - subnets = var.subnets + subnets = var.private_subnets name_prefix = var.suffix_1 consul_ecs_image = var.consul_ecs_image consul_partitions_enabled = true @@ -48,7 +48,7 @@ resource "aws_ecs_service" "test_client" { task_definition = module.test_client.task_definition_arn desired_count = 1 network_configuration { - subnets = var.subnets + subnets = var.private_subnets } launch_type = var.launch_type propagate_tags = "TASK_DEFINITION" @@ -122,7 +122,7 @@ module "ecs_controller_2" { consul_server_hosts = var.consul_server_address ecs_cluster_arn = local.ecs_cluster_2_arn region = var.region - subnets = var.subnets + subnets = var.private_subnets name_prefix = var.suffix_2 consul_ecs_image = var.consul_ecs_image consul_partitions_enabled = true @@ -144,7 +144,7 @@ resource "aws_ecs_service" "test_server" { task_definition = module.test_server.task_definition_arn desired_count = 1 network_configuration { - subnets = var.subnets + subnets = var.private_subnets } launch_type = var.launch_type propagate_tags = "TASK_DEFINITION" diff --git a/test/acceptance/tests/hcp/terraform/ap-tproxy/variables.tf b/test/acceptance/tests/hcp/terraform/ap-tproxy/variables.tf index 05062560..aefc534e 100644 --- a/test/acceptance/tests/hcp/terraform/ap-tproxy/variables.tf +++ b/test/acceptance/tests/hcp/terraform/ap-tproxy/variables.tf @@ -36,8 +36,13 @@ variable "route_table_ids" { type = list(string) } -variable "subnets" { - description = "Subnets to deploy into." +variable "private_subnets" { + description = "Private subnets to deploy into." + type = list(string) +} + +variable "public_subnets" { + description = "Public subnets to deploy into." type = list(string) } diff --git a/test/acceptance/tests/hcp/terraform/ns-tproxy/main.tf b/test/acceptance/tests/hcp/terraform/ns-tproxy/main.tf index f64f46c4..c2a3e53e 100644 --- a/test/acceptance/tests/hcp/terraform/ns-tproxy/main.tf +++ b/test/acceptance/tests/hcp/terraform/ns-tproxy/main.tf @@ -25,7 +25,7 @@ module "controller" { consul_server_hosts = var.consul_server_address ecs_cluster_arn = local.ecs_cluster_arn region = var.region - subnets = var.subnets + subnets = var.private_subnets name_prefix = var.suffix consul_ecs_image = var.consul_ecs_image consul_partitions_enabled = true @@ -46,7 +46,7 @@ resource "aws_ecs_service" "test_client" { task_definition = module.test_client.task_definition_arn desired_count = 1 network_configuration { - subnets = var.subnets + subnets = var.private_subnets } launch_type = var.launch_type propagate_tags = "TASK_DEFINITION" @@ -111,7 +111,7 @@ resource "aws_ecs_service" "test_server" { task_definition = module.test_server.task_definition_arn desired_count = 1 network_configuration { - subnets = var.subnets + subnets = var.private_subnets } launch_type = var.launch_type propagate_tags = "TASK_DEFINITION" diff --git a/test/acceptance/tests/hcp/terraform/ns-tproxy/variables.tf b/test/acceptance/tests/hcp/terraform/ns-tproxy/variables.tf index 2838d6bd..c2c9c4e6 100644 --- a/test/acceptance/tests/hcp/terraform/ns-tproxy/variables.tf +++ b/test/acceptance/tests/hcp/terraform/ns-tproxy/variables.tf @@ -21,9 +21,14 @@ variable "route_table_ids" { type = list(string) } -variable "subnets" { +variable "private_subnets" { + description = "Private subnets to deploy into." + type = list(string) +} + +variable "public_subnets" { + description = "Public subnets to deploy into." type = list(string) - description = "Subnets to deploy into." } variable "launch_type" { diff --git a/test/acceptance/tests/validation/terraform/tproxy-ec2-validate/main.tf b/test/acceptance/tests/validation/terraform/tproxy-validate/main.tf similarity index 55% rename from test/acceptance/tests/validation/terraform/tproxy-ec2-validate/main.tf rename to test/acceptance/tests/validation/terraform/tproxy-validate/main.tf index 55e61b89..0a088bfa 100644 --- a/test/acceptance/tests/validation/terraform/tproxy-ec2-validate/main.tf +++ b/test/acceptance/tests/validation/terraform/tproxy-validate/main.tf @@ -10,6 +10,18 @@ variable "requires_compatibilities" { type = list(string) } +variable "enable_transparent_proxy" { + description = "Whether to enable or disable transparent proxy for the task" + type = bool + default = true +} + +variable "enable_consul_dns" { + description = "Whether to enable or disable Consul DNS for the task" + type = bool + default = true +} + module "test_client" { source = "../../../../../../modules/mesh-task" family = "family" @@ -19,5 +31,6 @@ module "test_client" { outbound_only = true consul_server_hosts = "consul.dc1.host" requires_compatibilities = var.requires_compatibilities - enable_transparent_proxy = true + enable_transparent_proxy = var.enable_transparent_proxy + enable_consul_dns = var.enable_consul_dns } diff --git a/test/acceptance/tests/validation/validation_test.go b/test/acceptance/tests/validation/validation_test.go index 844be1e3..69039c52 100644 --- a/test/acceptance/tests/validation/validation_test.go +++ b/test/acceptance/tests/validation/validation_test.go @@ -1090,12 +1090,14 @@ func TestValidation_TerminatingGateway(t *testing.T) { } } -func TestValidation_TProxyEC2(t *testing.T) { +func TestValidation_TProxy(t *testing.T) { t.Parallel() cases := map[string]struct { requiresCompatibilities []string + disableTProxy bool error bool + errorStr string }{ "only EC2": { requiresCompatibilities: []string{"EC2"}, @@ -1103,15 +1105,23 @@ func TestValidation_TProxyEC2(t *testing.T) { "only Fargate": { requiresCompatibilities: []string{"FARGATE"}, error: true, + errorStr: "transparent proxy is supported only in ECS EC2 mode.", }, "both Fargate and EC2": { requiresCompatibilities: []string{"FARGATE", "EC2"}, error: true, + errorStr: "transparent proxy is supported only in ECS EC2 mode.", + }, + "Consul DNS does not work without enabling tproxy": { + requiresCompatibilities: []string{"FARGATE", "EC2"}, + disableTProxy: true, + error: true, + errorStr: "var.enable_transparent_proxy must be set to true for Consul DNS to be enabled.", }, } terraformOptions := &terraform.Options{ - TerraformDir: "./terraform/tproxy-ec2-validate", + TerraformDir: "./terraform/tproxy-validate", NoColor: true, } terraform.Init(t, terraformOptions) @@ -1122,17 +1132,22 @@ func TestValidation_TProxyEC2(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() + vars := map[string]interface{}{ + "requires_compatibilities": c.requiresCompatibilities, + } + if c.disableTProxy { + vars["enable_transparent_proxy"] = false + } + out, err := terraform.PlanE(t, &terraform.Options{ TerraformDir: terraformOptions.TerraformDir, NoColor: true, - Vars: map[string]interface{}{ - "requires_compatibilities": c.requiresCompatibilities, - }, + Vars: vars, }) if c.error { require.Error(t, err) - require.Regexp(t, "transparent proxy is supported only in ECS EC2 mode.", out) + require.Regexp(t, c.errorStr, out) } else { require.NoError(t, err) }