Retrieve secrets with Vault AWS Lambda extension
Challenge
AWS Lambda is a powerful tool available from Amazon Web Services. It offers Serverless functions that cost nothing when not used, and then fractions of a penny when invoked.
A common requirement for a Lambda function is to retrieve information from a secure location, and use it to access a database, file store or other secure location.
If you are using Vault for secrets management, Lambda requires access to Vault for authentication and to retrieve secrets.
Solution
Including the Vault Lambda Extension in the execution environment enables functions to retrieve secrets from Vault.
With the Vault Lambda Extension with your Lambda runtime, and setting the proper environment variables, the function will be able to retrieve secrets from Vault before the function executes. The function now has the credentials needed to implement your business logic.
Background
Lambda creates instances of serverless functions as needed, which the structure includes a few things like a runtime, environment variables and the executable/interpreter. Lambda has standard runtimes for many languages available, but if that runtime does not include a particular library or dependency it can be added a few ways. One of particular interest is the Lambda layer, which is an addition of a library, module or dependency to the standard Lambda runtime for your language. When a Lambda function is invoked, these are all loaded into the runtime process and then executed.
Extensions are additions to the runtime process and can added as a Lambda layer to your runtime environment. If the proper environment variables are set, the Vault AWS Lambda Extension will run authenticate and securely retrieve secrets before your Lambda function invokes.
Scenario introduction
First, using a Terraform config you will create the function with supporting IAM Roles and Policies, and review the infrastructure that is created.
You will then set up HCP Vault Dedicated to allow access from your AWS Account to Vault Dedicated via an IAM Role. After the initial Vault Dedicated setup, you will create a Vault Role and
Policy that allow the execution role the Lambda function uses to access one KV Secret (kv/data/test/lambda
) in your instance
of Vault Dedicated.
Next, you will create a secret in Vault, and then set up AWS Authentication to enable the function you created earlier to connect to your Vault Dedicated instance.
Finally, you will observe it all working together.
Prerequisites
This tutorial requires an AWS account, Terraform, Vault CLI and the example Terraform configuration to create a demonstration environment.
- AWS account - you need to be familiar with the AWS Console UI and where to find the Lambda. For this tutorial, you should create an AWS IAM User that has sufficient permissions to create resources in your account, and generate an Access Key and Secret Access Key for this lab. Please refer to IAM Users for more details.
- Terraform CLI
- AWS CLI
- Git
- HCP account with a service principal with contributor role already created.
- Some experience with the HCP interface, particularly getting the values for
VAULT_TOKEN
andVAULT_ADDR
.
- Some experience with the HCP interface, particularly getting the values for
Clone example repository
Clone the Terraform configuration and Lambda function code from the following repository:
Change into the repository directory.
The repository contains Terraform configuration to create the following resources:
- Vault Dedicated cluster
- Lambda Function
- IAM Lambda execution role
Set up for the Terraform configuration
- Log into the HCP Portal.
In HCP, under Access control (IAM) choose Service Principals.
From the Service Principals page, choose the link that your service principle's name uses and go into the details page.
in the Create service principal key page, choose + Generate key.
Copy the Client ID then, in a terminal, set the
HCP_CLIENT_ID
environment variable to the copied value.Switch back to the HCP Portal and copy the Client Secret then, in a terminal, set the
HCP_CLIENT_SECRET
environment variable to the copied value.Terraform is now able to authenticate with HCP.
Set
AWS_ACCESS_KEY_ID
to store your AWS Access Key.Set
AWS_SECRET_ACCESS_KEY
to store your AWS Secret Access Key.Now set the target AWS region.
Create the infrastructure
Run
terraform init
to initialize the Terraform configuration.Package the Lambda function through the build script.
Apply the changes.
The terminal output displays the plan that it found and the resources it creates.
Enter
yes
to confirm and resume.Note
Keep in mind that answering yes at this time creates actual resources with associated costs.
Verify that when the
terraform apply
command completes, smd you see the following.
Tour your creation
Take a quick tour to learn what was provisioned by Terraform in the AWS and HCP UI.
Launch your AWS Account Console and open the Lambda console. Select the
vault-lambda-extension-demo-function
function.Scroll down to the Code Source tab, and examine the Python code.
This code is straightforward, getting the location of the secret that is returned from Vault from an environment variable, reading it into a Python map and then printing it to standard output. Understanding the environment variables are critical to understanding the Vault lambda extension.
Click on the Configuration tab and click on the environment variables section on the left.
The environment variables should be similar to as follows.
Variable Name Value VAULT_ADDR https://XXX-XXXX-XXXX-NNNNNNNN.NNNNNNNN.NN.hashicorp.cloud:8200 VAULT_AUTH_PROVIDER aws VAULT_AUTH_ROLE vault-role-for-aws-lambdarole VAULT_NAMESPACE admin VAULT_SECRET_FILE_DB /tmp/vault_secret.json VAULT_SECRET_PATH_DB kv/data/test/ec2 The Vault Lambda Extension is configured via these environment variables. So
VAULT_AUTH_PROVIDER
indicates it should use AWS Authentication,VAULT_NAMESPACE
indicates the namespace that will be used, and so forth. Please see the previous link for details.In order to use the Vault CLI locally, you need to go to the HCP UI, find your cluster to get the Vault token, and address.
Choose your Vault instance and click on Access Vault, and choose Command-line (CLI).
From there some variables need to set in your terminal.
You still need to get the token. Go back to the main screen for your Vault cluster and find for the New admin token and choose Generate token. Generating it places it in your paste buffer. Copy the below and then set the admin token with:
Note
This token expires in 6 hours.
For more details. please refer to the configure development hosts, paying attention to the HCP sections for details on setting environment variables.
Create a secret in Vault
Create a standard KV secret through CLI.
Check Vault status to make sure the CLI is properly set up.
Enable KV Secrets Engine v2.
Create a secret named
api-key
.
Enable AWS auth method in Vault
In order for the Lambda function to be able to contact the Vault Dedicated instance you need AWS authentication set up.
List the authentication is already enabled.
Now create a policy called
vault-policy-for-aws-lambda-role
, which allows read access the secret created above.List the available policies.
For your lambda function to be able to connect to your instance of Vault Dedicated, go ahead and enable AWS Authentication.
List the available auth methods.
Configure AWS Authentication with the
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
already set up.Create an AWS auth method role in Vault that gives access to the IAM role
vault-lambda-extension-demo-lambda-role
and attach the policyvault-policy-for-aws-lambda-role
to it.Note
Update the
<YOUR_ACCOUNT_ID>
with your AWS Account ID in the following command before running it.List the roles.
Examine the details of
vault-role-for-aws-lambdarole
.
Test the function
Go back to the AWS Console, find
vault-lambda-extension-demo-function
and choose the Test tab and press Test button.Examine the output. In addition to a summary of execution, find for text similar to the below.
From the line with
API Key: ABCDEFG9876
you know that the extension retrieved theAPI_KEY
value from Vault.
Clean up your infrastructure
Clean up your infrastructure provisioned by Terraform.
The terraform destroy deletes the HCP Cluster, Lambda function and all the support structures - IAM Role, Policy, etc.
Delete the terraform state.
In the AWS IAM Console, find the
AWS_SECRET_ACCESS_KEY
andAWS_ACCESS_KEY_ID
you created for this tutorial and make them inactive and delete them both.Unset all the environment variables used in this tutorial.
Check the environment variables were unset:
If the variables were successfully unset they will not appear in the result of this command. An execution and successful unset will provide no output.
Next steps
In this tutorial you built and deployed a Lambda function using the Vault AWS Lambda Extension using Terraform. If you are interested in more detail on using Terraform to manage Vault Dedicated refer to Manage Codified Vault on HCP Vault Dedicated with Terraform That simple function retrieved a simple KV secret from Vault, and printed it to the CloudWatch logs. The extension is configured by the Lambda environment variables, and automatically authenticates and retrieves a secret before the function is invoked.
You can learn more about the Vault AWS Lambda Extension by reading the blog post Use AWS Lambda Extensions to Securely Retrieve Secrets From HashiCorp Vault and by reviewing the Vault AWS Lambda Extension code repository. Of particular interest are the environment variables used to configure the extension.
Next, you enabled AWS Authentication for Vault Dedicated, and you can learn more through the Set up AWS Auth Method for HCP Vault Dedicated tutorial and the documentation AWS Authentication.
If you are interested in a lab with a more complex example, you can try the Lambda Vault Extension tutorial. That tutorial has a more detailed scenario using a secret to then access a MYSQL Database. In addition there is a section on caching the secret retrieved from Vault.