AWS ECS logo

Secret Management for AWS ECS

Running tasks in the isolated environment of a container can make your life a lot easier. However, letting your containerized application get access to secrets is not straightforward. Especially when running these containers in AWS Elastic Container Service.

Using the SecretHub AWS Identity Provider can help you out. This guide will show you how to use the AWS Identity Provider to access secrets in an ECS Task using SecretHub.

Overview of using SecretHub in an ECS Task

Before you begin

Before you start with using SecretHub for EC2, make sure you have completed the following steps:

  1. Install the SecretHub CLI for your OS.
  2. Signup for a SecretHub account.
  3. Install the the AWS CLI.
  4. Configure the AWS CLI to connect to your AWS account.
  5. Install Docker CE for your platform.

Step 1: Setup the demo application

To make life easy, the SecretHub CLI comes packed with a demo application. This application serves a web page and tries to connect to https://demo.secrethub.io/api/v1/basic-auth using the credentials provided in the environment (DEMO_USERNAME and DEMO_PASSWORD).

For this guide we will run the application in a Docker container, so we can later deploy it to ECS. You can use the following Dockerfile:

FROM alpine

RUN apk add --repository https://alpine.secrethub.io/alpine/edge/main --allow-untrusted secrethub-cli

EXPOSE 80
CMD ["secrethub", "demo", "serve", "--host", "0.0.0.0", "--port", "80"]

After creating this file, you can build an image with:

docker build --tag secrethub-demo .

You can then run the image with:

docker run -p 8080:80 secrethub-demo

A web page will now be served at http://127.0.0.1:8080.

If you check it out, you will see that it does not work correctly because it is missing the username and password.


Step 2: Providing secrets to the application

To get the demo application to work correctly, we have to provide the username and password. You wouldn’t want to have those scattered around in plaintext, so let’s store those on SecretHub instead. Here’s a nice shortcut to auto-generate the values for you at your-username/demo:

secrethub demo init

Because the app gets the secrets it needs from the environment, we can leverage the power of secrethub run to inject secrets. All we need for this is a file named secrethub.env containing the definition of all environment variables:

DEMO_USERNAME = {{ your-username/demo/username }}
DEMO_PASSWORD = {{ your-username/demo/password }}

Make sure you include this file into the image by adding the following line after the RUN statement in the Dockerfile:

ADD secrethub.env .

You can then change the entrypoint of the image by adding the following line just before the CMD statement:

ENTRYPOINT ["secrethub", "run", "--"]

When you run this new image, the secrethub run entrypoint fetches all secrets in the secrethub.env file. For this it needs a credential, which you can provide by mounting you local user’s credential (don’t forget to rebuild the image first):

docker run -p 8080:80 -v $HOME/.secrethub:/root/.secrethub secrethub-demo

If you check http://127.0.0.1:8080 again, the red cross should be replaced by a green check mark.


Step 3: Create an IAM Role for ECS

Now that we have the application running locally, it is time to get it deployed to ECS. The first thing we need for the AWS Integration to work, is an IAM role.

  1. Go to the Create role page on the AWS Console.
  2. Select AWS Service and Elastic Container Service as trusted entity.
  3. Select Elastic Container Service Task as use case and continue by clicking Next: Permissions.

First step in creating IAM Role

  1. Select any Policies your ECS Task needs and then click Next: Tags. For using SecretHub no specific policy is needed.
  2. Add any tags you like and click Next: Review.
  3. Set a descriptive Role name (e.g. SecretHubDemoECSTaskRole) and description and click Create role.

Step 4: Create a KMS key

Next, we have to setup a KMS Key to use for encryption and decryption.

  1. Go to the Create Customer Managed Key page on the AWS Console.
  2. Enter an alias (e.g. SecretHub-Demo-Service-Key) and optionally a description for the key and click Next.
  3. Add any tags you like and click Next.
  4. Select any users or roles you would like as Key administrators and click Next. Make sure your own IAM user or a role you have access is selected or that you select it on the next page as a Key user.
  5. Select the role you previously created as a Key user and set any other preferred key users and then click Next. A role or user you have access to should either be a Key user or a Key Administrator.

Select the correct Key user for the KMS key

  1. Create the KMS key by clicking Finish.
  2. Take note of the id of the newly created key (e.g. 1234abcd-12ab-34cd-56ef-1234567890ab), you’ll need it in the next step.

Step 5: Setup SecretHub Service Account

With the IAM role and KMS key in place, we can go ahead and create a SecretHub service account for the app.

Run the following command and you’ll be prompted for the name of the role, the id or ARN of the KMS key and the region the KMS key is in:

secrethub service aws init your-username/demo --permission read

Setting --permission read automatically creates an access rule to give the newly created service account read access on the demo repo.

As you can see, the secrethub service aws init command – in contrary to the regular secrethub service init command – does not output a credential. That’s because applications do not need it anymore: as long they take on the specified role, they can automatically get their secrets from SecretHub.


Step 6: Create ECS Cluster

Before you can run a task on ECS, you have to create an ECS cluster:

  1. Go to the Create Cluster wizard.
  2. Select Netorking only and click Next step.
  3. Enter a name for the cluster (e.g. SecretHubDemoCluster) and click Create.

Step 7: Create Task Definition

The next step is to create a task definition that describes what task you’re going to run:

  1. Go the Create new Task Definition wizard.
  2. Select FARGATE and click Next step.
  3. Enter a Task Definition Name (e.g. SecretHubDemoTask).
  4. Select the previously created IAM role as Task Role.
  5. Set Task memory to 0.5GB and Task CPU to 0.25 vCPU.
  6. Click Add container.
  7. Enter app as Container name.
  8. Enter the location of the example app image in the Image field. You can choose to build and host your own image, but you can also use the one we’ve built: secrethub/demo-app.
  9. Scroll down to ENVIRONMENT section and add an Environment variable with the key SECRETHUB_IDENTITY_PROVIDER and aws as value.
  10. The secrethub/demo-app image uses a template variable in the secrethub.env file for the username. If you use the image, add an Environment variable with the key SECRETHUB_VAR_USERNAME and your username as value, so that it looks for the secrets in your workspace.

Environment variables for ECS Task Definition

  1. Click Add.
  2. Click Create.

Step 8: Launch Task

The only thing left to do is launch the task in the ECS Cluster:

  1. Go to the ECS Cluster Overview and select the cluster you just created.
  2. Select the Tasks tab and click Run new Task.
  3. Set Launch type to FARGATE.
  4. Select the Task Definition you just created.
  5. Select the desired Cluster VPC and Subnets (default will suffice for testing purposes).
  6. Under Security Groups make sure that there is a rule that allows TCP traffic from your IP (or anywhere) on port 80 and click Save.
  7. Set Auto-assign public IP to ENABLED.
  8. Click Run Task.
  9. Click on the Task id in the list of tasks.
  10. When the Status of the container is RUNNING, you can visit http://<PUBLIC-IP>/ to verify everything is working correctly. The public IP can be found in the Network section of the Task.

See also