In this phase, you will learn how to use AWS Secrets Manager for rotating the password for a private Amazon RDS database. As a reminder, the environment provisioned by CloudFormation is shown in the figure below. You will not be working with the AWS Fargate container in this phase so it is not shown below.
For the sake of simplicity, this tutorial uses jq to parse the secret value into environment variables to allow for easy command line manipulation. This is NOT a security best practice for a production environment. In a production environment, we recommend that you don’t store passwords in environment variables. Click here to read about the best practices for using Secrets Manager.
Go to the CloudFormation console and identify the stack that you built. Make sure you are in the correct region. The list of stacks will look similar to the figure below. The appearance may vary based on the version of the console you are using. Your stack will have a description of Workshop for AWS Secrets Manager with Amazon RDS and AWS Fargate.
Click the stack name link to reveal more information about the stack as shown in the figure below.
Click the Outputs tab as shown in the figure above to list the outputs of the stack which will be similar to the figure below.
The meanings of the output values are described in the table below.
Key | Meaning of Value |
---|---|
BastionIP | The IP address of the bastion host |
DBInstance | The Amazon RDS instance id |
DBPassword | The master password of the RDS data base |
DBUser | The master user of the RDS data base |
EC2UserPassword | The password for the ec2-user id |
ECRRepository | The ECR repository id |
ECSCluster | The ECS cluster id |
You will need the values in the DBInstance, DBPassword, DBUser, and EC2UserPassword outputs in the next section so copy them to a file on your desktop so they are readily available.
In this section, you will store the RDS database credentials in AWS Secrets Manager.
You have now stored your secret value as shown below.
In this section, you will connect to the bastion host so you can run scripts that the CloudFormation template has created on the instance.
Connect to the bastion host using AWS Systems Manager Session Manager. To do this:
The scripts you will be using are owned by the ec2-user account. Enter the command below to change your effective user id and directory to those of ec2-user:
sudo su - ec2-user
ls
You will see two shell scripts.
cat mysql.oldway.sh
You will see contents similar to the lines below. The values PASSWORD, USER, and ENDPOINT represent the hard-coded database password, username, and host endpoint.
(Note: This code fragment is for illustration only and not intended for copying.)
#/bin/bash
# mysql.oldway.sh
# This is the old way of accessing a database, with a hard-coded password.
# This script will only work right after the CloudFormation template runs.
# After you store and rotate the secret, you will need to use the
# mysql.newway.sh script.
mysql \
-pPASSWORD \
-u USER \
-P 3306 \
-h ENDPOINT
./mysql.oldway.sh
use smdemo;
show tables;
select * from bookinfo;
quit;
You can see an example of the output below. This shows that you can access the database, the “old” way, with a hard-coded user name and password. You may be wondering why MariaDB appears in the image below. Amazon Linux 2 includes the MariaDB port of the mysql command as an “extras” module. The mysql program is compatible with both MySQL and MariaDB.
cat mysql.newway.sh
Take a look at the lines below.
(Note: This code fragment is for illustration and not intended for copying.)
getsecretvalue() {
aws secretsmanager get-secret-value --secret-id $1 | \
jq .SecretString | \
jq fromjson
}
The above lines define a shell function that uses the AWS CLI to retrieve the secret whose name is passed as a command line argument ($1). The result is a JSON string so the jq utility is used to extract the actual value of the secret whose JSON key is named SecretString. Here is an example of what a SecretString looks like:
(Note: This code fragment is for illustration and not intended for copying.)
{
"engine": "mysql",
"username": "myuser",
"password": "mypassword",
"host": "my-database-endpoint.ap-southeast-2.rds.amazonaws.com",
"dbname": "myDatabase",
"port": "3306"
}
Note that the SecretString itself is a JSON structure. Now look at the following lines.
(Note: This code fragment is for illustration and not intended for copying.)
secret=`getsecretvalue $1`
user=$(echo $secret | jq -r .username)
password=$(echo $secret | jq -r .password)
endpoint=$(echo $secret | jq -r .host)
port=$(echo $secret | jq -r .port)
These lines call the shell function and then use jq to extract the database username, password, endpoint, and port from the SecretString. These are then passed to the mysql command as shown on the lines below. Note that there is no space after the -p option.
(Note: This code fragment is for illustration and not intended for copying.)
mysql \
-p$password \
-u $user \
-P $port \
-h $endpoint
./mysql.newway.sh smdemo
use smdemo;
show tables;
select * from bookinfo;
quit;
You can see an example of the output below. This shows that you can access the database, the “new” way, using AWS Secrets Manager.
In this section, you will enable the rotation of the secret you created in AWS Secrets Manager.
If your application supports two classes of users, for example a “superuser” and a “normal privilege” user, you could select Use a secret that I have previously stored in Secrets Manager and use the “superuser” credential to rotate the credential for the “normal privilege” user.
Your window should look similar to the figure below.
If you see the following error message, goto the AWS Lambda and verify the Lambda function secretsManagersmdemo exists, than follow the above Rotate steps again but this time selecting Use an existing lambda function to perform rotation and choose secretsManagersmdemo Lambda function to enable automatic rotation.
A message will appear when the rotation is complete. Refresh your browser window to update your any cached fields.
Let’s try to connect to the database again, both the “old” way with a hard-coded password, the “new” way with AWS Secrets Manager.
./mysql.oldway.sh
You should receive an error message (access denied) because the mysql.oldway.sh script has the same hard-coded password.
./mysql.newway.sh smdemo
use smdemo;
show tables;
select * from bookinfo;
quit;
You have completed ths RDS phase and have learned how to use AWS Secrets Manager with Amazon RDS. You will now continue to the Fargate phase.
This video has no audio