Secret Management for AWS EC2

This guide will show you how to provision an application running on EC2 with the secrets it needs. While the principles described in the guide for Linux VMs can also be applied here, we’ll cover a better way here to do the same thing on AWS EC2.

To do that, we’ll use the AWS identity provider, which allows you to abstract the SecretHub service credentials away from your app configuration, making your apps ‘keyless’.

Overview of using SecretHub on AWS EC2

Before you begin

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

  1. Install the SecretHub CLI for your OS.
  2. Sign up for a SecretHub account.
  3. Install and configure the AWS CLI.
  4. Setup a method for connecting to EC2 Instances.

Step 1: Check out the demo application

To see the mechanism in action, the SecretHub CLI comes packed with a demo application. This application serves a web page and tries to connect to using credentials provided in the environment (DEMO_USERNAME and DEMO_PASSWORD).

First, try to run the app locally without setting the username and password:

secrethub demo serve

A web page will now be served at http://localhost:8080, but if you visit it, you’ll see that it shows an error because it’s missing the username and password.

Step 2: Provide secrets to the application

To get the demo application to work correctly, you’ll need to provide a username and password. You wouldn’t want to have those scattered around in plaintext, so let’s store those on SecretHub instead and use secrethub run to inject them at runtime.

Here’s a nice shortcut to auto-generate the values for you at your-username/demo:

secrethub demo init

Next, create a secrethub.env file, and instead of hardcoding secret values, reference them by path:

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

Then, wrap the app start command in secrethub run:

secrethub run -- secrethub demo serve

The secrets will now automatically get fetched, decrypted and injected as environment variables to the app.

If you visit http://localhost:8080 again, you’ll see that the red cross got replaced by a green checkmark. The wisdom that was hidden in the Demo API has now been revealed!

Step 3: Create an IAM role for EC2

Now that you have the application running locally, it’s time to get it deployed to EC2. The first thing you’ll 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 then EC2 as trusted entity. Continue by clicking Next: Permissions.

First step in creating IAM Role

  1. Select any Policies your EC2 Instance 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. SecretHubDemoEC2Role) and description and click Create role.

Step 4: Create a KMS key

The second component to set up is a KMS key. Note that they are region bound, so make sure you create it in the region you’re EC2 instance is in.

  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: Launch EC2 Instance

Now that everything is set up, it’s time to launch an EC2 instance:

  1. Go the the EC2 Launch Wizard. (Unfortunately there resides little magic in this wizard.)
  2. Select an Machine Image. We’re goimg with Amazon Linux 2 AMI x86.
  3. Choose an Instance Type and click Next: Configure Instance Details. We’re going with t2.micro.
  4. Select the previously created role at the IAM role field. You can leave all other settings at their default.
  5. Click Next: Add Storage.
  6. Click Next: Add Tags.
  7. Click Next: Configure Security Group.
  8. Click Add Rule and set the Type of the newly created rule to HTTP. You should now have 2 rules listed:

Security Group rules for EC2 Instance

  1. Click Launch.
  2. Select a previously created key pair or create and download a new key pair. Then click Launch Instances.

Your EC2 Instance should come online shortly.

Step 7: Run application on EC2

When the EC2 Instance is fully up and running, connect to it, and install the SecretHub CLI. The easiest way to do this on the Linux AMI provided by Amazon is to use yum:

sudo yum install -y

Create or move the secrethub.env file we used earlier and wrap the demo app start command in secrethub run, setting the --port flag to an open port on the machine:

secrethub run --identity-provider=aws -- secrethub demo serve --host --port 1234

And that’s it! There’s no SecretHub key that needs to be deployed to the EC2 instance, just set the --identity-provider flag to aws.

See if it works by visiting http://<EC2-INSTANCE-IP>:8080.

See also