Securely Deploying an RDS Instance with AWS Secrets Manager in Terraform

Securely Deploying an RDS Instance with AWS Secrets Manager in Terraform

Managing database credentials securely is crucial in cloud infrastructure. Instead of hardcoding passwords in Terraform configurations, we can use AWS Secrets Manager to store sensitive information securely. This post walks through deploying an Amazon RDS MySQL instance using Terraform, with a dynamically generated password stored in AWS Secrets Manager.

Why Use AWS Secrets Manager for RDS Passwords?

Hardcoding database credentials in Terraform scripts or environment variables is a security risk. AWS Secrets Manager securely stores credentials and enables automatic password rotation. Using Terraform, we can:

  • Generate a strong password dynamically.

  • Store the password securely in AWS Secrets Manager.

  • Retrieve the password securely for our RDS instance.

  • Ensure better security and compliance in our infrastructure.


Terraform Implementation

1️⃣ Generate a Secure Password

Instead of defining a static password, we use the random_password resource to generate a strong password dynamically:

resource "random_password" "db_password" {
  length           = 16
  special          = true
  override_special = "_!%^"
}

This ensures that our database password is random, strong, and compliant with security best practices.

2️⃣ Store the Password in AWS Secrets Manager

To prevent hardcoding passwords in Terraform, we store the generated password in AWS Secrets Manager:

resource "aws_secretsmanager_secret" "db_secret" {
  name = "test-db-password"
}

resource "aws_secretsmanager_secret_version" "db_secret_version" {
  secret_id     = aws_secretsmanager_secret.db_secret.id
  secret_string = random_password.db_password.result
}

Now, the password is stored securely in AWS Secrets Manager, and we can retrieve it when deploying our database.


3️⃣ Retrieve the Password from AWS Secrets Manager

When deploying the RDS instance, Terraform retrieves the password from Secrets Manager using data sources:

data "aws_secretsmanager_secret" "db_secret" {
  name = "test-db-password"
}

data "aws_secretsmanager_secret_version" "db_secret_version" {
  secret_id = aws_secretsmanager_secret.db_secret.id
}

This ensures that the RDS instance never stores or exposes the password in plain text within Terraform configurations.


4️⃣ Deploy an RDS MySQL Instance

A. Create an RDS Subnet Group

RDS instances require a subnet group to define where the database will be deployed:

resource "aws_db_subnet_group" "test_subnet_group" {
  name = "test-db-subnet-group"
  subnet_ids = [
    aws_subnet.subnet1-public.id,
    aws_subnet.subnet2-public.id,
  ]
  tags = {
    Name = "My test DB subnet group"
  }
}

B. Deploy the RDS Instance

Finally, we create the Amazon RDS MySQL instance with the password retrieved from Secrets Manager:

resource "aws_db_instance" "test_db_instance" {
  identifier           = "testdb"
  allocated_storage    = 10
  engine               = "mysql"
  engine_version       = "8.0.39"
  instance_class       = "db.t3.medium"
  db_name              = "test_db"
  username             = "dbadmin"
  password             = data.aws_secretsmanager_secret_version.db_secret_version.secret_string
  publicly_accessible  = true
  db_subnet_group_name = aws_db_subnet_group.test_subnet_group.id
}

Key Benefits of This Approach

Enhanced Security: No hardcoded passwords; credentials are stored securely in AWS Secrets Manager. ✅ Automated Secret Management: Use AWS Secrets Manager for password retrieval and potential rotation. ✅ Infrastructure as Code (IaC) Best Practices: Terraform manages everything, making deployments consistent and repeatable.


Final Thoughts

By integrating AWS Secrets Manager with Terraform, we ensure that sensitive database credentials remain secure. This approach follows security best practices and prevents secrets from being exposed in logs, version control, or configuration files.

Try implementing this method in your Terraform workflows to strengthen your cloud security! 🚀

Don't forget to destroy your RDS instance after practicing to avoid unexpected costs!

Github Repo: sensitive-information-TF