Using Terraform:- Deploying PostgreSQL instance with Read-replica in AWS
By: Sameed Uddin Mohammed
Tags: Postgres, Mentorship, AWS, Terraform, Infrastructure As Code

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.

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.html provider "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.

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.

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

allow inbound access from the internet for Postgres at port 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.

configure the DB instance. For testing purpose I’m using small instance type : with 5GB storage,(but feel free to customize based on your own requirements). The PostgreSQL version is 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

to generate password. Once instance launched successfully it will be printed later . You can also look in the file 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:

Backups are required to create a replicas. 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

}