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

Last updated: 2019-07-26

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

Short Description

Passing sensitive information in plaintext can cause security issues. This information is discoverable in the AWS Management Console or through AWS APIs such as DescribeTaskDefinition or DescribeTasks.

To provide security, 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 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 IAM role to fetch the information from the AWS Systems Manager Parameter Store or Secrets Manager. The task execution AWS Identity and Access Management (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. See the following 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.

Note: The managed policy is required if the task uses an image stored in Amazon Elastic Container Registry (Amazon ECR) or sends 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 drop-down menu, choose ValueFrom.

8.    In the text box for the key, enter the 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):

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. See the following 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 register-task-definition 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 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, 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 you?

Anything we could improve?


Need more help?