Search code examples
amazon-web-servicesterraformterraform-provider-aws

Retrieve ssm parameter by path and set to ECS task definition in terraform


I'm creating a task definition with terraform and the containers need a few variables that are stored in SSM parameter store. I'm getting them by path but I when I set them to task definition, I get this error:

creating ECS Task Definition (superset): ClientException: Environment variable name cannot be null or blank

My code

data "aws_ssm_parameters_by_path" "superset_prod" {
  path = "/prod/superset/"
  recursive = true
}

resource "aws_ecs_task_definition" "superset_task_definition" {
  family                   = "superset"
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  task_role_arn            = aws_iam_role.ecs_task_role.arn
  requires_compatibilities = ["FARGATE"]
  memory                   = 1024
  cpu                      = 512
  network_mode             = "awsvpc"

  container_definitions = jsonencode([
    {
      name = local.services.superset_app.service_name
      image     = local.superset_image
      memory    = 1024
      user = "root"
      command = ["/app/docker/docker-bootstrap.sh", "app-gunicorn"]
      cpu       = 512
      essential = true
      portMappings = [
        {
          containerPort = local.services.superset_app.port
          hostPort      = local.services.superset_app.port
          protocol      = "tcp"
        }
      ],
      environment = [
        data.aws_ssm_parameters_by_path.superset_prod

      ]
      secrets = []
      logConfiguration = {
        logDriver = "awsfirelens",
        options = {
          Name               = "es"
          Cloud_ID           = var.elastic_cloud_id
          Index              = "filebeat-8.6.1"
          tls                = "On"
          "tls.verify"       = "Off"
          Tag_Key            = "tags"
          Include_Tag_Key    = "true"
          Retry_Limit        = "10"
          Suppress_Type_Name = "On"
          Trace_Output       = "On" # DEBUG
          Trace_Error        = "On" # DEBUG
          Replace_Dots       = "On"
        }
        secretOptions = []
      },
      mountPoints = [],
      volumesFrom = [],
      dependsOn   = []
    },
  tags = {
    environment = local.environment
  }
}

How can I set all the parameters in the environment variable for the container?


Solution

  • Based on your question, I would say you want to use the ARNs of the parameters directly, something like the following:

    resource "aws_ecs_task_definition" "superset_task_definition" {
      family                   = "superset"
      execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
      task_role_arn            = aws_iam_role.ecs_task_role.arn
      requires_compatibilities = ["FARGATE"]
      memory                   = 1024
      cpu                      = 512
      network_mode             = "awsvpc"
    
      container_definitions = jsonencode([
        {
          name = local.services.superset_app.service_name
          image     = local.superset_image
          memory    = 1024
          user = "root"
          command = ["/app/docker/docker-bootstrap.sh", "app-gunicorn"]
          cpu       = 512
          essential = true
          portMappings = [
            {
              containerPort = local.services.superset_app.port
              hostPort      = local.services.superset_app.port
              protocol      = "tcp"
            }
          ],
          secrets = [
            {
              name = "<environment_variable_name>"
              valueFrom = "arn:aws:ssm:<region>:<aws_account_id>:parameter/<parameter_name>"
            }
          ]
          logConfiguration = {
            logDriver = "awsfirelens",
            options = {
              Name               = "es"
              Cloud_ID           = var.elastic_cloud_id
              Index              = "filebeat-8.6.1"
              tls                = "On"
              "tls.verify"       = "Off"
              Tag_Key            = "tags"
              Include_Tag_Key    = "true"
              Retry_Limit        = "10"
              Suppress_Type_Name = "On"
              Trace_Output       = "On" # DEBUG
              Trace_Error        = "On" # DEBUG
              Replace_Dots       = "On"
            }
            secretOptions = []
          },
          mountPoints = [],
          volumesFrom = [],
          dependsOn   = []
        },
      tags = {
        environment = local.environment
      }
    }
    

    You would of course have to do this for all the environment variables you need.

    Bear in mind that the task role needs to have properly defined permissions for this to work.