Skip to main content
This guide covers the security controls available in the module: storage encryption, IAM database authentication, master password management (including Secrets Manager rotation), write-only passwords, deletion protection, and Active Directory integration.

Storage encryption

storage_encrypted defaults to true. All new instances are encrypted by default. You must explicitly set storage_encrypted = false to disable encryption — for example, SQL Server Express edition does not support encryption.
VariableDefaultDescription
storage_encryptedtrueWhether to encrypt the DB instance.
kms_key_idnullARN of the KMS key to use for encryption. If omitted and storage_encrypted = true, AWS uses the default aws/rds key. Use the full ARN, not an alias.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "my-db"

  # Encryption (true by default — shown here for clarity)
  storage_encrypted = true
  kms_key_id        = "arn:aws:kms:eu-west-1:123456789012:key/mrk-1234abcd..."

  # ... other variables
}

Master password management

manage_master_user_password defaults to true. RDS manages the master password in AWS Secrets Manager automatically. The secret ARN is available in the db_instance_master_user_secret_arn output.
When manage_master_user_password = true:
  • RDS stores the password in Secrets Manager.
  • Rotation is handled by RDS (default schedule).
  • You do not provide password_wo.
  • Read replicas and Blue/Green deployments do not support manage_master_user_password. Set it to false and use password_wo / password_wo_version for those cases.

Variables

VariableDefaultDescription
manage_master_user_passwordtrueLet RDS manage the master password in Secrets Manager.
master_user_secret_kms_key_idnullKMS key ARN, ID, alias ARN, or alias name for encrypting the Secrets Manager secret.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "my-db"

  # manage_master_user_password = true (default)
  # Access the secret ARN via: module.db.db_instance_master_user_secret_arn

  master_user_secret_kms_key_id = "arn:aws:kms:eu-west-1:123456789012:key/mrk-..."

  # ... other variables
}

Password rotation

You can configure the rotation schedule explicitly using manage_master_user_password_rotation. This controls a separate aws_secretsmanager_secret_rotation resource.
VariableDefaultDescription
manage_master_user_password_rotationfalseWhether to manage rotation configuration. When false on first apply, RDS handles rotation. Setting to false after previously true disables rotation.
master_user_password_rotate_immediatelynullRotate the secret immediately on apply, rather than waiting for the next window.
master_user_password_rotation_automatically_after_daysnullDays between automatic rotations. Mutually exclusive with schedule_expression.
master_user_password_rotation_durationnullDuration of the rotation window in hours (e.g., "3h").
master_user_password_rotation_schedule_expressionnullcron() or rate() expression for the rotation schedule. Mutually exclusive with automatically_after_days.
The complete-postgres example configures a custom rotation schedule:
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "complete-postgresql"

  engine         = "postgres"
  engine_version = "17"
  # ...

  # Setting manage_master_user_password_rotation to false after it
  # has previously been set to true disables automatic rotation.
  # However using an initial value of false (default) does not disable
  # automatic rotation — rotation will be handled by RDS.
  manage_master_user_password_rotation              = true
  master_user_password_rotate_immediately           = false
  master_user_password_rotation_schedule_expression = "rate(15 days)"
}

Write-only passwords

As an alternative to Secrets Manager, you can provide the password directly using the write-only password_wo variable. This is required when manage_master_user_password = false and no snapshot_identifier or replicate_source_db is provided.
VariableDefaultDescription
password_wonullWrite-only password for the master DB user. Ephemeral — not stored in state.
password_wo_versionnullIncrement this number to trigger a password change.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "my-db"

  manage_master_user_password = false
  password_wo                 = var.db_password  # sourced from a variable or secrets backend
  password_wo_version         = 1

  # ... other variables
}
To rotate the password, update password_wo and increment password_wo_version.
password_wo is declared as ephemeral = true in the module, meaning it is not persisted in Terraform state. Blue/green deployments and replicas must use manage_master_user_password = false with a write-only password.

IAM database authentication

IAM database authentication allows you to use IAM users and roles to authenticate to MySQL and PostgreSQL without a password. RDS verifies identity using an AWS-signed authentication token.
VariableDefaultDescription
iam_database_authentication_enabledfalseEnable IAM authentication for the DB instance.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "my-db"

  iam_database_authentication_enabled = true

  # ... other variables
}

Deletion protection

Deletion protection prevents the RDS instance from being deleted via the AWS console, CLI, or Terraform until the protection is removed. The default is false but production deployments should set this to true.
VariableDefaultDescription
deletion_protectionfalsePrevent deletion of the DB instance.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "prod-db"

  deletion_protection = true

  # ... other variables
}

VPC and public accessibility

publicly_accessible defaults to false. RDS instances are private by default. Do not set this to true unless you specifically require public access and have implemented compensating controls such as VPC security groups and SSL enforcement.
VariableDefaultDescription
vpc_security_group_ids[]List of VPC security group IDs to associate with the instance.
publicly_accessiblefalseWhether the instance is accessible from the internet.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "my-db"

  vpc_security_group_ids = [module.security_group.security_group_id]
  publicly_accessible    = false  # default — shown for clarity

  # ... other variables
}

Active Directory authentication

You can join an RDS instance to an AWS Directory Service (Managed Microsoft AD) domain to enable Windows Authentication. This is primarily used with SQL Server.

AWS Managed Active Directory (legacy approach)

Use domain and domain_iam_role_name together:
VariableDescription
domainID of the Directory Service Active Directory domain (e.g., d-1234567890).
domain_iam_role_nameName of the IAM role the instance uses to call Directory Service APIs. Required when domain is set.
resource "aws_directory_service_directory" "demo" {
  name     = "corp.demo.com"
  password = var.ad_password
  edition  = "Standard"
  type     = "MicrosoftAD"

  vpc_settings {
    vpc_id     = module.vpc.vpc_id
    subnet_ids = slice(tolist(module.vpc.database_subnets), 0, 2)
  }
}

resource "aws_iam_role" "rds_ad_auth" {
  name               = "demo-rds-ad-auth"
  assume_role_policy = data.aws_iam_policy_document.rds_assume_role.json
}

resource "aws_iam_role_policy_attachment" "rds_directory_services" {
  role       = aws_iam_role.rds_ad_auth.id
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSDirectoryServiceAccess"
}

module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "complete-mssql"

  engine         = "sqlserver-ex"
  engine_version = "15.00"
  # ...

  domain               = aws_directory_service_directory.demo.id
  domain_iam_role_name = aws_iam_role.rds_ad_auth.name

  # ...
}

Self-managed Active Directory

Use domain_fqdn and related variables for a self-managed (on-premises) AD. These conflict with domain and domain_iam_role_name:
VariableDescription
domain_fqdnFQDN of the self-managed AD domain (e.g., "corp.example.com").
domain_auth_secret_arnARN of the Secrets Manager secret containing AD credentials. Required when domain_fqdn is set.
domain_dns_ipsList of two IPv4 DNS IP addresses of your AD domain controllers.
domain_ouOrganizational Unit (OU) for the DB instance to join.
module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "my-db"

  domain_fqdn            = "corp.example.com"
  domain_auth_secret_arn = aws_secretsmanager_secret.ad_creds.arn
  domain_dns_ips         = ["10.0.1.10", "10.0.2.10"]
  domain_ou              = "OU=RDS,OU=Databases,DC=corp,DC=example,DC=com"

  # ... other variables
}

Build docs developers (and LLMs) love