Creating a PostgreSQL RDS database with Terraform

Amazon Relational Database Service (RDS) is an on-demand, ready-to-use, and resizable EC2 instance specifically tailored and configured to run the requested database server. You can launch many different relational database servers on RDS, and we'll focus on PostgreSQL for this recipe.

Getting ready

To step through this recipe, you will need the following:

  • A working Terraform installation
  • An AWS provider configured in Terraform (refer to the previous recipes)
  • An Internet connection

How to do it…

There are many parameters at play in a database deployment, even a simple one. To be certain of what we'll deploy, we'll start by filling a simple table with the database requirements, and build on it:

Parameter

Variable name

Value

RDS Database Engine

rds_engine

postgresql

RDS Database Engine Version

rds_engine_version

9.5.2

RDS Instance Name

rds_identifier

db

RDS Instance Type

rds_instance_type

db.t2.micro

RDS Storage Size (GB)

rds_storage_size

5

RDS First Database Name

rds_db_name

iac_book_db

RDS Administrator Username

rds_admin_user

dbadmin

RDS Administrator Password

rds_admin_password

super_secret_password

RDS Publicly Accessible

rds_publicly_accessible

true

Let's set all those variables in our variables.tf file:

variable "rds_identifier" {
  default = "db"
}

variable "rds_instance_type" {
  default = "db.t2.micro"
}
variable "rds_storage_size" {
  default = "5"
}

variable "rds_engine" {
  default = "postgres"
}

variable "rds_engine_version" {
  default = "9.5.2"
}

variable "rds_db_name" {
  default = "iac_book_db"
}

variable "rds_admin_user" {
  default = "dbadmin"
}

variable "rds_admin_password" {
  default = "super_secret_password"
}

variable "rds_publicly_accessible" {
  default = "true"
}

As we're running PostgreSQL and we want it to be available on the Internet (though generally not a good idea for production), we'll need a security group allowing just the default PgSQL port (TCP/5432) for our IP address (refer to the Using AWS security groups with Terraform recipe), in securitygroups.tf:

resource "aws_security_group" "rds_security_group" {
  name        = "rds_security_group"
  description = "RDS Security Group"

  ingress {
    from_port   = 5432
    to_port     = 5432
    protocol    = "tcp"
    cidr_blocks = ["1.2.3.4/32"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags {
    Name = "rds_security_group"
  }
}

Now we have everything in place to construct the aws_db_instance resource:

resource "aws_db_instance" "db" {
  engine            = "${var.rds_engine}"
  engine_version    = "${var.rds_engine_version}"
  identifier        = "${var.rds_identifier}"
  instance_class    = "${var.rds_instance_type}"
  allocated_storage = "${var.rds_storage_size}"
  name              = "${var.rds_db_name}"
  username          = "${var.rds_admin_user}"
  password          = "${var.rds_admin_password}"
  publicly_accessible    = "${var.rds_publicly_accessible}"
  vpc_security_group_ids = ["${aws_security_group.rds_security_group.id}"]
  tags {
    Name = "IAC Database in ${var.aws_region}"
  }
}

As we did previously, a quick output giving us the FQDN of our new database will help us to use it quickly, in outputs.tf:

output "RDS" {
  value = "address: ${aws_db_instance.db.address}"
}

Let's terraform apply now and try the result:

# psql -h <your_db_address> -d iac_book_db -U dbadmin
Password for user dbadmin:
psql (9.5.4, server 9.5.2)
[...]

iac_book_db=> l
                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-------------+----------+----------+-------------+-------------+-----------------------
 iac_book_db | dbadmin  | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres    | dbadmin  | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 rdsadmin    | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 | rdsadmin=CTc/rdsadmin
 template0   | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/rdsadmin          +
             |          |          |             |             | rdsadmin=CTc/rdsadmin
 template1   | dbadmin  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/dbadmin           +
             |          |          |             |             | dbadmin=CTc/dbadmin
(5 rows)

There are many more useful options you can use or set, such as maintenance windows, backup retention periods, dedicated database subnets, storage encryption, and master/slave configuration.

There's more…

How would that work when using Ansible to do a similar job with the same values? Just as easy as usual:

---
- name: create RDS PgSQL
  rds:
    command: create
    instance_name: db
    db_engine: postgres
    engine_version: 9.5.2
    db_name: iac_book_db
    size: 5
    instance_type: db.t2.micro
    username: dbadmin
    password: super_secure_password
    publicly_accessible: yes
    tags:
      Name: IAC Database

After executing this playbook, a similar PostgreSQL server will run on RDS as we just did with Terraform.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.66.185