I love not having to manage databases. Hosting it on your compute is guaranteed to be cheaper, but I don’t want to be constantly worrying about backups and database upgrade / maintenance.

AWS offers managed databases, known as RDS. Mostly I use postgres, which works well for most use cases. (It’s also a given that - if you don’t really need NoSQL database, then don’t use it).

If I spin up RDS postgres, I can reach it assuming I have set up the correct networking pathways. (And you shouldn’t expose your database to public, unless it’s for playground with no sensitive data.)

RDS itself returns a hostname with following format: mydb.123456789012.us-east-1.rds.amazonaws.com. This works well for all intent and purposes, but there are some cases where you might want it to be easy to remember, or that you want to switch database instance without incurring downtime. A simple solution is to setup a DNS record, but it would be nice if you can set it all up during database creation!

Enough intro, below is the terraform code (and yes, this works for a replica as well):

resource "aws_db_instance" "db" {
  engine            = var.engine
  allocated_storage = var.allocated_storage
  engine_version    = var.engine_version
  instance_class    = var.instance_class

  identifier = var.identifier
  db_name    = var.db_name
  username   = var.username
  password   = var.password

  replicate_source_db = var.source_db_id # for replica

  parameter_group_name = var.parameter_group_name

  performance_insights_enabled    = true
  performance_insights_kms_key_id = var.performance_insights_kms_key_id

  deletion_protection = var.deletion_protection

  ### networking
  vpc_security_group_ids = var.vpc_security_group_ids
  db_subnet_group_name   = var.db_subnet_group_name

  ### backup (in UTC)
  maintenance_window      = var.maintenance_window
  backup_window           = var.backup_window
  backup_retention_period = var.backup_window != null ? 3 : 0 # Backups are required in order to create a replica
  skip_final_snapshot     = var.skip_final_snapshot

  apply_immediately = var.apply_immediately

resource "aws_route53_record" "db" {
  zone_id = var.zone_id
  name    = var.dns_name
  type    = "CNAME"
  ttl     = 5
  records = [aws_db_instance.db.address]