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

Last updated: 2021-01-06

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

Short description

Passing sensitive data in plaintext can cause security issues, as it's discoverable in the AWS Management Console or through AWS APIs such as DescribeTaskDefinition or DescribeTasks.

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

AWS supports data injection only for the following:

Resolution

Complete prerequisites

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

For AWS Systems Manager Parameter Store, run the following command:

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

For Secrets Manager, run the following command:

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

Note: The Amazon ECS container agent uses a task execution AWS Identity and Access Management (IAM) role to fetch the information from the AWS Systems Manager Parameter Store or Secrets Manager. The task execution IAM role must grant permissions to the following actions: ssm:GetParameters, secretsmanager:GetSecretValue, and kms:Decrypt.

2.    Open the IAM console, and then create a role with a trust relation for ecs-tasks.amazonaws.com. For example:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

3.    To create an inline policy for your role in the IAM console, choose Roles, select the role that you created in step 2, and then choose Add inline policy on the Permissions tab. Choose the JSON tab, and then create a policy with the following code:

{
  "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 your parameters are stored. Replace awsExampleParameter with the name of the parameters that you created in step 1.

Note: If you use a customer managed KMS key for encrypting data in AWS Systems Manager Parameter Store or Secrets Manager, then you must get permissions for kms:Decrypt.

4.    (Optional) Attach the managed policy AmazonECSTaskExecutionRolePolicy to the role that you created in step 2.

Important: A managed policy is required for tasks that use images stored in Amazon Elastic Container Registry (Amazon ECR) or send logs to Amazon CloudWatch.

Reference sensitive information in the ECS task definition

From the AWS Management Console:

1.    Open the Amazon ECS console.

2.    From the navigation pane, choose Task Definitions, and then choose Create new Task Definition.

3.    Choose your launch type, and then choose Next step.

4.    For Task execution role, choose the task execution IAM role that you created earlier.

5.    In the Container Definitions section, choose Add container.

6.    In the Environment variables section under ENVIRONMENT, for Key, enter a key for your environment variable.

7.    On the Value dropdown list, choose ValueFrom.

8.    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.

From the AWS Command Line Interface (AWS CLI):

Note: If you receive errors when running AWS CLI commands, be sure that you’re using the most recent version of the AWS CLI.

1.    Reference AWS Systems Manager Parameter Store or Secrets Manager resources in the task definition as environment variables using the secrets section or as log configuration options using the secretOptions section. For example:

{
  "requiresCompatibilities": [
    "EC2"
  ],
  "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"
}

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

2.    To register the task definition, run the following command:

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

When a task is launched using the task definition that you create, the Amazon ECS container agent automatically resolves the secrets and injects the values as environment variables to the container.

Important: Sensitive data is injected into your container when the container is initially started. If the secret or Parameter Store parameter is updated or rotated, the container doesn't receive the updated value automatically. You must launch a new task. If your task is part of a service, update the service and use the Force new deployment option to force the service to launch a fresh task.

To force a new deployment:

1.    Open the Amazon ECS console.

2.    Choose Clusters, and then select the cluster with your service.

3.    Select the Force New Deployment check box, and then choose Update Service.

Note: To force a new deployment from the AWS CLI, run the update-service command with the --force-new-deployment flag.


Did this article help?


Do you need billing or technical support?