Create RDS cluster and manage passwords in 2024
Tags: devops, terraform, database, rds
Published: 2024-02-01 21:33:59


Hello there! In this post I am going to show you Terraform code example of how to create AWS RDS cluster and mange DB passwords in  AWS Secrets Manager. 

---

Ok, let's get started with creating RDS cluster. In my example I am going to create Aurora PostgreSQL Serverless DB. To create a cluster I am going to use [existing terraform module ](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master). I will put details after each part of the code. Also the all scripts can be found in [my repo ](https://github.com/nbekenov/rds-aurora)

> data.tf to get VPC details and engine details

```
data "aws_caller_identity" "current" {}

data "aws_vpc" "vpc" {
  filter {
    name   = "tag:Name"
    values = [var.vpc_name]
  }
}

data "aws_subnets" "private" {
  filter {
    name   = "tag:Name"
    values = ["${var.vpc_name}-private-*"]
  }
}

data "aws_rds_engine_version" "postgresql" {
  engine  = "aurora-postgresql"
  version = var.engine_version
}
```
> vars.tf - update vars based on your environment setup

```
variable "database_name" {
  type        = string
  description = "database_name"
  default     = "aurorapostgres"
}

variable "admin_user_name" {
  type        = string
  description = "admin_user_name"
  default     = "aurora_admin"
}

variable "engine_version" {
  type        = string
  description = "postgresql engine_version"
  default     = "15.4"
}

variable "max_capacity" {
  type        = number
  description = "max scaling capacity"
  default     = 4
}

variable "min_capacity" {
  type        = number
  description = "min scaling capacity"
  default     = 2
}

variable "vpc_name" {
  type        = string
  description = "vpc_name"
  default     = "main-vpc"
}
```

> rds.tf
```
resource "aws_kms_key" "aurora_kms_key" {
  description             = "CMK for Aurora PostgreSQL server side encryption"
  deletion_window_in_days = 10
  enable_key_rotation     = false
}

resource "aws_kms_alias" "aurora_kms_key_alias" {
  name          = "alias/aurora-data-store-key"
  target_key_id = aws_kms_key.aurora_kms_key.id
}

resource "aws_db_subnet_group" "serverlessv2_sg" {
  name       = "${var.database_name}-subnet_group"
  subnet_ids = data.aws_subnets.private.ids
}

module "aurora_postgresql_v2" {
  source  = "terraform-aws-modules/rds-aurora/aws"
  version = "8.5.0"

  name          = var.database_name
  database_name = var.database_name

  engine         = data.aws_rds_engine_version.postgresql.engine
  engine_version = data.aws_rds_engine_version.postgresql.version

  instance_class = "db.serverless"
  instances = {
    one = {}
    two = {}
  }
  serverlessv2_scaling_configuration = {
    min_capacity = var.min_capacity
    max_capacity = var.max_capacity
  }

  master_username                     = var.admin_user_name
  manage_master_user_password         = true
  storage_encrypted                   = true
  kms_key_id                          = aws_kms_key.aurora_kms_key.arn
  iam_database_authentication_enabled = true
  ca_cert_identifier                  = "rds-ca-rsa2048-g1"

  vpc_id               = data.aws_vpc.vpc.id
  db_subnet_group_name = aws_db_subnet_group.serverlessv2_sg.name
  security_group_rules = {
    vpc_ingress = {
      cidr_blocks = [data.aws_vpc.vpc.cidr_block]
    }
  }

  monitoring_interval = 60
  apply_immediately   = true
  skip_final_snapshot = true

  deletion_protection = true

}
```

So here I am at first creating KMS key that will be used in server side encryption. Then I am creating cluster with subnet group. Let's stop on DB master user and password

Previously there were couple ways to setup DB master user and password:
- create secret (password=random string) in AWS Secrets Manager and then using terraform `${data.aws_secretsmanager_secret_version.db_password.secret_string}` provide password to create the cluster. In this case if someone will get access to your Terraform state file they will be able to see the DB password in the plain text.
- To workaround this you could have configured password update by enabling secrets rotation in AWS Secrets Manager. That would usually require additional Lambda function that will trigger rotation and password update in RDS cluster

But now (well [since Dec 22, 2022](https://aws.amazon.com/about-aws/whats-new/2022/12/amazon-rds-integration-aws-secrets-manager/)) "...RDS fully manages the master user password and stores it in AWS Secrets Manager whenever your RDS database instances are created, modified, or restored. The new feature supports the entire lifecycle maintenance for your RDS master user password including regular and automatic password rotations; removing the need for you to manage rotations using custom Lambda functions." 

The life become significantly easier - you just need to select the option

```
  master_username                     = var.admin_user_name
  manage_master_user_password         = true
```
And it will create secret for you. The rotation schedule by default is 7 days.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdxrgjjf8j2n2t9iuc8z.png)

And that's it. We created RDS cluster and managing master password in most secure way with enabled rotation.

In the next post I will be providing details on how to configure secure access to RDS instances using Terraform

https://dev.to/aws-builders/securely-connect-to-an-amazon-rds-2i3p