Skip to content

How can I securely pass secrets or sensitive information to containers in an Amazon ECS task?

6 minute read
1

I want to securely pass secrets or sensitive information to containers in a task for Amazon Elastic Container Service (Amazon ECS).

Short description

If you pass sensitive data in plaintext, then you can cause security issues. The data might be discoverable in the AWS Management Console or through the DescribeTaskDefinition AWS API.

As a security best practice, pass sensitive information to containers as environment variables. To securely inject data into containers, reference the values stored in Parameter Store, a capability of AWS Systems Manager. You can also use AWS Secrets Manager in an Amazon ECS task definition. Then, you can expose your sensitive information as environment variables or in the log configuration of a container.

Resolution

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshoot AWS CLI errors. Also, make sure that you're using the most recent AWS CLI version.

Prerequisites:

  • Your tasks must use AWS Fargate platform version 1.3.0 or later with the AWS Fargate launch type.
  • Your container instances must use amazon-ecs-agent version 1.22.0 or later with the Amazon Elastic Compute Cloud (Amazon EC2) launch type. For more information, see Changelog on the GitHub website.
  • Your Fargate platform must have version 1.4.0 or later for Linux or 1.0.0 for Windows to inject a JSON key.
  • To use specific JSON keys or secret versions, your container instance's ECS container agent must run version 1.37.0 or later for secret injection.
  • Your container instance's ECS container agent must run version 1.22.0 or later to inject full contents of secrets into log configurations or environment variables.

Create the IAM role and policies

Complete the following steps:

  1. Store your sensitive information in either Parameter Store or Secrets Manager.

    For Parameter Store, run the following put-parameter AWS CLI command:

    aws ssm put-parameter --type SecureString --name awsExampleParameter --value awsExampleValue

    Note: Replace awsExampleParameter with your own parameters. Replace awsExampleValue with your secret value.

    For Secrets Manager, run the following create-secret AWS CLI command:

    aws secretsmanager create-secret --name awsExampleParameter --secret-string awsExampleValue

    Note: Replace awsExampleParameter with your own parameters. Replace awsExampleValue with your secret value. The ECS container agent uses a task execution role to fetch the information from the Parameter Store or Secrets Manager. The task execution role must grant permissions to ssm:GetParameters, secretsmanager:GetSecretValue, and kms:Decrypt actions.

  2. Open the AWS Identity and Access Management (IAM) console.

  3. Create a role with a trust relation for ecs-tasks.amazonaws.com.
    Example trust policy of role:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "",
          "Effect": "Allow",
          "Principal": {
            "Service": "ecs-tasks.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
  4. Choose Roles, and then select the role that you created.

  5. Under the Permissions tab, choose the Add permissions dropdown list.

  6. Choose Create inline policy, and then choose the JSON tab.

  7. Attach the following policy:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "ssm:GetParameters",
            "secretsmanager:GetSecretValue"
          ],
          "Resource": [
            "arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter",
            "arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter*"
          ]
        }
      ]
    }

    Note: Replace us-east-1 and awsExampleAccountID with the AWS Region and account where you stored your parameters. Replace awsExampleParameter with the name of the parameters that you created. You can use an AWS Key Management Service (AWS KMS) customer managed key to encrypt data in Parameter Store or Secrets Manager. To use the customer managed key, get permissions for kms:Decrypt.

  8. (Optional) Attach the managed policy AmazonECSTaskExecutionRolePolicy to the role that you created.

Important: Tasks that send logs to Amazon CloudWatch or use images stored in Amazon Elastic Container Registry (Amazon ECR) must have a managed policy.

Reference sensitive information in the ECS task definition

Use the Amazon ECS console or AWS CLI to reference sensitive information in the ECS task definition.

Use the Amazon ECS console

Complete the following steps:

  1. Open the Amazon ECS console.
  2. In the navigation pane, choose Task Definitions, and then choose Create new task definition.
    For Task definition family, enter a name.
    For Launch type, choose AWS Fargate or Amazon EC2 instances for the launch type.
  3. For Task execution role, choose the task execution IAM role that you created.
  4. On the Container Definitions section, under the Environment variables section, choose Add environment variable.
  5. For Key, enter a key for your environment variable.
  6. On the ValueType dropdown list, choose ValueFrom.
  7. In the text box for the key, enter the Amazon Resource Name (ARN) of your Parameter Store or Secrets Manager resource.
    Note: You can also specify secrets in the log driver configuration.

Use the AWS CLI

Use the secrets section to reference Parameter Store or Secrets Manager resources in the task definition as environment variables. Or, use the secretOptions section to reference Parameter Store or Secrets Manager as log configuration options.

Example of task definition:

{
  "requiresCompatibilities": [
    "EC2"
  ],
  "family": "Web",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "httpd",
      "memory": 128,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "splunk",
        "options": {
          "splunk-url": "https://sample.splunk.com:8080"
        },
        "secretOptions": [
          {
            "name": "splunk-token",
            "valueFrom": "arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter"
          }
        ]
      },
      "secrets": [
        {
          "name": "DATABASE_PASSWORD",
          "valueFrom": "arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter"
        }
      ]
    }
  ],
  "executionRoleArn": "arn:aws:iam::awsExampleAccountID:role/awsExampleRoleName"
}

Note: Replace us-east-1 and awsExampleAccountID with your Region and account ID. Replace awsExampleParameter with the parameter that you created. Replace awsExampleRoleName with the role that you created.

Then, run the following register-task-definition AWS CLI command to register the task definition:

aws ecs register-task-definition --family-name yourTaskDefinitionFamily --cli-input-json file://pathToYourJsonFile

Note: Replace yourTaskDefinitionFamily with your task definition family name.

When you launch a task with this definition, the ECS container agent automatically resolves the secrets. Then, the container agent injects the values as environment variables to the container.

Update secrets and deploy changes

When you start the ECS container, the container injects sensitive data into it. If you update or rotate the secret or Parameter Store parameter, then the container doesn't automatically receive the updated value. You must launch a new task. If your task is part of a service, then update the service. To force the service to launch a fresh task, use the Force new deployment option.

To force a new deployment, complete the following steps:

  1. Open the Amazon ECS console.
  2. Choose Clusters, and then select the cluster with your service.
  3. Select Force New Deployment from the Update dropdown list.
    Note: To force a new deployment from the AWS CLI, run the update-service command with the --force-new-deployment flag.

Related information

Updating the Amazon ECS container agent