Using Terraform:- Deploying PostgreSQL instance with Read-replica in AWS

Sameed Uddin Mohammed
4 min readFeb 7, 2021

We will go through the following steps:

  • Define the infrastructure with Terraform
  • Launch a PostgreSQL instance in AWS RDS
  • Add a replica instance

Terraform is an Infra-as-code Cloud agnostic tool which helps you deploy, update, destroy resources & services that are no longer needed but also manage them across multiple platforms. For more information here

A lot of infrastructure types can be deployed: AWS, GCP, Azure, VMware & more. List of Providers https://www.terraform.io/docs/providers/index.html

Using Version Control System like Github to keep my manage configuration files in one place, make revisions, updating resources, permissions, share code with team or community to showoff.

PostgreSQL has become the preferred open source relational database for many enterprise developers and start-ups, powering leading business and mobile applications. Amazon RDS makes it easy to set up, operate, and scale PostgreSQL deployments in the cloud. For example it can be used as the primary data store or data warehouse for many web, mobile, mapping, and analytics applications.

  1. Lets get started with Terraform tutorial here. By going through these steps, you should be able to set up Terraform, make sure to provide the AWS credential in provider.tf
provider "aws" {
region = "us-west-2"
access_key = "my-access-key"
secret_key = "my-secret-key"
}

2. By using the following link you will be able to setup aws_db_instance& configure it according to your requirements.

# https://www.terraform.io/docs/providers/aws/r/db_instance.htmlprovider "aws" {
profile = "default"
region = "us-east-1"
}
data "aws_vpc" "default" {
default = true
}
resource "random_string" "uddin-db-password" {
length = 32
upper = true
number = true
special = false
}
resource "aws_security_group" "uddin" {
vpc_id = "${data.aws_vpc.default.id}"
name = "uddin"
description = "Allow all inbound for Postgres"
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_db_instance" "uddin-sameed" {
identifier = "uddin-sameed"
name = "uddin"
instance_class = "db.t2.micro"
allocated_storage = 5
engine = "postgres"
engine_version = "12.5"
skip_final_snapshot = true
publicly_accessible = true
vpc_security_group_ids = [aws_security_group.uddin.id]
username = "sameed"
password = "random_string.uddin-db-password.result}"
}

The setting is as follow:

  • The provider defines in Terraform that its a resource is AWS type.
  • The data "aws_vpc" "default"can be used to define a default VPC or Custom VPC you want to use.
  • The aws_security_group allow inbound access from the internet for Postgres at port 5432
  • The aws_db_instance configure the DB instance. For testing purpose I’m using small instance type : db.t2.micro with 5GB storage,(but feel free to customize based on your own requirements). The PostgreSQL version is 12.5 and the snapshot feature is disabled.
  • As per best practices, we should never specify password in configuration file but instead use the extension random_string to generate password. Once instance launched successfully it will be printed later . You can also look in the file terraform.tfstate
  • After configuration is properly, use this command terraform apply. (it will take approximately 5–10 min)to make sure you arent getting any errors and once its done,login and check on AWS Console & confirm . Stop and remove the instance with terraform destroy command.

Let me show you how you can replicate your Primary DB with Secondary DB instance by using additional configuration & point it back to the existing database (master) identifier with replicate_source_db.

Important Notes:

  1. Backups are required to create a replicas.
  2. Username and password must not be set for replicas.

Add this replica configuration to the existing one as follows:

# Backups are required in order to create a replica
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
backup_retention_period = 1
}
resource "aws_db_instance" "uddin-sameed-read" {
identifier = "uddin-sameed-read"
replicate_source_db = aws_db_instance.uddin-sameed.identifier ## refer to the master instance
name = "uddin"
instance_class = "db.t2.micro"
allocated_storage = 5
engine = "postgres"
engine_version = "12.5"
skip_final_snapshot = true
publicly_accessible = true
vpc_security_group_ids = [aws_security_group.uddin.id]
# Username and password must not be set for replicas
username = ""
password = ""
# disable backups to create DB faster
backup_retention_period = 0
}

Then apply this configuration using command terraform apply. There you have it AWS Postgres SQL instance with Read-replica.

Please show your appreciation by Clap! & share your thoughts and recommendations so i we all can learn together.

--

--

Sameed Uddin Mohammed

Terraform|3x-AWS|2x-Azure|2x-GCP|CertifiedCloud/DevOpsEngineerLooking for better opportunities- Remote| Join me https://chat.whatsapp.com/EiCi7XYnCSD7BQnPz2mJIa