Search code examples
amazon-web-servicesaws-lambdaenvironment-variablesamazon-ecsaws-fargate

Environment variable setting for Fargate task


I have the following code fragment in my Javascript AWS Lambda function:

const taskParams = {
    "taskDefinition": workerTaskDefinitionName,
    "launchType": "FARGATE",
    "count": "1",
    "overrides": { 
        "containerOverrides": [ 
           {
              "name": containerName, 
              "environment": [ 
                { 
                    "name": "INPUT_VIDEO_FILE_URL",
                    "value": srcKey
                },
                { 
                    "name": "POSITION_TIME_DURATION",
                    "value": positionTimeDuration
                },
                { 
                    "name":"OUTPUT_THUMBS_FILE_NAME",
                    "value": dstKey
                },
                { 
                    "name":"OUTPUT_S3_PATH",
                    "value": destinationBucket
                }
              ]
           }
        ]
     }
};

try {

    console.log('Starting task...');
    console.log(`  srcBucket=${srcBucket}`);
    console.log(`  srcKey=${srcKey}`);
    console.log(`  positionTimeDuration=${positionTimeDuration}`);
    console.log(`  dstKey=${dstKey}`);
    console.log(`  destinationBucket=${destinationBucket}`);

    ecs.runTask(taskParams, function(err, data) {
        if (err) {
            console.log(err, err.stack); // an error occurred
        } 
        else  {
            console.log(data);           // successful response
            console.log('Successfully ran the task.');
        }
    });
      
} catch(error) {
    console.log('Error running the task.');
    console.log(error);
}

Essentially, the lambda is setting the environment for the Fargate containerized task and calling the task.

I have a placeholder bash script as the containerized task:

#!/bin/bash

### Environment variables ###
# INPUT_VIDEO_FILE_URL
# POSITION_TIME_DURATION
# OUTPUT_THUMBS_FILE_NAME
# OUTPUT_S3_PATH
echo "INPUT_VIDEO_FILE_URL = ${INPUT_VIDEO_FILE_URL}"
echo "POSITION_TIME_DURATION = ${POSITION_TIME_DURATION}"
echo "OUTPUT_THUMBS_FILE_NAME = ${OUTPUT_THUMBS_FILE_NAME}"
echo "OUTPUT_S3_PATH = ${OUTPUT_S3_PATH}"
#############################

echo "Copying ${OUTPUT_THUMBS_FILE_NAME} to S3 at ${OUTPUT_S3_PATH}/${OUTPUT_THUMBS_FILE_NAME} ..."

echo "Done (dummy bash script)."

When I check the Cloudwatch logs after the Lambda function is triggered, I see the logs for the lambda function logging the expected values correctly. But, the containerized worker task logs are not showing the values passed as environment variable overrides.

Here's the lambda log:

START RequestId: ab6e3b4e-f026-4d43-b137-b72dc76e83ad Version: $LATEST
2021-02-18T13:29:19.394Z    ab6e3b4e-f026-4d43-b137-b72dc76e83ad    INFO    Starting task...
2021-02-18T13:29:19.433Z    ab6e3b4e-f026-4d43-b137-b72dc76e83ad    INFO      srcBucket=vxx..x
2021-02-18T13:29:19.433Z    ab6e3b4e-f026-4d43-b137-b72dc76e83ad    INFO      srcKey=small.mp4
2021-02-18T13:29:19.433Z    ab6e3b4e-f026-4d43-b137-b72dc76e83ad    INFO      positionTimeDuration=00:03
2021-02-18T13:29:19.433Z    ab6e3b4e-f026-4d43-b137-b72dc76e83ad    INFO      dstKey=transcoded-small.mp4
2021-02-18T13:29:19.434Z    ab6e3b4e-f026-4d43-b137-b72dc76e83ad    INFO      destinationBucket=arn:aws:s3:::vyyy..y
END RequestId: ab6e3b4e-f026-4d43-b137-b72dc76e83ad
REPORT RequestId: ab6e3b4e-f026-4d43-b137-b72dc76e83ad  Duration: 721.20 ms Billed Duration: 722 ms Memory Size: 128 MB Max Memory Used: 90 MB  Init Duration: 447.57 ms    

Here's the container task log:

INPUT_VIDEO_FILE_URL = 
POSITION_TIME_DURATION = 
OUTPUT_THUMBS_FILE_NAME = 
OUTPUT_S3_PATH = 
Copying  to S3 at / ...
Done (dummy bash script).

What am I doing incorrectly?


Solution

  • Looking at the example in the AWS JavaScript SDK, I believe you need to add a name property to the containerOverrides definition, that matches the container name:

    "overrides": { 
                "containerOverrides": [ 
                   { 
                      "name": "<this-name-should-match-the-container-name>",
                      "environment": [ 
                        { 
                            "name": "INPUT_VIDEO_FILE_URL",
                            "value": srcKey
                        },
                        { 
                            "name": "POSITION_TIME_DURATION",
                            "value": positionTimeDuration
                        },
                        { 
                            "name":"OUTPUT_THUMBS_FILE_NAME",
                            "value": dstKey
                        },
                        { 
                            "name":"OUTPUT_S3_PATH",
                            "value": destinationBucket
                        }
                      ]
                   }
                ]
             }
    

    From the documentation:

    name — (String) The name of the container that receives the override. This parameter is required if any override is specified.