# AWS Lambda and Secrets Manager Tutorial in Python
## Introduction
In this article, I'm going to show you how to access secrets stored in the Amazon Secrets Manager service from an AWS Lambda function. Secrets Manager is a great way to store hard-coded API keys, database usernames, passwords, or any secret string values instead of hard-coding them into your source code. In order to access a secret from Secrets Manager in our Lambda function, we first need to create our secret, so that's going to be our first step.
To create a secret, search for the Secrets Manager service in the AWS console. The home screen should look like this:
![](https://i.imgur.com/XBaNYkH.png)
Before we begin, just a heads up, there is a 40-cent cost to store a secret. Click "Store a new secret" and select the secret type that you want to store. If you're using Amazon RDS, DocumentDB, or Redshift, I highly recommend selecting one of those options because you will also get automatic secret rotation which will be an extra layer of security on top of your storage. However, if you're storing a secret value in plain text, like an API key for GitHub, you'll want to use the "Other type of secret" option. In this demo, we will use the "Other type of secret.
![](https://i.imgur.com/tfIgcl3.png)
## Key-Value Pairs
Once you've chosen the "Other type of secret" option, you'll see some options asking you to set some key-value pairs. For the key-value pairs, you can store a JSON object with the key name and key password, or you can just put it in plain text. For this case, I'm going to put key-value pairs here and call them "secret" and "password."
![](https://i.imgur.com/GDJk31H.png)
We will use the AWS-provided KMS encryption key for the encryption key. This is an important detail, so I want to spend a moment talking about this.
## Create Your Own Kms Key
When you create an AWS account, you automatically have access to KMS Keys which will manage the key used to encrypt your data. By default, if you leave this as is, this is the AWS-managed KMS key. In addition, you can also create your own KMS key. To do this, hit "Add a new key" and select "AWS managed key" or "custom key." This is important because if you use just the normal AWS-provided KMS key, you only need a certain set of permissions to access your secret key and secret value. However, if you use your own custom-managed or custom created KMS key, you need some different permissions.
For this first part, we're just going to use the default for now, and we'll come back here to create the second version that has a custom key.
Hit "Next" now, and let's call the secret "aws-managed-secret." I'd recommend putting this on your clipboard so you don't forget it and then hit "Next."
![](https://i.imgur.com/q3EcJ5Y.png)
## Automatic Rotation of Your Secret Values:
![](https://i.imgur.com/yxZp6NP.png)
Really quick on this, there's this concept of automatic key rotation. Rotation of your secret values is a fully managed key rotation offered by AWS. This means that you can set it up so that periodically Secrets Manager will change the values of your stored credentials. If you want something that is going to stay fixed and not changed, you don't need to use rotation. However, some services like RDS, Redshift and DocumentDB offer automatic key rotation.
In order to use automatic key rotation, you need to provide a Lambda function ARN that will transform the key into the new value. However, it's a lot of headache, so I'm not going to do that in this article.
Let's continue - proceed through the screen till you're able to store the key. If you click on refresh now, you should see the secret there. If you see your secret there, then everything's working correctly here.
Now, let's go and create our secret using a KMS key that is custom-made. Repeat the process, but select a custom KMS key now. Now we should have two different secrets that are stored here. We are now ready to create our Lambda function now and add the code to actually access this stuff.
Open the Lambda service in the AWS console. Hit "Author from scratch," and let's call the function "SecretsManagerKeyRetriever" - you can name this whatever you want. For runtime, we're going to use Python 3.9, and architecture doesn't matter. For permissions, we're going to leave the default execution role here, so it's going to create a brand-new role for us, but we'll need to modify that in the next step. Hit "Create function" now.
![](https://i.imgur.com/2Cf1D1g.png)
We successfully created the Lambda function. To modify the code, scroll down to the code section in the Lambda function and drop in the code that's going to let us access our secret. Here is the code we're going to paste:
```python
import json
import boto3
import base64
# Your secret's name and region
secret_name = "custom-managed-secret"
region_name = "us-east-1"
#Set up our Session and Client
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name=region_name
)
def lambda_handler(event, context):
# Calling SecretsManager
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
#Raw Response
print(get_secret_value_response)
#Extracting the key/value from the secret
secret = get_secret_value_response['SecretString']
print(secret)
```
## Call the Secrets Manager
To walk you through the code:
`secret_name` is the hard-coded value for our secret that we have stored in the Secrets Manager service. `region_name` is the region you are in; you can see what region you are in from the AWS console. We're creating a `boto3` session as well as a client of the type `secretsmanager` and passing in the region name.
Our first step in the body of the Lambda function is to call the secrets manager. We're storing the response in `get_secret_value_response` and then we print it out. Finally, we get the actual secret from the response and print that out as well. If you invoke this right now, this is actually going to fail because we don't have the correct permission associated with this Lambda function yet. Let's deploy it anyway to test it.
When you click on "Test" in the Lambda function, you're going to get an `AccessDeniedException`. What's happening is that we are missing the permission to call Secrets Manager, so we need to go and add that.
To do that, go into the configuration section of our Lambda function and go to the Permissions tab.
![](https://i.imgur.com/8tlqOoo.png)
We need to modify our execution role to permit getting the secret value. Go to IAM and modify the IAM role corresponding to your secret. Under the permissions policy section in the permission tab, click on the drop-down that says "Create inline policy."
![](https://i.imgur.com/oF8O4nE.png)
Select Secrets Manager as the service, then add the `GetSecretValue` action, and finally, we're going to apply this to all resources so that we can just get this working really quickly. Click review policy, name this policy "SecretsPolicy," and create the policy. It should now be attached to our role.
![](https://i.imgur.com/FKZtApK.png)
If you go back to the Lambda function and test it again, you'll see the secret you created in Secrets Manager!
## Add Permissions
Now, we want to try and access our custom secret name. Change the `secret_name` variable to the name of your custom-managed secret. If you test the function, you'll start to get `AccessDeniedExceptions` again. Why? It turns out that if you use a secret that is guarded by a non-AWS-managed KMS key, you need to grant your Lambda function additional IAM permissions. The permission that you need is the KMS Decrypt action. Let's add that to our IAM role.
![](https://i.imgur.com/ynikOLe.png)
Once you're at the IAM role, create a new inline policy. This time, use the KMS service and give it the Decrypt action. Generally, you want to select the specific resource to give access to, but for this demo, you can just set it to All Resources. Finally, review the policy, name it something, and create it. Now, you'll see three policies: one for the role, one for the secrets, and one for KMS Decrypt.
If you go back to the Lambda function and invoke it again to access the custom-managed secret, your function should work correctly!
--
Secrets Manager is a powerful AWS service that allows you to store your secrets securely. In this article, I show you how to create a Secret and access it from your AWS Lambda function in Python.
IAM Policy + Code - https://gist.github.com/beabetterdevv/1bf0a0f0f2b77c24dc37bf292c5df9a1
Become a Better Developer Using the Courses I Recommend Below:
- Master FAANG Coding Interviews - https://bit.ly/3CVgRN9
- Learn AWS From Scratch - https://bit.ly/3gasoAm
- Master Python here - https://bit.ly/3yJFJpI
📚 My Courses 📚
AWS Lambda - A Practical Guide - https://www.udemy.com/course/aws-lambda-a-practical-guide/?referralCode=F6D1A50467E579C65372
🎉SUPPORT BE A BETTER DEV🎉
Become a Patron: https://www.patreon.com/beabetterdev
📚 MY RECOMMENDED READING LIST FOR SOFTWARE DEVELOPERS📚
Clean Code - https://amzn.to/37T7xdP
Clean Architecture - https://amzn.to/3sCEGCe
Head First Design Patterns - https://amzn.to/37WXAMy
Domain Driven Design - https://amzn.to/3aWSW2W
Code Complete - https://amzn.to/3ksQDrB
The Pragmatic Programmer - https://amzn.to/3uH4kaQ
Algorithms - https://amzn.to/3syvyP5
Working Effectively with Legacy Code - https://amzn.to/3kvMza7
Refactoring - https://amzn.to/3r6FQ8U
🌎 Find me here:
Twitter - https://twitter.com/BeABetterDevv
Instagram - https://www.instagram.com/beabetterdevv/
Patreon - Donations help fund additional content - https://www.patreon.com/beabetterdev