This project demonstrates the use of Terraform to manage and provision cloud infrastructure on AWS. It was designed to implement a scalable and secure cloud, leveraging AWS services to create a robust environment suitable for hosting web applications. The project includes configurations for a Virtual Private Cloud (VPC), Application Load Balancer (ALB), Auto Scaling Group (ASG), and Relational Database Service (RDS). The infrastructure is secured using AWS Security Groups to manage inbound and outbound traffic for each resource, guaranteeing that only authorized traffic is allowed.
The architecture diagram below shows the infrastructure, which includes:
VPC: A Virtual Private Cloud with public and private subnets across two availability zones.
ALB: An Application Load Balancer to distribute incoming traffic across multiple instances.
ASG: An Auto Scaling Group to ensure the application scales based on demand.
RDS: A managed MySQL database instance for persistent data storage.
Users access the application via the internet through the public ALB DNS, which efficiently distributes traffic across instances within the Auto Scaling Group. This group is configured to dynamically adjust the number of instances based on demand. The RDS serves as the application's data storage solution. All EC2 instances reside in private subnets, ensuring they are not directly accessible from the internet, similar to the RDS.
This Terraform project is organized into two key components: modules and backend configuration. Each part plays a crucial role in managing and deploying infrastructure efficiently.
Modules
Modules are the building blocks of this Terraform configuration. They encapsulate specific pieces of infrastructure, making the code reusable and easier to manage. In this project, we have several modules:
VPC Module: This module is responsible for setting up the Virtual Private Cloud (VPC). It defines the CIDR block and configures both public and private subnets across different availability zones. In this configuration, DNS hostnames are disabled, while DNS support is enabled, ensuring internal DNS resolution within the VPC.
ALB Module: The Application Load Balancer (ALB) module manages the load balancer configuration. It sets up the ALB with specified subnets, target group settings and health check parameters to ensure traffic is distributed efficiently.
ASG Module: The Auto Scaling Group (ASG) module configures the auto-scaling of EC2 instances. It defines the launch template, instance type, and scaling policies to maintain the desired capacity and performance.
RDS Module: This module handles the setup of the Relational Database Service (RDS). It specifies the database engine, version, instance class, and security group settings, ensuring a secure and scalable database environment.
Inside each module, there is a main.tf file that defines the resources, a variables.tf file that defines the variables, and an outputs.tf file that defines the outputs, when needed.
Backend Configuration
The backend configuration is crucial for managing the state of the infrastructure. We can store the state locally or remotely, but doing it remotely is more secure and easier to manage, especially when working in a team. In this project, the backend is configured to use Amazon S3, which stores the Terraform state file. This setup includes:
S3 Bucket: The S3 bucket where the state file is stored.
Key: The path within the bucket for the state file.
Region: The region where the state file is stored.
DynamoDB Table: The DynamoDB table used to lock the state file, ensuring that only one user can modify the state file at a time.
Encryption: Ensures that the state file is stored securely.
The process of creating the backend configuration involves creating the necessary resources using Terraform instead of manually setting them up in the AWS console. This approach ensures that all resources are managed as code, providing consistency and version control.
Once the resources are created, the backend is defined as "s3" to store the Terraform state file. After defining the backend, the terraform init command is used to migrate the state to S3. This command initializes the backend configuration, ensuring that the state is managed remotely and securely.
This module is designed to create a Virtual Private Cloud (VPC) on AWS, along with associated resources such as subnets, internet gateways, and route tables. The architecture is structured to support two public and three private subnets across multiple availability zones, providing a robust and scalable network infrastructure. The two public subnets are used to host the ALB and the three private subnets are used to host the RDS and the EC2 instances.
Features
VPC: Creates a VPC with DNS and hostname support.
Internet Gateway: Provisions an internet gateway to allow inbound and outbound traffic.
Subnets: Configures public and private subnets across multiple availability zones.
Route Tables: Configures route tables to manage network traffic.
Route Table Associations: Associates subnets with the appropriate route tables.
Resources
1. Virtual Private Cloud (VPC)
Resource: aws_vpc.main
cidr_block: The CIDR block for the VPC.
enable_dns_hostnames: Whether to enable DNS hostnames in the VPC.
enable_dns_support: Whether to enable DNS support in the VPC.
tags: Assigns a name tag to the VPC for identification.
The module uses several input variables to customize the deployment, such as: cidr_block, enable_dns_hostnames, public_subnet_cidr_block_1, and others. These variables are defined in the variables.tf file and allow for flexible configuration of the VPC and its components. The module also provides outputs for the VPC ID, subnet IDs, and CIDR blocks in the outputs.tf file, which can be used by other modules or resources within the infrastructure.
ALB Module
The ALB (Application Load Balancer) module is a key component of the infrastructure, designed to manage and distribute incoming application traffic across multiple targets, such as EC2 instances, in a single or multiple Availability Zones. This module ensures high availability, automatic scaling, and robust security for your applications.
Features
Application Load Balancer: Configures an ALB to distribute incoming HTTP and HTTPS traffic.
Target Group: Manages a target group for routing requests to one or more registered targets.
Listener: Sets up a listener to check for connection requests from clients and forwards them to the target group.
Security Group: Establishes a security group to control inbound and outbound traffic to the ALB.
Resources
1. Application Load Balancer (ALB)
Resources aws_lb
name: The name of the ALB.
internal: Specifies whether the ALB is internet-facing or internal, set to false.
load_balancer_type: Type of the load balancer, set to "application".
security_groups: List of security group IDs associated with the ALB.
subnets: List of subnet IDs where the ALB is deployed.
enable_deletion_protection: Boolean to enable/disable deletion protection.
description: The description of the security group.
vpc_id: The ID of the VPC where the security group is deployed.
ingress: Allows HTTP (port 80) and HTTPS (port 443) from any IP.
egress: Allows traffic only to specified CIDR blocks, in port 8080.
alb/main.tf
resource "aws_security_group""iac-project-alb-security-group"{name="iac-project-alb-security-group"description="Security group for the ALB"vpc_id= var.vpc_id
ingress{from_port=80to_port=80protocol="tcp"cidr_blocks=["0.0.0.0/0"]}ingress{from_port=443to_port=443protocol="tcp"cidr_blocks=["0.0.0.0/0"]}egress{from_port=8080to_port=8080protocol="tcp"cidr_blocks= var.ec2_cidr_blocks
}}
Variables and Outputs
The module uses several input variables to customize the deployment, such as: alb_name, public_subnet_id, alb_target_group_name, and others. These variables are defined in the variables.tf file and allow for flexible configuration of the VPC and its components. The module also provides outputs for the security group ID and target group ARN in the outputs.tf file, which can be used by other modules or resources within the infrastructure.
ASG Module
The ASG (Auto Scaling Group) module is designed to automatically manage the scaling of EC2 instances based on demand. This module ensures that the application remains available and can handle varying levels of traffic by dynamically adjusting the number of instances in response to load.
Features
Lauching template: Configures a launch template to define the instance configuration.
Auto Scaling Group: Manages the scaling of instances to maintain desired performance.
Security Groups: Establishes a security group to control inbound and outbound traffic for the instances.
Resources
1. Launch Template
Resource: aws_launch_template
name: The name of the launch template.
image_id: The ID of the AMI to use for the instances.
instance_type: The type of instance to use.
key_name: The name of the key for SSH access.
network_interface:
associate_public_ip_address: Whether to associate a public IP address with the instance, set to false.
security_groups: List of security group IDs to associate with the instances.
user_data: Base64-encoded script to initialize the instance.
The module uses several input variables to customize the deployment, such as: launch_template_name, image_id, instance_type, and others. These variables are defined in the variables.tf file and allow for flexible configuration of the VPC and its components. The module also provides outputs for the auto scaling group name and RDS security group ID in the outputs.tf file, which can be used by other modules or resources within the infrastructure.
RDS Module
The RDS (Relational Database Service) module is designed to provision and manage a relational database instance on AWS. This module simplifies the deployment of a database by handling the configuration of the database engine, storage, networking, and security settings, ensuring a robust and scalable database solution.
Features
RDS Instance: Provisions a database instance with specified engine and version.
Subnet Group: Configures a subnet group for the RDS instance to ensure high availability.
Security Group: Manages security groups to control access to the database.
Resources
1. RDS Instance
Resource: aws_rds_instance
identifier_prefix: A unique prefix for the RDS instance identifier.
engine: The database engine to use (e.g., MySQL, PostgreSQL).
engine_version: The version of the database engine.
instance_class: The instance class for the database engine.
allocated_storage: The amount of storage allocated to the database instance.
username: The master username for the database.
password: The master password for the database.
vpc_security_group_ids: List of security group IDs to associate with the RDS instance.
db_subnet_group_name: The subnet group name for the RDS instance.
skip_final_snapshot: Whether to skip the final snapshot when the database is deleted.
subnet_ids: List of subnet IDs to associate with the DB subnet group.
tags: Assigns a name tag to the subnet group for identification.
rds/main.tf
resource "aws_db_subnet_group""default"{name="mydb-subnet-group"subnet_ids= var.private_subnet_ids
tags={Name="My DB subnet group"}}
Variables and Outputs
The module uses several input variables to customize the deployment, such as: such as engine, engine_version, instance_class and others. These variables are defined in the variables.tf file and allow for flexible configuration of the VPC and its components. Additionally, the username and password variables must be defined as environment variables and not hardcoded, for security reasons.
Main File
The main.tf file serves as the central configuration for deploying and managing the infrastructure on AWS using Terraform. It orchestrates the setup of the modules and resources previously defined, ensuring that all components are correctly provisioned and interconnected to form a cohesive infrastructure environment.
Ensuring the integrity and correctness of the infrastructure code is crucial for successful deployments. Terraform provides several commands to help test and validate the configurations before applying them to your environment.
Terraform fmt
The terraform fmt command is used to format the Terraform configuration files consistently. It automatically updates the files to follow the standard Terraform style conventions, making the code more readable and maintainable.
Terraform validade
The terraform validate command checks the syntax and internal consistency of the Terraform configuration files. It ensures that the configuration is syntactically valid and that all required arguments are provided.
Terraform plan
The terraform plan command creates an execution plan, showing what actions Terraform will take to achieve the desired state of the infrastructure. This command provides a detailed preview of the changes that will be made, allowing you to review and confirm them before applying.
Deployment
After testing and validating the configuration, you can deploy the infrastructure using the terraform apply command. This command executes the changes defined in the Terraform files. It applies the planned changes to the actual infrastructure, creating or updating the resources as specified.