Migrate Tasks to Consul on AWS Elastic Container Service (ECS) with Terraform

This topic describes how to migrate your existing ECS Tasks to use our mesh-task Terraform module.

Define Tasks in Terraform

Your tasks must first be specified in Terraform using the ecs_task_definition resource so that they can then be converted to use the mesh-task module.

For example, your tasks should be defined with Terraform similar to the following:

  1. resource "aws_ecs_task_definition" "my_task" {
  2. family = "my_task"
  3. requires_compatibilities = ["FARGATE"]
  4. network_mode = "awsvpc"
  5. cpu = 256
  6. memory = 512
  7. execution_role_arn = "arn:aws:iam::111111111111:role/execution-role"
  8. task_role_arn = "arn:aws:iam::111111111111:role/task-role"
  9. container_definitions = jsonencode(
  10. [{
  11. name = "example-client-app"
  12. image = "docker.io/org/my_task:v0.0.1"
  13. essential = true
  14. portMappings = [
  15. {
  16. containerPort = 9090
  17. hostPort = 9090
  18. protocol = "tcp"
  19. }
  20. ]
  21. cpu = 0
  22. mountPoints = []
  23. volumesFrom = []
  24. }]
  25. )
  26. }
  27. resource "aws_ecs_service" "my_task" {
  28. name = "my_task"
  29. cluster = "arn:aws:ecs:us-east-1:111111111111:cluster/my-cluster"
  30. task_definition = aws_ecs_task_definition.my_task.arn
  31. desired_count = 1
  32. network_configuration {
  33. subnets = ["subnet-abc123"]
  34. }
  35. launch_type = "FARGATE"
  36. }

Convert to the mesh-task Module

In order to add the necessary sidecar containers for your task to join the mesh, you must use the mesh-task module.

The mesh-task module uses inputs similar to your old ECS task definition but creates a new version of the task definition with additional containers.

The mesh-task module is used as follows:

  1. module "my_task" {
  2. source = "hashicorp/consul-ecs/aws//modules/mesh-task"
  3. version = "<latest version>"
  4. family = "my_task"
  5. container_definitions = [
  6. {
  7. name = "example-client-app"
  8. image = "docker.io/org/my_task:v0.0.1"
  9. essential = true
  10. portMappings = [
  11. {
  12. containerPort = 9090
  13. hostPort = 9090
  14. protocol = "tcp"
  15. }
  16. ]
  17. cpu = 0
  18. mountPoints = []
  19. volumesFrom = []
  20. }
  21. ]
  22. port = 9090
  23. retry_join = ["<address of the Consul server>"]
  24. }

The main differences are:

  • You should remove the execution_role_arn and task_role_arn fields. The mesh-task module creates the task and execution roles by default. If you need to use existing IAM role(s), set the task_role and execution_role fields to pass in existing roles.
  • You must set the port field to the port that your application listens on. If your application has no listening port, set outbound_only = true and remove the port field.
  • You must add the retry_join field. This specifies the location of your Consul servers so that your task can join the mesh.
  • You must remove the jsonencode() function from the container_definitions field.

The mesh-task module will create a new version of your task definition with the necessary sidecar containers added so you can delete your existing aws_ecs_task_definition resource.

Next Steps

Now that your task(s) are migrated to the mesh-task module,