Terraform Hands-On: Setting Up a Database for a Web Application Using AWS RDS with Terraform
I will walk through the steps to provision a database for a web application using AWS RDS (Relational Database Service) with Terraform. This setup will include creating a subnet group, a security group, IAM roles, and an RDS instance. Let's dive into the details.
Prerequisites
Before we begin, ensure you have the following:
Terraform installed on your local machine.
AWS credentials configured (e.g., using aws configure).
Subnets in your VPC to deploy the database.
Project Structure
First, let's outline the structure of our Terraform project:
- Configuring the AWS Provider In provider.tf, we start by configuring the AWS provider. This tells Terraform to use AWS for provisioning resources.
# Configure AWS provider
provider "aws" {
region = var.aws_region
}
- Defining Variables We define our variables in variables.tf to make our configuration flexible and reusable. This includes the AWS region, database engine, instance class, database name, username, password, and subnet IDs.
variable "aws_region" {
description = "AWS region to deploy resources in"
default = "us-east-2"
}
variable "subnet_ids" {
type = list(string)
description = "List of subnet IDs for the DB subnet group"
}
# Define variables
variable "db_engine" {
default = "mysql"
}
variable "db_instance_class" {
default = "db.t3.micro"
}
variable "db_name" {
default = "mydatabase"
}
variable "db_username" {
default = "admin"
}
variable "db_password" {
default = "abcxyz123" # Replace with secure password
}
Provisioning the RDS Instance
We provision the RDS instance using the specified parameters. We associate the instance with the subnet group and security group that we create. Creating an IAM role that the RDS instance can assume. This role allows the RDS to interact with other AWS services securely.
# Create a DB subnet group
resource "aws_db_subnet_group" "my_subnet_group" {
name = "my-subnet-group"
subnet_ids = var.subnet_ids
tags = {
Name = "My DB Subnet Group"
}
}
# Create a DB security group
resource "aws_security_group" "db_security_group" {
name = "db-security-group"
description = "Allow database inbound traffic"
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "DB Security Group"
}
}
# Create an IAM role for RDS
resource "aws_iam_role" "rds_role" {
name = "rds-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Principal = {
Service = "rds.amazonaws.com"
},
Action = "sts:AssumeRole"
}]
})
}
# Create RDS instance
resource "aws_db_instance" "my_database" {
identifier = "mydatabase-instance"
allocated_storage = 20
storage_type = "gp2"
engine = var.db_engine
engine_version = "8.0.35"
instance_class = var.db_instance_class
db_name = var.db_name
username = var.db_username
password = var.db_password
db_subnet_group_name = aws_db_subnet_group.my_subnet_group.name
vpc_security_group_ids = [aws_security_group.db_security_group.id]
iam_database_authentication_enabled = true
skip_final_snapshot = true
publicly_accessible = false
tags = {
Name = "My Database"
}
}
# Output
output "db_endpoint" {
value = aws_db_instance.my_database.endpoint
}
Outputs
We define outputs to display the endpoint of the RDS instance after it has been created. This endpoint is essential for connecting your web application to the database.
output "database_endpoint" {
description = "Endpoint of the provisioned database"
value = aws_db_instance.my_database.endpoint
}
terraform.tfvars Block
aws_region = "us-east-2" subnet_ids = ["subnet-0eaa8b8dbef1a4749", "subnet-022f81991f8a78cd6", "subnet-049a83138e31b1e8d"]
Terraform Initialization (terraform init)
The terraform init command initializes a Terraform working directory by downloading necessary providers and modules defined in your configuration files (main.tf, variables.tf, etc.).
terraform init
Terraform Plan (terraform plan)
The terraform plan command creates an execution plan detailing the actions Terraform will take to achieve the desired state as defined in your configuration files.
terraform plan
Terraform Apply (terraform apply)
The terraform apply command executes the actions proposed in the execution plan generated by terraform plan, provisioning and managing infrastructure according to your Terraform configuration.
terraform apply
Terraform Destroy (terraform destroy)
The terraform destroy command deletes the resources made by the apply command.
terraform destroy
Conclusion:
We have successfully set up a database for a web application using AWS RDS with Terraform. This setup includes creating necessary subnet groups, security groups, IAM roles, and the RDS instance itself. Terraform makes it easier to manage infrastructure as code, allowing for version control, collaboration, and automation