Welcome to Day 8 of 21 Days of AWS using Terraform. The topic for today is Introduction to AWS RDS MySQL using Terraform. With that we will be able to finish the last part of our two-tier architecture i.e MySQL DB is private subnets.
What is AWS RDS?
Amazon Relational Database Service (Amazon RDS) is a web service that makes it easier to set up, operate, and scale a relational database in the cloud. It provides cost-efficient, resizable capacity for an industry-standard relational database and manages common database administration tasks.
To create a database, go to Database section(AWS Console) and click on RDS
Click on Get Started Now
Then Select MySQL
On the next screen, choose Dev/Test -MySQL(or depend upon your requirement, as my use case is only for testing purpose)
On the next screen provide all the info
As this is for testing Purpose
- DB instance class(db.t2.micro)
- Skip MultiAZ deployment for the time being
- Gave all the info like(DB instance identifier, Master username, Master password)
Fill all the details in the next screen
Mainly you need to fill
- Database name(Don’t confuse it DB instance identifier)
- Backup retention period(0 days, for the time being)
Then click on Launch DB instance
Wait for few mins 5–10min(or depend upon your instance type and size) and check Instance Status(It should be available)
Now lets try to create Read Replica out of this database
Ohho no Create read replica option is not highlighted for me and the reason for that
- We don’t have a snapshot
- We don’t have an automated backups
Read replica is always created from a snapshot or the latest backup
Let’s take a snapshot of this database
Once the snapshot creation is done, let’s try to convert this into multi-AZ. Go to Instance actions and click on Modify
These are the things you need to modify
- Multi-AZ set to Yes
- Under settings you need to enter the password again
- I am enabling backup and set it to 1 day
- On the final screen, you have the option
1: Apply during the next scheduled maintenance window
2: Apply immediately(This will cause a downtime)
To restore a database from the snapshot
and then on the next screen, give DB Instance Identifier or any other setting you want to modify while restoring
To Verify if Multi-AZ is enabled, Click on the particular DB
Now let’s try to create read-replica again, as you can see Create read replica tab is now enabled
The Important thing to remember we can create read replica in any other region
Under the Settings tab, give it a unique name
Now whatever we have done manually here, let’s try to terraformed it
provider "aws" {
region = "us-west-2"
}
resource "aws_db_instance" "my-test-sql" {
instance_class = "${var.db_instance}"
engine = "mysql"
engine_version = "5.7"
multi_az = true
storage_type = "gp2"
allocated_storage = 20
name = "mytestrds"
username = "admin"
password = "admin123"
apply_immediately = "true"
backup_retention_period = 10
backup_window = "09:46-10:16"
db_subnet_group_name = "${aws_db_subnet_group.my-rds-db-subnet.name}"
vpc_security_group_ids = ["${aws_security_group.my-rds-sg.id}"]
}
resource "aws_db_subnet_group" "my-rds-db-subnet" {
name = "my-rds-db-subnet"
subnet_ids = ["${var.rds_subnet1}","${var.rds_subnet2}"]
}
resource "aws_security_group" "my-rds-sg" {
name = "my-rds-sg"
vpc_id = "${var.vpc_id}"
}
resource "aws_security_group_rule" "my-rds-sg-rule" {
from_port = 3306
protocol = "tcp"
security_group_id = "${aws_security_group.my-rds-sg.id}"
to_port = 3306
type = "ingress"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "outbound_rule" {
from_port = 0
protocol = "-1"
security_group_id = "${aws_security_group.my-rds-sg.id}"
to_port = 0
type = "egress"
cidr_blocks = ["0.0.0.0/0"]
}
* allocated_storage: This is the amount in GB
* storage_type: Type of storage we want to allocate(options avilable "standard" (magnetic), "gp2" (general purpose SSD), or "io1" (provisioned IOPS SSD)
* engine: Database engine(for supported values check https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html) eg: Oracle, Amazon Aurora,Postgres
* engine_version: engine version to use
* instance_class: instance type for rds instance
* name: The name of the database to create when the DB instance is created.
* username: Username for the master DB user.
* password: Password for the master DB user
* db_subnet_group_name: DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in thedefault
VPC
* vpc_security_group_ids: List of VPC security groups to associate.
* allows_major_version_upgrade: Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible.
* auto_minor_version_upgrade:Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Defaults to true.
* backup_retention_period: The days to retain backups for. Must be between0
and35
. When creating a Read Replica the value must be greater than0
The daily time range (in UTC) during which automated backups are created if they are enabled. Must not overlap with
* backup_window:maintenance_window
The window to perform maintenance in. Syntax: "ddd:hh24:mi-ddd:hh24:mi".
* maintainence_window:
* multi_az: Specifies if the RDS instance is multi-AZ
* skip_final_snapshot: Determines whether a final DB snapshot is created before the DB instance is deleted. If true is specified, no DBSnapshot is created. If false is specified, a DB snapshot is created before the DB instance is deleted, using the value fromfinal_snapshot_identifier
. Default isfalse
NOTE: Here we are storing mysql password in plan text, I will come up the blog shortly how to store this password in encrypted format.
variables.tf
variable "rds_subnet1" {}
variable "rds_subnet2" {}
variable "db_instance" {}
variable "vpc_id" {}
- We need to do some changes in order to make this work, by outputting the value of private subnet in terraform vpc module which will act an input to rds aws_db_subnet_group
output "private_subnet1" {
value = "${element(aws_subnet.private_subnet.*.id, 1 )}"
}
output "private_subnet2" {
value = "${element(aws_subnet.private_subnet.*.id, 2 )}"
}
- RDS Mysql Module will look like this
module "rds" {
source = "./rds"
db_instance = "db.t2.micro"
rds_subnet1 = "${module.vpc.private_subnet1}"
rds_subnet2 = "${module.vpc.private_subnet2}"
vpc_id = "${module.vpc.vpc_id}"
}
GitHub Link
https://github.com/100daysofdevops/21_days_of_aws_using_terraform/tree/master/rds
Looking forward for you guys to join this journey
- Website: https://100daysofdevops.com/
- Twitter: @100daysofdevops OR @lakhera2015
- Facebook: https://www.facebook.com/groups/795382630808645/
- Medium: https://medium.com/@devopslearning
- GitHub: https://github.com/100daysofdevops/100daysofdevops
- Slack: https://join.slack.com/t/100daysofdevops/shared_invite/enQtNzg1MjUzMzQzMzgxLWM4Yjk0ZWJiMjY4ZWE3ODBjZjgyYTllZmUxNzFkNTgxZjQ4NDlmZjkzODAwNDczOTYwOTM2MzlhZDNkM2FkMDA
- YouTube Channel: https://www.youtube.com/user/laprashant/videos?view_as=subscriber
In addition to that, I am going to host 5 meetups whose aim is to build the below architecture.
- Meetup: https://www.meetup.com/100daysofdevops
- Day1(Nov 10): Introduction to Terraform https://www.meetup.com/100daysofdevops/events/266192294/
- Day 2(Nov 16): Building VPC using Terraform
- Day 3(Nov 17): Creating EC2 Instance inside this VPC using Terraform
- Day 4(Nov 23): Adding Application Load Balancer and Auto-Scaling to the EC2 instance created on Day 3
- Day5(Nov 24): Add Backend MySQL Database and CloudWatch Alarm using Terraform
Keep up the good work, thanks!
Thanks Ryan