We value your privacy

We use cookies to help enhance and develop our website experience, by analysing our traffic. By clicking “ACCEPT ALL” you consent to our use of cookies. Visit our cookie policy for more info.

Skip to main content

Part 3 - Create an RDS DB instance

By Ben Outram / 2018-06-15

Create a new file rds.tf which we will add all of our RDS configuration to.

Create subnets in each availability zone for RDS, each with address blocks within the VPC:

resource "aws_subnet" "rds" {
  count                   = "${length(data.aws_availability_zones.available.names)}"
  vpc_id                  = "${aws_vpc.vpc.id}"
  cidr_block              = "10.0.${length(data.aws_availability_zones.available.names) + count.index}.0/24"
  map_public_ip_on_launch = true
  availability_zone       = "${element(data.aws_availability_zones.available.names, count.index)}"
  tags {
    Name = "rds-${element(data.aws_availability_zones.available.names, count.index)}"
  }
}

Create a subnet group with all of our RDS subnets. The group will be applied to the database instance:

resource "aws_db_subnet_group" "default" {
  name        = "${var.rds_instance_identifier}-subnet-group"
  description = "Terraform example RDS subnet group"
  subnet_ids  = ["${aws_subnet.rds.*.id}"]
}

Create a RDS security group in the VPC which our database will belong to:

resource "aws_security_group" "rds" {
  name        = "terraform_rds_security_group"
  description = "Terraform example RDS MySQL server"
  vpc_id      = "${aws_vpc.vpc.id}"
  # Keep the instance private by only allowing traffic from the web server.
  ingress {
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = ["${aws_security_group.default.id}"]
  }
  # Allow all outbound traffic.
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags {
    Name = "terraform-example-rds-security-group"
  }
}

Create a RDS MySQL database instance in the VPC with our RDS subnet group and security group:

resource "aws_db_instance" "default" {
  identifier                = "${var.rds_instance_identifier}"
  allocated_storage         = 5
  engine                    = "mysql"
  engine_version            = "5.6.35"
  instance_class            = "db.t2.micro"
  name                      = "${var.database_name}"
  username                  = "${var.database_user}"
  password                  = "${var.database_password}"
  db_subnet_group_name      = "${aws_db_subnet_group.default.id}"
  vpc_security_group_ids    = ["${aws_security_group.rds.id}"]
  skip_final_snapshot       = true
  final_snapshot_identifier = "Ignore"
}

Manage the MySQL configuration by creating a parameter group:

resource "aws_db_parameter_group" "default" {
  name        = "${var.rds_instance_identifier}-param-group"
  description = "Terraform example parameter group for mysql5.6"
  family      = "mysql5.6"
  parameter {
    name  = "character_set_server"
    value = "utf8"
  }
  parameter {
    name  = "character_set_client"
    value = "utf8"
  }
}

Finally let's define new variables that we have introduced in configuration blocks during this section.

Add the following to variables.tf:

variable "rds_instance_identifier" {}
variable "database_name" {}
variable "database_password" {}
variable "database_user" {}

Assign the variable values in terraform.tfvars, excluding the password variable:

rds_instance_identifier = "terraform-mysql"
database_name = "terraform_test_db"
database_user = "terraform"

Assign the password variable in our user.tfvars file which should be ignored from version control. Give this property a random password. It will be the MySQL password for the Terraform user account used by the web application.

database_password = "some-random-password"

We can now try another plan:

$ terraform plan -var-file="user.tfvars"

Terraform will perform the following actions:

  + aws_db_instance.default
  + aws_db_parameter_group.default
  + aws_db_subnet_group.default
  + aws_security_group.rds
  + aws_subnet.rds[0]
  + aws_subnet.rds[1]
  + aws_subnet.rds[2]

Plan: 7 to add, 0 to change, 0 to destroy.

It's time to review the plan and apply our changes again before we move on!

$ terraform apply -var-file="user.tfvars"

Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

You can find all the source code for this part of the lab here in GitHub.

More posts in this series