Search code examples
amazon-web-servicesamazon-ec2amazon-ecs

Using AWS ECS Placement Constraints with instance tags


Is it possible to constrain the placement of ECS tasks based on instance tags? I have EC2 instances in the ECS cluster that are tagged, and would like to use this to ensure certain tasks run on those instances? I don't see how it can be done.

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-constraints.html


Solution

  • Here is a snippet of Terraform config to illustrate how to implement this approach

    data aws_ssm_parameter amazonLinux2 {
      name = "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id"
    }
    
    resource aws_instance elasticsearchInstance {
      ami = data.aws_ssm_parameter.amazonLinux2.value
      instance_type = "t2.medium"
      availability_zone = data.aws_availability_zones.available.names[0]
      subnet_id = aws_subnet.ecsPrivateSubnet.id
      associate_public_ip_address = false
      iam_instance_profile = aws_iam_instance_profile.ecs_agent.name
    
      user_data = <<EOT
    #!/bin/bash
    echo 'ECS_CLUSTER=clusterName' >> /etc/ecs/ecs.config
    echo 'ECS_INSTANCE_ATTRIBUTES={"type": "elasticsearch"}' >> /etc/ecs/ecs.config
    EOT
    }
    
    resource "aws_ecs_task_definition" "elasticsearchTask" {
      family = "elasticsearch"
      network_mode = "awsvpc"
      container_definitions = jsonencode([
        {
          name      = "elasticsearch"
          image     = "docker.elastic.co/elasticsearch/elasticsearch:7.15.2"
          cpu       = 2048
          memory    = 3942
          essential = true
          portMappings = [
            {
              containerPort = 9200
            }
          ]
        }
      ])
      placement_constraints {
        type       = "memberOf"
        expression = "attribute:type == elasticsearch"
      }
    }
    

    The is not a full configuration, but the core bits are setting the user_data to add ECS_INSTANCE_ATTRIBUTES in this case type=elasticsearch and then adding placement_constraints to the task definition that forces the task onto the instance.