AWS EKS logo

Secret Management for AWS EKS

This guide will show you how to provision an application running on EKS with the secrets it needs. To make life easy, you can use the demo app from the Getting Started guide or deploy your own custom app and follow along.

You will be able to grant your app access to the required secrets just by having your pods assume an IAM role, using the AWS Identity Provider.

Before you begin

Before you start using SecretHub with EKS, make sure you have:

  1. Followed the Getting Started guide.
  2. Configured your AWS credentials.
  3. Installed eksctl, the official CLI for EKS.
  4. Installed kubectl.

Step 1: Create Cluster

First, create a Kubernetes cluster with EKS, by running the following command:

eksctl create cluster --name my-cluster

Step 2: Enable IAM Roles for service accounts

Next, to allow your pods to assume IAM roles and have secrets provisioned to them, enable IAM Roles for Kubernetes Service Accounts by running:

eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve

Step 3: Create a policy for the pods

To restrict the access of the Kubernetes pods to external services, go to the Create Policy page on the AWS Console and create a policy. To follow along, you can use MyPolicy:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "sts:GetCallerIdentity"
        ],
        "Resource": "*"
    }
}

Step 4: Create IAM Role:

The Kubernetes pods can access your secrets straight out of the box just by assuming an IAM role, without the need for a secret key. To allow the pods to assume roles, run the following command with the ARN of the policy created in the previous step:

eksctl create iamserviceaccount \
                --name my-service-account \
                --cluster my-cluster \
                --attach-policy-arn <my-policy-arn> \
                --approve

This command will create a new Kubernetes service account named my-service-account and attach to it a new IAM Role. To get the name of this IAM Role run:

kubectl get sa my-service-account -o yaml

The role’s ARN is the the value of the eks.amazonaws.com/role-arn key. Take note of it, as you will need it in the next step.


Step 5: Create a KMS key

Next, to allow your secrets to be encrypted and decrypted, set up a KMS key.

  1. Go to the Create Customer Managed Key page on the AWS Console.
  2. Enter an alias (e.g. MyServiceKey) 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 created in the previous step as a Key User, 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.
  6. Create the KMS key by clicking Finish.
  7. 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 6: Setup SecretHub Service Account

Next, to give the previously created IAM Role access to secrets, create a SecretHub service account.

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.

You may have noticed that unlike the usual secrethub service init command, secrethub service aws init does not output a credential.

That’s because applications on AWS do not need it anymore: as long they take on the specified role, they can automatically get their secrets from SecretHub.


Step 7: Create Kubernetes Deployment

Next, to configure your deployment you can write a deployment.yml file similar to this one:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: app
  name: demo-app
spec:
  replicas: 2
  selector:
    matchLabels:
      run: app
  template:
    metadata:
      labels:
        run: app
    spec:
      serviceAccountName: my-service-account
      containers:
      - image: secrethub/demo-app
        name: demo-app
        env:
        - name: DEMO_USERNAME
          value: "secrethub://your-username/demo/username"
        - name: DEMO_PASSWORD
          value: "secrethub://your-username/demo/password"
        - name: SECRETHUB_IDENTITY_PROVIDER
          value: "aws"
        ports:
        - containerPort: 8080

The line serviceAccountName: my-service-account configures the pods to use the previously created Kubernetes service account, which has access to the required secrets.

This image runs the demo app, with the secrethub run command and exposes it on port 8080. You can follow our Docker guide to use a custom docker image for your app.

In the env section the environment variables DEMO_USERNAME and DEMO_PASSWORD (used by the demo app) are configured to reference the previously created secrets.

Finally, all you need to do is tell the app it’s running on AWS by setting the SECRETHUB_IDENTITY_PROVIDER environment variable to aws. This will ensure the IAM Role of the pod is used for authenticating to SecretHub.


Step 8: Deploy app

Finally, to deploy the SecretHub demo app, run:

kubectl apply -f deployment.yml

Step 9: Verify that it works

Now let’s see the app running!

Run the following command to forward data from your local 8080 port to one of the pods in the deployment:

kubectl port-forward deployment/demo-app 8080

Then visit: http://127.0.0.1:8080 and you should see the app running:

Screenshot of the demo app running
Demo app running

See also