skip to Main Content

I have a containerized app that I want to run on ECS and it requires a configuration file, a JSON object. I defined my ECS instance like the one below in the CloudFormation template.

"ECRInstance": {
            "Type": "AWS::ECS::TaskDefinition",
            "Properties": {
                "NetworkMode": "awsvpc",
                "Cpu": 256,
                "Memory": 512,
                "ExecutionRoleArn": {
                    "Ref": "ECSTaskRole"
                },
                "requiresCompatibilities": ["FARGATE"],
                "ContainerDefinitions": [
                    {
                        "Name": "my_app",
                        "Image": "...",
                        "PortMappings": [
                            {"ContainerPort": 8080}
                        ],
                        "LogConfiguration": {
                            "LogDriver": "awslogs",
                            "Options": {
                                "awslogs-group": {
                                    "Ref": "CloudWatchLogsGroup"
                                },
                                "awslogs-region": {
                                    "Ref": "AWS::Region"
                                },
                                "awslogs-stream-prefix": "my_app"
                            }
                        }
                    }
                ]
            }
        }

Is there a way that I can pass my configuration file to the ECS instance through the CloudFormation template and possibly add a section to my code to receive that configuration object? Something like the below:

// readCfg() reads the configuration object given in the CloudFormation template.
const configuration = readCfg();

2

Answers


  1. You cannot pass a JSON directly via the CloudFormation template.

    However, you can leverage the command property in your Task Definition to create a JSON file that you can then read in your Node.js code.

    Something like:

    "command": ["/bin/sh -c "echo '{"cfgKey1":"cfgValue1"}' >  /tmp/config.json""]
    

    And then in your code:

    'use strict';
    
    const fs = require('fs');
    
    const rawdata = fs.readFileSync('/tmp/config.json');
    const config = JSON.parse(rawdata);
    
    Login or Signup to reply.
  2. If it’s not sensitive data, just pass it as a string in an environment variable. It’s exposed to NodeJS in process.env.MY_VAR_NAME, all other languages can read environment too.

    If it’s sensitive data (passwords, access tokens and such like), create a secret in SecretsManager and populate this secret outside your template (so that it’s not getting exposed in your template code).

    Then, inside your container’s code, read the secret:

    import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
    await new SecretsManagerClient().send(new GetSecretValueCommand({SecretId: "my_secret_id"}));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search