DEV Community

Felipe Arcaro
Felipe Arcaro

Posted on • Edited on

Creating an AWS RDS instance with Terraform

TL;DR

Here's the Terraform code to create an RDS Postgres instance:

# RDS instance
resource "aws_db_instance" "my_project_db" {
  engine               = "postgres"
  instance_class       = "db.t3.micro"
  username             = "sidewalk"
  password             = "${var.postgres_pw}"
  allocated_storage    = 20
  publicly_accessible = true
}
Enter fullscreen mode Exit fullscreen mode

Creating an RDS instance

Amazon Relational Database Service (RDS) is a managed database service provided by AWS that simplifies the process of setting up, operating, and scaling a relational database in the cloud.

Here is a quick recap of some RDS notable features:

  • Multi-AZ
    • Supports standby instance in another AZ that helps with failure recover
  • Read replicas
    • Offload read requests
    • Can be used in disaster recovery plan
  • Automatic backups
    • Configurable time window
  • Configurable storage
  • IAM authentication
  • RDS Enhance monitoring

Starting in the Management Console (UI)

First, we create a free RDS Postgres instance through the Management Console. Since this was the first AWS service on this account, it automatically created a VPC 1 and a Security Group 2 to ensure the instance was securely isolated and protected by a firewall.

To see if the Postgres database is working, we can use PGAdmin, but we also need to go through the following steps:

  • Make the RDS instance publicly available
  • Add our personal IP to the Security Group's inbound rules used by the database so we can connect to it from outside the VPC (our personal computer):
    • Although not recommended, we can all ports 0-655353 and all IPs 0.0.0.0/0 to the inbound rules so everyone can connect to our database

Everything seems to be working as expected.

Importing existing resources to Terraform code

Now, let's start with terraform import to import my database instance to my configuration file so I can manage it from there.

First, we create the most basic version of the aws_db_instance resource on our Terraform main.tf file:

resource "aws_db_instance" "my_project_db" {
  engine               = "postgres"
  instance_class       = "db.t2.micro"
  username             = "sidewalk"
  password             = "${var.postgres_pw}"
}
Enter fullscreen mode Exit fullscreen mode

You probably noticed we're using a variable instead of writing the password in plain text. Here's the easiest way to do it:

  • Create a file called vars.tf in the same folder as the main.tf file and add the following code to it:
variable "super_secret_password" {
  default = "ThisPassword123!"
}
Enter fullscreen mode Exit fullscreen mode

Now you can call it from your main terraform code like this ${var.super_secret_password}

Ok, now it's time to run terraform import aws_instance.my_project_db <db-instance-id> (you can find the <db-instance-id> in the Management Console) – it seems like the database was imported successfully.

There was a small problem though – the database we created through the Management Console had the parameter instance_class = db.t3.micro while our Terraform code had instance_class = db.t2.micro.

When we run terraform plan, it says that a particular resource must be replaced. Then, when we run terraform apply, the database created through the Management Console is deleted and we get an error saying there were some important parameters missing to create the new one – in this case, the allocated_storage parameter.

Key learnings on using terraform import:

  • To import an existing infrastructure from AWS, you must have the resource in the Terraform code with all required parameters
  • Make sure the configuration you have on your configuration file matches exactly what you have on AWS
  • terraform plan won't show if there are required parameters missing, only terraform apply

Creating resources from Terraform code

Now that we know how this works, let's go ahead and create the database directly from the Terraform code using AWS documentation on aws_db_instance:

resource "aws_db_instance" "my_project_db" {
  engine               = "postgres"
  instance_class       = "db.t3.micro"
  username             = "sidewalk"
  password             = "${var.postgres_pw}"
  allocated_storage    = 20
}
Enter fullscreen mode Exit fullscreen mode

We can run terraform plan to make sure everything is looking good and terraform apply to create the database. After the database is created, we can type terraform show to see the infrastructure's current state – the VPC, the Security Group, etc.

Key learnings on creating infrastructure using Terraform code:

  • It automatically created it on the only VPC available on that AWS account
  • It automatically added the only Security Group available on that AWS account

And here's the updated Terraform code to make the RDS instance publicly accessible:

# RDS instance
resource "aws_db_instance" "my_project_db" {
  engine               = "postgres"
  instance_class       = "db.t3.micro"
  username             = "sidewalk"
  password             = "${var.postgres_pw}"
  allocated_storage    = 20
  publicly_accessible = true
}
Enter fullscreen mode Exit fullscreen mode

  1. VPC – Virtual Private Cloud is a virtual network infrastructure that allows you to create a logically isolated network environment. It is essentially a virtual data center in the cloud 

  2. A Security Group is a virtual firewall that controls the inbound and outbound traffic for one or more instances. Every instance within a VPC in AWS must be associated with at least one security group. 

Top comments (0)