Skip to content

Commit afa1057

Browse files
committed
Added sec man to store DB credentials
1 parent c9bbab8 commit afa1057

File tree

7 files changed

+60
-16
lines changed

7 files changed

+60
-16
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
builds/*
22
.terraform
33
.terraform.*
4+
function.zip
5+
src/function/pymysql
6+
src/function/pymysql/*
7+
src/function/PyMySQL-1.1.0.dist-info
8+
src/function/PyMySQL-1.1.0.dist-info/*

terraform-lambda-aurora-serverless/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# AWS Lambda function to Amazon Aurora Serverless
22

3-
The pattern creates a Lambda function and a Amazon Aurora Serverless cluster, a Log group and the IAM resources required to run the application.
3+
The pattern creates an AWS Lambda function and an Amazon Aurora Serverless cluster, a Log group and the IAM resources required to run the application. The database credentials are stored in AWS Secrets Manager secret.
44

55
The Lambda function is written in Python that uses pymysql client to establish connectivity with the serverless database.
66

@@ -22,6 +22,13 @@ terraform init
2222
terrform deploy
2323
```
2424

25+
Naming constraints with Amazon Aurora for Master password:
26+
- The password for the database master user can include any printable ASCII character except /, ', ", @, or a space.
27+
- The password can contain the following number of printable ASCII characters depending on the DB engine: Aurora MySQL: 8–41 and Aurora PostgreSQL: 8–99.
28+
For more information, please refer to [this](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_Limits.html#RDS_Limits.Constraints)
29+
30+
31+
2532
## Testing
2633

2734
After deployment, invoke Lambda function with multiple inputs, and go to the Step Function Console and view the different invocations to note the different behavior with the different inputs.

terraform-lambda-aurora-serverless/example-pattern.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"title": "AWS Lambda function to Amazon Aurora Serverless",
3-
"description": "The pattern creates a Lambda function and an Amazon Aurora Cluster with Serverless instance.",
3+
"description": "The pattern creates a Lambda function and an Amazon Aurora Cluster with Serverless instance. The Database credentials are stored and accessed from AWS Secrets Manager.",
44
"language": "Python",
5-
"level": "200",
5+
"level": "300",
66
"framework": "Terraform",
77
"introBox": {
88
"headline": "How it works",
99
"text": [
1010
"The pattern creates a Lambda function and an Amazon Aurora Cluster with Serverless instance.",
11+
"The Database credentials are stored and accessed from AWS Secrets Manager.",
1112
"It also guides how to invoke the function to access the database."
1213
]
1314
},

terraform-lambda-aurora-serverless/main.tf

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,24 @@ resource "aws_security_group" "aurora_sg" {
142142
}
143143
}
144144

145+
# Secrets Manager Configuration - stores db credentials
146+
147+
resource "aws_secretsmanager_secret" "aurora_secret" {
148+
name = "aurora-db-credentials"
149+
tags = {
150+
Environment = var.environment
151+
}
152+
}
153+
154+
resource "aws_secretsmanager_secret_version" "aurora_secret_version" {
155+
secret_id = aws_secretsmanager_secret.aurora_secret.id
156+
secret_string = jsonencode({
157+
username = var.db_username
158+
password = var.db_password
159+
})
160+
}
161+
162+
145163
# Aurora Configuration
146164
resource "aws_db_subnet_group" "aurora_subnet_group" {
147165
name = "aurora-subnet-group"
@@ -159,8 +177,8 @@ resource "aws_rds_cluster" "aurora_cluster" {
159177
engine_version = "8.0.mysql_aurora.3.04.1"
160178
engine_mode = "provisioned"
161179
database_name = var.database_name
162-
master_username = var.db_username
163-
master_password = var.db_password
180+
master_username = jsondecode(aws_secretsmanager_secret_version.aurora_secret_version.secret_string)["username"]
181+
master_password = jsondecode(aws_secretsmanager_secret_version.aurora_secret_version.secret_string)["password"]
164182
storage_encrypted = true
165183
skip_final_snapshot = true
166184
db_subnet_group_name = aws_db_subnet_group.aurora_subnet_group.name
@@ -230,7 +248,8 @@ resource "aws_iam_role_policy" "lambda_policy" {
230248
"logs:PutLogEvents",
231249
"ec2:CreateNetworkInterface",
232250
"ec2:DescribeNetworkInterfaces",
233-
"ec2:DeleteNetworkInterface"
251+
"ec2:DeleteNetworkInterface",
252+
"secretsmanager:GetSecretValue"
234253
]
235254
Resource = "*"
236255
}
@@ -268,8 +287,7 @@ resource "aws_lambda_function" "aurora_lambda" {
268287
variables = {
269288
DB_ENDPOINT = aws_rds_cluster.aurora_cluster.endpoint
270289
DB_NAME = var.database_name
271-
DB_USERNAME = var.db_username
272-
DB_PASSWORD = var.db_password
290+
SECRET_ARN = aws_secretsmanager_secret.aurora_secret.arn
273291
}
274292
}
275293

terraform-lambda-aurora-serverless/src/function/app.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: MIT-0
3-
43
import os
54
import json
65
import pymysql
76
import logging
7+
import boto3
88

99
logger = logging.getLogger()
1010
logger.setLevel(logging.INFO)
1111

12+
session = boto3.session.Session()
13+
client = session.client('secretsmanager')
14+
15+
host = os.environ['DB_ENDPOINT']
16+
database = os.environ['DB_NAME']
17+
secret_name = os.environ['SECRET_ARN']
18+
19+
def get_secret():
20+
try:
21+
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
22+
except ClientError as e:
23+
raise e
24+
else:
25+
if 'SecretString' in get_secret_value_response:
26+
secret = json.loads(get_secret_value_response['SecretString'])
27+
logger.info(f"value of password: {secret['password']}")
28+
return secret['username'], secret['password']
29+
1230
def lambda_handler(event, context):
13-
# Get database connection info from environment variables
14-
host = os.environ['DB_ENDPOINT']
15-
database = os.environ['DB_NAME']
16-
username = os.environ['DB_USERNAME']
17-
password = os.environ['DB_PASSWORD']
31+
username, password = get_secret()
1832

1933
try:
2034
# Attempt database connection

terraform-lambda-aurora-serverless/variables.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ variable "db_username" {
2222
default = "admin"
2323
}
2424

25+
# Example of valid password: "MyDBPassword123!"
2526
variable "db_password" {
2627
description = "Database administrator password, please change it"
2728
type = string

terraform-lambda-aurora-serverless/versions.tf

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
terraform {
42
required_providers {
53
aws = {

0 commit comments

Comments
 (0)