How to launch an RDS Cluster with Multi AZ Read Replica using Terraform
Tags: ec2, rds, terraform, availabilityzone
Published: 2023-09-22 18:46:39

# What is Terraform?

- HashiCorp Terraform is an infrastructure as code (IaC) tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share.

Please visit my **[GitHub Repository for RDS articles](https://github.com/awsmine/RDS_projects)** on various topics being updated on constant basis.

Please visit my **[GitHub Repository for Terraform articles](https://github.com/awsmine/Terraform_projects)** on various topics being updated on constant basis.


_**Let’s get started!**_


# Objectives:

**1.** Sign into AWS Management Console.

**2.** Create the organizational structure 

**3.** Under ***`RDS_files`*** directory:
Create 4 files - ***`variables.tf`***, ***`terraform.tfvars`***, ***`main.tf`***, ***`outputs.tf`***


**4.** Initialize Terraform

**5.** Generate the action plans

**6.** Create all the resources declared in main.tf configuration file

**7.** Validate all resources created in the AWS Console

**8.** Execute Database Operations via SSH

# Pre-requisites:
- AWS user account with admin access, not a root account.
- Cloud9 IDE with AWS CLI.

# Resources Used:

[Terraform documentation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)

[What is Amazon Relational Database Service (Amazon RDS)?](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html)

# Steps for implementation to this project:

## 1. Sign into AWS Management Console.

- Make sure you're in the N. Virginia (us-east-1) region

## 2. Let’s create the following organizational structure as shown below.


## 3. Under ***`RDS-files`*** directory:
Create 4 files - ***`variables.tf`***, ***`terraform.tfvars`***, ***`main.tf`***, ***`outputs.tf`***

- 1. variables.tf - to declare all the global variables with a short description and a default value.

```
variable "access_key" {
    description = "Access key to AWS console"
}
variable "secret_key" {
    description = "Secret key to AWS console"
}
variable "region" {
    description = "AWS region"
}
```

- 2. terraform.tfvars - Replace the values of access_key and secret_key by copying your AWS Access Key ID and Secret Access Key ID.

```
region = "us-east-1"
access_key = "<YOUR AWS CONSOLE ACCESS ID>"
secret_key = "<YOUR AWS CONSOLE SECRET KEY>"
```

- 3. main.tf - Creating a EC2, RDS and  its components
- define the provider as aws
- Create a Security group and key pair for EC2 in main.tf file
- Create an EC2 Instance
- Create a Security group for RDS
- Create RDS Database DB Cluster and Instance
# an Amazon Aurora database with Multi-AZ enabled
# Creating Amazon Aurora Cluster 

```
# define the provider as aws
provider "aws" {
    region     = "${var.region}"
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"            
}

# Create a Security group and key pair for EC2
# Creating Security Group for EC2 
resource "aws_security_group" "web-server" {
    name        = "MyEC2server-SG"
    description = "Security for EC2 server to connect with RDS"
    ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]     
    }
    egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]     
    }           
}

# Creating Key pair for EC2 
resource "tls_private_key" "example" {
  algorithm = "RSA"
  rsa_bits  = 4096          
}

resource "aws_key_pair" "rev_key" {
  key_name   = "RevKey"
  public_key = tls_private_key.example.public_key_openssh           
} 

# Launch an EC2 Instance
resource "aws_instance" "web-server" {
    ami             = "ami-00c6177f250e07ec1"
    instance_type   = "t2.micro"
    key_name        = aws_key_pair.rev_key.key_name
    security_groups = ["${aws_security_group.web-server.name}"]
    user_data = <<-EOF
#!/bin/bash -ex 
yum install mysql -y    
    EOF
    tags = {
        Name = "MyRDSEC2server"     
    }           
}

# Create a Security group for RDS
resource "aws_security_group" "rds-server" {
    name        = "RDS-AZ-SG"
    description = "Security group for RDS Aurora"
    ingress {
        from_port   = 3306
        to_port     = 3306
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]     
    }
    egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]     
    }           
}

# Create RDS Database DB Cluster and Instance
# an Amazon Aurora database with Multi-AZ enabled
# Creating Amazon Aurora Cluster 
resource "aws_rds_cluster" "aurorards" {
  cluster_identifier      = "myauroracluster"
  engine                  = "aurora-mysql"
  database_name           = "MyDB"
  master_username         = "Admin"
  availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
  master_password         = "Admin123"
  vpc_security_group_ids = [aws_security_group.rds-server.id]
  storage_encrypted = false
  skip_final_snapshot   = true          
}
# Launching Amazon Aurora DB Instance 
resource "aws_rds_cluster_instance" "cluster_instances" {
  count = 2
  identifier         = "muaurorainstance${count.index}"
  cluster_identifier = aws_rds_cluster.aurorards.id
  publicly_accessible = true
  instance_class     = "db.t3.small"
  engine             = aws_rds_cluster.aurorards.engine
  engine_version =      aws_rds_cluster.aurorards.engine_version            
}
```

- 4. output.tf - displays the output as EC2 instance ID and aurorards endpoint.

```
output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.web-server.id          
}
output "cluster_endpoint" {
  value       = aws_rds_cluster.aurorards.endpoint          
}
```

## 4. Initialize Terraform

***`cd RDS-files`***

```
terraform version
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxq3gy44nw7id71ro2ok.png)


- terraform init will check for all the plugin dependencies and download them if required, this will be used for creating a deployment plan.

```
terraform init
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmedlnpgko1fi9lul0w5.png)


## 5. To generate the action plans, run the below command:

```
terraform plan
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qstcun481qvjbo5b9n2l.png)


## 6. Create all the resources declared in main.tf configuration file

```
terraform apply
```
- takes up to 15-20 minutes to create all the resources

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbqwldt3fk6p4fdr4828.png)


## 7. Validate all resources created in the AWS Console

- Aurora Cluster in Multi-zone

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qlc98b99mwijdusjopzl.png)





- Click on the RDS cluster/Connectivity & security to find the endpoint of your Master(Writer) and Reader instances, with which you can connect to your DB instance.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxuwevyznbcbftkvjj7r.png)



- Copy the Endpoints for later use

```
# Master(Writer) endpoint 
myauroracluster.cluster-cgizjtuyxkda.us-east-1.rds.amazonaws.com

# Reader instance endpoint
myauroracluster.cluster-ro-cgizjtuyxkda.us-east-1.rds.amazonaws.com
```

##8. Execute Database Operations via SSH

- select the MyRDSEC2server, Click on Connect button to SSH into the EC2 instance



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z83y4evjrq33mlr9f7z0.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37lx218u8vrw3zcj6vit.png)




- Switch to the root user

```
sudo -su
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lg31z8wg0hsc3wi10cwt.png)


- Log into the RDS instance

```
# mysql -h <Hostname> -u <username> -p
# mysql -h <Master(Writer)Cluster endpoint> -u <Username>
# -p Admin123

mysql -h myauroracluster.cluster-cgizjtuyxkda.us-east-1.rds.amazonaws.com -u Admin -p
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n7mq03ou5amxhz5ji7p.png)


- List all Databases

```
Show databases;
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dykuobunwtec6xipshl.png)




- Create database rev_aurora_db

```
Create database rev_aurora_db;
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z34rat2y5q405r4nsoy1.png)


- Select the newly-created database

```
use rev_aurora_db;
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsssa4k0hbfapqdz047q.png)

- create a table named ***`students`*** and insert few rows of data 

```
CREATE TABLE students       
  (
     subject_id   INT auto_increment,
     subject_name VARCHAR(255) NOT NULL,
     teacher      VARCHAR(255),
     start_date   DATE,
     lesson       TEXT,
     PRIMARY KEY (subject_id)       
  );
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41th1dja7mmwpvmtzkgt.png)

- Insert data into the table

```
INSERT INTO students(subject_name, teacher) VALUES ('Science', 'Sav');

INSERT INTO students(subject_name, teacher) VALUES ('Hindi', 'Nita');

INSERT INTO students(subject_name, teacher) VALUES ('Maths', 'Prabha');

INSERT INTO students(subject_name, teacher) VALUES ('Arts', 'Manju');
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0onwdhvpi5kc38gddy1.png)

- select the contents of the table ***`students`***

```
select * from students;
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7dhwoajgo578cx01559r.png)

- Exit from mysql 

```
exit
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0zacxx5xqopwiszbxcy.png)


# Cleanup

```
terraform destroy
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fwuacyq3vkuxkxsbwqip.png)


# What we have done so far

- Using Terraform, we have successfully launched an EC2 Instance, created an Amazon Aurora MySQL database with Multi-Az enabled and executed Database operations via ssh.