3

Using Terraform, I have tried the hardest to find out how to create 1 ECS cluster and have multiple services running under it. SO basically i have 2 different containers i want to run with this 1 ECS cluster.

How do i do this? I have seen many examples but usually 1 service with 1 ECS cluster

So from this link i got a template https://www.terraform.io/docs/providers/aws/d/ecs_task_definition.html

# Simply specify the family to find the latest ACTIVE revision in that family.
data "aws_ecs_task_definition" "mongo" {
  task_definition = "${aws_ecs_task_definition.mongo.family}"
}

resource "aws_ecs_cluster" "foo" {
  name = "foo"
}

resource "aws_ecs_task_definition" "mongo" {
  family = "mongodb"

  container_definitions = <<DEFINITION
[
  {
    "cpu": 128,
    "environment": [{
      "name": "SECRET",
      "value": "KEY"
    }],
    "essential": true,
    "image": "mongo:latest",
    "memory": 128,
    "memoryReservation": 64,
    "name": "mongodb"
  }
]
DEFINITION
}

resource "aws_ecs_service" "mongo" {
  name          = "mongo"
  cluster       = "${aws_ecs_cluster.foo.id}"
  desired_count = 2

  # Track the latest ACTIVE revision
  task_definition = "${aws_ecs_task_definition.mongo.family}:${max("${aws_ecs_task_definition.mongo.revision}", "${data.aws_ecs_task_definition.mongo.revision}")}"
}

So lets say i want to add a node app service to that how will it look? And have them both run on the same cluster

Thanks!

uberrebu
  • 493
  • 5
  • 15
  • 32

3 Answers3

2

You simply create another aws_ecs_service and aws_ecs_task_definition resources.

If you want it running on the same cluster, just specify the same cluster ID in the cluster param.

So it would look something like this

# Simply specify the family to find the latest ACTIVE revision in that family.
data "aws_ecs_task_definition" "mongo" {
  task_definition = "${aws_ecs_task_definition.mongo.family}"
}

data "aws_ecs_task_definition" "nginx" {
  task_definition = "${aws_ecs_task_definition.nginx.family}"
}

resource "aws_ecs_cluster" "foo" {
  name = "foo"
}


# ======================  TASKS ===================
resource "aws_ecs_task_definition" "mongo" {
  family = "mongodb"

  container_definitions = <<DEFINITION
[
  {
    "cpu": 128,
    "environment": [{
      "name": "SECRET",
      "value": "KEY"
    }],
    "essential": true,
    "image": "mongo:latest",
    "memory": 128,
    "memoryReservation": 64,
    "name": "mongodb"
  }
]
DEFINITION
}

resource "aws_ecs_task_definition" "nginx" {
  family = "nginx"

  container_definitions = <<DEFINITION
[
  {
    "cpu": 128,
    "environment": [{
      "name": "SECRET",
      "value": "KEY"
    }],
    "essential": true,
    "image": "nginx:latest",
    "memory": 128,
    "memoryReservation": 64,
    "name": "nginx"
  }
]
DEFINITION
}

# ======================  SERVICES ===================

resource "aws_ecs_service" "mongo" {
  name          = "mongo"
  cluster       = "${aws_ecs_cluster.foo.id}"
  desired_count = 2

  # Track the latest ACTIVE revision
  task_definition = "${aws_ecs_task_definition.mongo.family}:${max("${aws_ecs_task_definition.mongo.revision}", "${data.aws_ecs_task_definition.mongo.revision}")}"
}

resource "aws_ecs_service" "nginx" {
  name          = "nginx"
  cluster       = "${aws_ecs_cluster.foo.id}"
  desired_count = 2

  # Track the latest ACTIVE revision
  task_definition = "${aws_ecs_task_definition.nginx.family}:${max("${aws_ecs_task_definition.nginx.revision}", "${data.aws_ecs_task_definition.nginx.revision}")}"
}

There is another way of running multiple containers on ECS.

You can place both Nginx and MongoDB on the same instance and under the same Task/Service.

It would look like this

# Simply specify the family to find the latest ACTIVE revision in that family.
data "aws_ecs_task_definition" "webapp" {
  task_definition = "${aws_ecs_task_definition.webapp.family}"
}

resource "aws_ecs_cluster" "foo" {
  name = "foo"
}


# ======================  TASKS ===================

resource "aws_ecs_task_definition" "webapp" {
  family = "webapp"

  container_definitions = <<DEFINITION
[
  {
    "cpu": 128,
    "environment": [{
      "name": "SECRET",
      "value": "KEY"
    }],
    "essential": true,
    "image": "nginx:latest",
    "memory": 128,
    "memoryReservation": 64,
    "name": "nginx"
  },
  {
    "cpu": 128,
    "environment": [{
      "name": "SECRET",
      "value": "KEY"
    }],
    "essential": true,
    "image": "mongo:latest",
    "memory": 128,
    "memoryReservation": 64,
    "name": "mongodb"
  }
]
DEFINITION
}

# ======================  SERVICES ===================

resource "aws_ecs_service" "webapp" {
  name          = "webapp"
  cluster       = "${aws_ecs_cluster.foo.id}"
  desired_count = 1

  # Track the latest ACTIVE revision
  task_definition = "${aws_ecs_task_definition.webapp.family}:${max("${aws_ecs_task_definition.webapp.revision}", "${data.aws_ecs_task_definition.webapp.revision}")}"
}

The advantage of the first method is that you can scale and manage each container independently.

The advantage of the second method is that the containers will be placed on the same EC2 instance and can be linked but can not be scaled independently. When you set desired count to N, you will get N number of "webapp" (so both Nginx and MongoDB instances). With the first method you can have N number of Nginx and X number of MongoDB.

Hope this helps.

NOTE : Terraform code has not been tested.

Andrey
  • 548
  • 2
  • 8
  • yes i later figured it out..i did have the task definitions described but the `deafult` cluster was killing me, but i recovered from the death after finding the root cause..thanks though for taking the time to reply..i will mark yours as answer – uberrebu Apr 10 '17 at 19:50
1

@babababa To your point of making sure the Container Instances (the actual AWS hosts) join the proper cluster, the best practice is to use a user data script to make them join the cluster at instance creation. This will avoid your having to manually edit the ECS agent config.

So however you're creating the actual EC2 instances that form the ECS cluster (either manually, auto-scaling group or through Terraform), you should add something similar to the following to the user data for those instances:

#!/bin/bash
echo ECS_CLUSTER=your_cluster_name >> /etc/ecs/ecs.config
0

Yes i think i later found out what the issue was. I had to edit the /etc/ecs/ecs.config file and set the cluster name so that the instances register with the cluster and then the services are run on the instances using the different task definitions.

The issue i was facing before was that instances were ending up in a default cluster and no way to have my services run on them, since task definitions are set by the cluster i wanted and not the default cluster

So the issue to solve my problem was editing the /etc/ecs/ecs.config appropriately

uberrebu
  • 493
  • 5
  • 15
  • 32