Not able to figure out the issue related to the variables

I have the ECS main code with the name aidbox_ecs.tf with the following line of code:

ecs.tf

resource "aws_ecs_cluster" "main" {
  name = "cb-cluster"
}

data "template_file" "cb_app" {
 template = file("./templates/ecs/cb_app.json.tpl")

  vars = {
    app_image      = var.app_image
    app_port       = var.app_port
    fargate_cpu    = var.fargate_cpu
    fargate_memory = var.fargate_memory
    aws_region     = var.aws_region
  }
}

resource "aws_ecs_task_definition" "app" {
  family                   = "cb-app-task"
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = var.fargate_cpu
  memory                   = var.fargate_memory
  container_definitions    = data.template_file.cb_app.rendered
}

resource "aws_ecs_service" "main" {
  name            = "cb-service"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count = 1
  launch_type     = "FARGATE"

  network_configuration {
    security_groups  = [aws_security_group.ecs_tasks.id]
    subnets          = aws_subnet.public.*.id
    assign_public_ip = true
  }

  depends_on = [aws_iam_role_policy_attachment.ecs_task_execution_role, aws_db_instance.dev-db]
}

And the ./templates/ecs/cb_app.json.tpl file contains the following code.

[
  {
    "name": "cb-app",
    "image": "${app_image}",
    "cpu": ${fargate_cpu},
    "memory": ${fargate_memory},
    "networkMode": "awsvpc",
    "environment": [
        { 
          "name" : "AIDBOX_ADMIN_ID",
          "value" : "admin"
        },
        { "name" : "AIDBOX_ADMIN_PASSWORD",
          "value" : "secret"
        },
        { 
          "name" : "AIDBOX_CLIENT_ID", 
          "value" : "root"
        },
        {
          "name" : "AIDBOX_CLIENT_SECRET",
          "value" : "secret"
        },
        { 
          "name" : "AIDBOX_CORRECT_AIDBOX_FORMAT", 
          "value" : "true" 
        },
        {
          "name" : "AIDBOX_LICENSE_ID", 
          "value" : "chggsvsg457829hsskkubsgs64hjs" 
        },
        { 
          "name" : "AIDBOX_LICENSE_KEY", 
          "value" : "jdfshdejy4674797672gssst3t53w" 
        },
        { 
          "name" : "AIDBOX_PORT",
          "value" : "8888"
        },
        { 
          "name" : "AIDBOX_ZEN_ENTRYPOINT", 
          "value" : "hl7-fhir-us-core","hl7-fhir-us-dme-orders"
        },
        { 
          "name" : "AIDBOX_ZEN_PATHS",
          "value" : "url:zip:https://github.com/zen-lang/fhir/releases/latest/download/hl7-fhir-us-core.zip,url:zip:https://github.com/zen-lang/fhir/releases/latest/download/hl7-fhir-us-dme-orders.zip"
        },
        { 
          "name" : "PGDATABASE",
          "value" : "devbox"
        },
        {
          "name" : "PGHOST",
          "value" : "aws_db_instance.dev-db.name" 
        },
        { 
          "name" : "PGPASSWORD",
          "value" : "postgreshshhsggs"
        },
        { 
          "name" : "PGPORT", 
          "value" : "5432" 
        },
        { 
          "name" : "PGUSER", 
          "value" : "postgres"
        }
        ],
    "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/cb-app",
          "awslogs-region": "${aws_region}",
          "awslogs-stream-prefix": "ecs"
        }
    },
    "portMappings": [
      {
        "containerPort": ${app_port},
        "hostPort": ${app_port}
      }
    ]
  }
]

And when I hot the command, terraform validate, I get the following error:

 Error: ECS Task Definition container_definitions is invalid: Error decoding JSON: invalid character '}' after object key

Hi @Desh-Deepak-Dhobi!

It seems like you’ve encountered a classic problem with trying to generate JSON using string concatenation: it’s tricky to make sure all of the delimiters and punction are correct when inserting other content that may itself need special encoding, etc.

It’s for this reason that we have some special advice on Generating JSON and YAML from a template, which involves using the jsonencode function to create a guaranteed-valid JSON string from a data structure, so that it can be Terraform’s problem to create the valid JSON, rather than you having to deal with it manually in your template.

You are using the obsolete template_file data source instead of the templatefile function, so what’s available there will depend on what functions are compiled into the hashicorp/template provider release you are using, but I believe the latest release was recent enough to include the jsonencode function that should work the same way as it would for the templatefile function. If you can move to using the built-in templatefile function instead though, it will avoid the need to install this extra provider and integrate this behavior better into the main language.

1 Like