title: Terraform updating a one of many ECS service/task
body: <p>Happy Friday! hoping someone can help me with this issue or point out the flaws in my thinking.</p>
  
  <pre class="lang-sh prettyprint-override"><code>$ terraform --version
  Terraform v0.12.7
  + provider.aws v2.25.0
  + provider.template v2.1.2
  </code></pre>
  
  <h2>Preface</h2>
  
  <p>This is my first time using Terraform. We have an existing AWS ECS/Fargate environment up and running, this is in a 'test' environment. We recently (e.g. after setting up the test env) started to use Terraform for IaC purposes.</p>
  
  <h2>Current Config</h2>
  
  <p>The environment has a single ECS cluster, we're using FARGATE but I'm not sure that matters for this question. The cluster has several services, each service has a single task (docker image) associated with it - so they can be individually scaled. Each docker image has its own Repo.</p>
  
  <h2>What I'm trying to do</h2>
  
  <p>So with Terraform I was hoping to be able to create, update and destroy the environment. Creating/destroying seems fairly straight forward, however; I'm hitting a road-block for updating.</p>
  
  <p>As I said each task has its own repo, when a pull request is made against the repo our CI platform (CircleCI if that matters) builds the new docker image, tags it and pushes it. Then we use an API call to trigger a build of the Terraform Repo passing the name of the service/task that was updated.</p>
  
  <h2>Problem</h2>
  
  <p>The problem we're facing is that when going through the services (described below) I can't figure out how to get Terraform to either ignore the services that are not being updated, or how I can provide the correct <em>container_definitions</em> in the <em>aws_ecs_task_definition</em>, specifically the current image tag (we don't use the <a href="https://blog.container-solutions.com/docker-latest-confusion" rel="nofollow noreferrer">latest tag</a>). So I'm trying to figure out how I can get the latest container information (tag) or just tell Terraform to skip the unmodified task.</p>
  
  <h2>Terraform Script</h2>
  
  <p>Here is a stripped down version of what I have tried, this is in a module called <em>ecs.tf</em>, the <em>var.ecs_svc_names</em> is a <em>list</em> of the service names. I have removed some elements as I don't think they pertain to this issue and having them makes this very large.</p>
  
  <p><em>CAVEATS</em>
  I have not run the Terraform 'script' as shown below due to the issues I am asking about, so my syntax maybe a off. Sorry if that is the case, hopefully this will show you what I'm trying to do....</p>
  
  <p><em><strong>ecs.tf</strong></em></p>
  
  <pre><code>/* ecs_service_names is passed in, but here is its definition:
  variable "ecs_service_names" {
    type = list(string)
    description = "This is a list/array of the images/services that are contained in the cluster"
    default = [
      "main",
      "sub-service1",
      "sub-service2"]
  }
  */
  
  locals {
    numberOfServices = length(var.ecs_svc_names)
  }
  
  resource "aws_ecs_cluster" "ecs_cluster" {
    name = "${var.env_type}-ecs-cluster"
  }
  
  // Create the service objects (1 for each service)
  resource "aws_ecs_service" "ecs-service" {
    // How many services are being created
    count = local.numberOfServices
    name = var.ecs_svc_names[count.index]
    cluster = aws_ecs_cluster.ecs_cluster.id
   definition[count.index].family}:${max(aws_ecs_task_definition.ecs-task-definition[count.index].revision, data.aws_ecs_task_definition.ecs-task-def.revision)}"
    desired_count = 1
    launch_type = "FARGATE"
  // stuff removed
  }
  
  resource "aws_ecs_task_definition" "ecs-task-definition" {
    // How many tasks. There is a 1-1 relationship between tasks and services
    count = local.numberOfServices
    family = var.ecs_svc_names[count.index]
    network_mode = "awsvpc"
    requires_compatibilities = ["FARGATE"]
  // cpu/memory stuff removed
    task_role_arn = var.ecs_task_role_arn
  
    container_definitions = data.template_file.ecs_containers_json[count.index].rendered
  }
  </code></pre>
  
  <p><em><strong>data.tf</strong></em></p>
  
  <pre><code>locals {
      numberOfServices = length(var.ecs_svc_names)
  }
  data "aws_ecs_task_definition" "ecs-task-def" {
      // How many services are being created, 1-1 relationship between tasks and services
      count = local.numberOfServices
      task_definition = aws_ecs_task_definition.ecs-task-definition[count.index].family
  
      depends_on = [
          "aws_ecs_task_definition.ecs-task-definition",
      ]
  }
  
  data "template_file" "ecs_containers_json" {
      // How many tasks. There is a 1-1 relationship between tasks and services
      count = local.numberOfServices
    template = file("${path.module}/container.json.template")
    vars = {
  // vars removed
  
        image = aws_ecs_task_definition.ecs-task-definition[count.index].family
  
  // This is where I hit the road-block, how do I get the current docker tag from Terraform?
        tag = var.ecs_svc_name_2_update == var.ecs_svc_names[count.index]
              ? var.ecs_svc_image_tag
              : data.aws_ecs_task_definition.ecs-task-def[count.index].
  }
  </code></pre>
  
  <p>I didn't post the JSON document, if you need that I can provide it...</p>
  
  <p>Thank you</p>