Infra as Code - Overview

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.

Github repository: https://github.com/samuelincoln1/infra-as-code

Architecture Diagram

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.

Architecture Diagram

Diagram created with Lucidchart: https://www.lucidchart.com/pages/landing

Code Structure

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.

Code Structure

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.
Backend Structure

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.

backend/main.tf

terraform {
    backend "s3" {
        # bucket = "samuellincoln-terraform-state"
        # key = "tf-infra/terraform.tfstate"  
        # region = "us-east-1"
        # dynamodb_table = "terraform-state-locking"
        # encrypt = true
    }

    required_providers {
        aws = {
            source = "hashicorp/aws"
            version = "~> 5.0"
        }
    }
}

provider "aws" {
    region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
    bucket = var.bucket_name
    force_destroy = true
}

resource "aws_s3_bucket_versioning" "terraform_state_versioning" {
    bucket = aws_s3_bucket.terraform_state.id
    versioning_configuration {
        status = "Enabled"
    }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state_encryption" {
    bucket = aws_s3_bucket.terraform_state.id
    rule {
        apply_server_side_encryption_by_default {
            sse_algorithm = var.sse_algorithm
        }
    }
}

resource "aws_dynamodb_table" "terraform_locks" {
    name = var.dynamodb_table_name
    billing_mode = var.billing_mode
    hash_key = var.hash_key
    attribute {
        name = var.attribute_name
        type = var.attribute_type
    }
}

The variables are defined in the variables.tf file and initialized in the backend.tfvars .

backend/backend.tfvars

bucket_name = "samuellincoln-iac-project-state"
sse_algorithm = "AES256"
dynamodb_table_name = "iac-project-state-locking"
billing_mode = "PAY_PER_REQUEST"
attribute_name = "LockID"
attribute_type = "S"
hash_key = "LockID"

VPC Module

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.

vpc/main.tf

resource "aws_vpc" "main" {
  cidr_block           = var.cidr_block
  enable_dns_hostnames = var.enable_dns_hostnames
  enable_dns_support   = var.enable_dns_support
  tags = {
    Name = "iac-project-vpc"
  }
}

2. Internet Gateway

  • Resource: aws_internet_gateway
    • vpc_id: The ID of the VPC to which the internet gateway is attached.
    • tags: Assigns a name tag to the internet gateway.

vpc/main.tf

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "iac-project-igw"
  }
}

3. Subnets

Public Subnets

  • Resource: aws_subnet
    • vpc_id: The ID of the VPC to which the subnet is associated.
    • cidr_block: The CIDR block for the subnet.
    • map_public_ip_on_launch: Enable to assign a public IP to instances launched in this subnet.
    • availability_zone: The availability zone for the subnet.
    • tags: Assigns a name tag to the subnet for identification.

Private Subnets

  • Resource: aws_subnet
    • vpc_id: The ID of the VPC to which the subnet is associated.
    • cidr_block: The CIDR block for the subnet.
    • map_public_ip_on_launch: Disable to assign a private IP to instances launched in this subnet.
    • availability_zone: The availability zone for the subnet.
    • tags: Assigns a name tag to the subnet for identification.

vpc/main.tf

resource "aws_subnet" "public-subnet-1" {
    vpc_id                  = aws_vpc.main.id
    cidr_block              = var.public_subnet_cidr_block_1
    map_public_ip_on_launch = var.map_public_ip_on_launch
    availability_zone       = var.availability_zone_1
    tags = {
      Name = "iac-project-public-subnet-1"
    }
  }
  
  resource "aws_subnet" "public-subnet-2" {
    vpc_id                  = aws_vpc.main.id
    cidr_block              = var.public_subnet_cidr_block_2
    map_public_ip_on_launch = var.map_public_ip_on_launch
    availability_zone       = var.availability_zone_2
    tags = {
      Name = "iac-project-public-subnet-2"
    }
  }
  
  
  resource "aws_subnet" "private-subnet-1" {
    vpc_id                  = aws_vpc.main.id
    cidr_block              = var.private_subnet_cidr_block_1
    map_public_ip_on_launch = false
    availability_zone       = var.availability_zone_1
    tags = {
      Name = "iac-project-private-subnet-1"
    }
  }
  resource "aws_subnet" "private-subnet-2" {
    vpc_id                  = aws_vpc.main.id
    cidr_block              = var.private_subnet_cidr_block_2
    map_public_ip_on_launch = false
    availability_zone       = var.availability_zone_2
    tags = {
      Name = "iac-project-private-subnet-2"
    }
  }
  
  resource "aws_subnet" "private-subnet-3" {
    vpc_id                  = aws_vpc.main.id
    cidr_block              = var.private_subnet_cidr_block_3
    map_public_ip_on_launch = false
    availability_zone       = var.availability_zone_2
    tags = {
      Name = "iac-project-private-subnet-3"
    }
  }

4. Route Tables

Public Route Table

  • Resource: aws_route_table
    • vpc_id: The ID of the VPC to which the route table is associated.
    • route: Includes a route for 0.0.0.0/0 through the internet gateway.
    • tags: Assigns a name tag to the route table for identification.

Private Route Table

  • Resource: aws_route_table
    • vpc_id: The ID of the VPC to which the route table is associated.
    • tags: Assigns a name tag to the route table for identification.

vpc/main.tf

resource "aws_route_table" "public-route-table" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "iac-project-public-route-table"
  }
}

resource "aws_route_table" "private-route-table" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "iac-project-private-route-table"
  }
}

5. Route Table Associations

  • Public Subnets: Associated with the public route table.
  • Private Subnets: Associated with the private route table.

vpc/main.tf

resource "aws_route_table_association" "public-route-table-association" {
  subnet_id      = aws_subnet.public-subnet-1.id
  route_table_id = aws_route_table.public-route-table.id
}

resource "aws_route_table_association" "public-route-table-association-2" {
  subnet_id      = aws_subnet.public-subnet-2.id
  route_table_id = aws_route_table.public-route-table.id
}


resource "aws_route_table_association" "private-route-table-association" {
  subnet_id      = aws_subnet.private-subnet-1.id
  route_table_id = aws_route_table.private-route-table.id
}

resource "aws_route_table_association" "private-route-table-association-2" {
  subnet_id      = aws_subnet.private-subnet-2.id
  route_table_id = aws_route_table.private-route-table.id
}

resource "aws_route_table_association" "private-route-table-association-3" {
  subnet_id      = aws_subnet.private-subnet-3.id
  route_table_id = aws_route_table.private-route-table.id
}

Variables and Outputs

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.

alb/main.tf

resource "aws_lb" "iac-project-alb" {
  name                       = var.alb_name
  internal                   = false
  load_balancer_type         = "application"
  security_groups            = [aws_security_group.iac-project-alb-security-group.id]
  subnets                    = [var.public_subnet_id, var.public_subnet_id_2]
  enable_deletion_protection = false
}

2. Target Group

  • Resource: aws_lb_target_group
    • name: The name of the target group.
    • port: The port on which the ALB forwards traffic to targets, set to 8080.
    • protocol: The protocol to use for routing traffic to the targets.
    • vpc_id: The ID of the VPC where the target group is deployed.
    • Health Check Configuration:
      • path: The destination for the health check request.
      • interval: Time between health checks.
      • timeout: Time to wait for a health check response.
      • healthy_threshold: Number of consecutive successful health checks required before considering a target healthy.
      • unhealthy_threshold: Number of consecutive failed health checks required before considering a target unhealthy.
      • matcher: HTTP codes to use when checking for a successful response.

alb/main.tf

resource "aws_lb_target_group" "iac-project-alb-target-group" {
  name     = var.alb_target_group_name
  port     = 8080
  protocol = var.alb_target_group_protocol
  vpc_id   = var.vpc_id

  health_check {
    path                = var.alb_target_group_health_check_path
    interval            = var.alb_target_group_health_check_interval
    timeout             = var.alb_target_group_health_check_timeout
    healthy_threshold   = var.alb_target_group_health_check_healthy_threshold
    unhealthy_threshold = var.alb_target_group_health_check_unhealthy_threshold
    matcher             = var.alb_target_group_health_check_matcher
  }
}

3. Listener

  • Resource: aws_lb_listener
    • load_balancer_arn: The ARN of the load balancer.
    • port: The port on which the ALB receives traffic, set to 80.
    • protocol: The protocol to use for routing traffic to the targets, set to "HTTP".
    • default_action: The default action to take when a request is received.
      • type: The type of the default action, set to "forward".
      • target_group_arn: The ARN of the target group to forward the traffic to.

alb/main.tf

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.iac-project-alb.arn
  port              = 80
  protocol          = "HTTP"
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.iac-project-alb-target-group.arn
  }
}

4. Security Group

  • Resource: aws_security_group
    • name: The name of the security group.
    • 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   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "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.

asg/main.tf

resource "aws_launch_template" "web-server-launch-template" {
  name          = var.launch_template_name
  image_id      = var.image_id
  instance_type = var.instance_type
  key_name      = var.key_name

  network_interfaces {
    associate_public_ip_address = false
    security_groups             = [aws_security_group.web-server-security-group.id]
  }

  user_data = base64encode(<<-EOF
              #!/bin/bash
              echo "Hello, World" > index.html
              nohup python3 -m http.server 8080 &
              EOF
  )
}

2. Auto Scaling Group

  • Resource: aws_autoscaling_group
    • name: The name of the auto scaling group.
    • max_size: Maximum number of instances.
    • min_size: Minimum number of instances.
    • desired_capacity: Desired number of instances.
    • vpc_zone_identifier: List of subnet IDs to associate with the auto scaling group.
    • target_group_arns: List of target group ARNs to associate with the ASG.

asg/main.tf

resource "aws_autoscaling_group" "web-server-autoscaling-group" {
  name                = var.autoscaling_group_name
  max_size            = var.max_size
  min_size            = var.min_size
  desired_capacity    = var.desired_capacity
  vpc_zone_identifier = var.vpc_zone_identifier
  launch_template {
    id = aws_launch_template.web-server-launch-template.id
  }
  target_group_arns = [var.target_group_arn]
}

3. Security Group

  • Web Server Security Group
    • Resource: aws_security_group
      • name: The name of the security group.
      • vpc_id: The ID of the VPC where the security group is deployed.
      • ingress: Allows HTTP on port 8080 from the ALB.
      • egress: Allows egress to CIDR blocks within the VPC.
    • RDS Security Group
    • Resource: aws_security_group
      • name: The name of the security group.
      • vpc_id: The ID of the VPC where the security group is deployed.
      • ingress: Allows traffic from the web-server security group.
      • egress: Allows outbound traffic to any destination.

asg/main.tf

resource "aws_security_group" "web-server-security-group" {
  name   = "iac-project-web-server-security-group"
  vpc_id = var.vpc_id
  ingress {
    from_port       = 8080
    to_port         = 8080
    protocol        = "tcp"
    security_groups = [var.alb_security_group_id]
  }

  egress {
    from_port   = 3306
    to_port     = 3306
    protocol    = "tcp"
    cidr_blocks = [var.rds_cidr_block]
  }

  tags = {
    Name = "instances-security-group"
  }
}

resource "aws_security_group" "rds-security-group" {
  name   = "iac-project-rds-security-group"
  vpc_id = var.vpc_id
  ingress {
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.web-server-security-group.id]
  }

  egress {
    from_port       = 0
    to_port         = 0
    protocol        = "-1"
    security_groups = [aws_security_group.web-server-security-group.id]
  }
}

Variables and Outputs

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.

rds/main.tf

resource "aws_db_instance" "iac-project-rds" {
  identifier_prefix      = "iac-project-rds"
  engine                 = var.engine
  engine_version         = var.engine_version
  instance_class         = var.instance_class
  allocated_storage      = var.allocated_storage
  username               = var.db_username
  password               = var.db_password
  port                   = var.port
  vpc_security_group_ids = var.rds_security_group_ids
  db_subnet_group_name   = aws_db_subnet_group.default.name
  skip_final_snapshot    = var.skip_final_snapshot
}

2. DB Subnet Group

  • Resource: aws_db_subnet_group
    • name: The name of the DB subnet group.
    • 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.

main.tf

terraform {
  backend "s3" {
    bucket         = "samuellincoln-iac-project-state"
    key            = "tf-infra/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "iac-project-state-locking"
    encrypt        = true
  }
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

module "vpc" {
  source                      = "./modules/vpc"
  cidr_block                  = "10.0.0.0/16"
  enable_dns_hostnames        = false
  enable_dns_support          = true
  public_subnet_cidr_block_1  = "10.0.1.0/24"
  public_subnet_cidr_block_2  = "10.0.2.0/24"
  map_public_ip_on_launch     = true
  availability_zone_1         = "us-east-1a"
  availability_zone_2         = "us-east-1b"
  private_subnet_cidr_block_1 = "10.0.3.0/24"
  private_subnet_cidr_block_2 = "10.0.4.0/24"
  private_subnet_cidr_block_3 = "10.0.5.0/24"
}

module "alb" {
  source                                            = "./modules/alb"
  vpc_id                                            = module.vpc.vpc_id
  public_subnet_id                                  = module.vpc.public_subnet_id_1
  public_subnet_id_2                                = module.vpc.public_subnet_id_2
  alb_name                                          = "iac-project-alb"
  alb_target_group_name                             = "iac-project-alb-target-group"
  alb_target_group_port                             = 80
  alb_target_group_protocol                         = "HTTP"
  alb_target_group_health_check_path                = "/"
  alb_target_group_health_check_interval            = 30
  alb_target_group_health_check_timeout             = 10
  alb_target_group_health_check_healthy_threshold   = 2
  alb_target_group_health_check_unhealthy_threshold = 2
  alb_target_group_health_check_matcher             = "200-399"
  ec2_cidr_blocks                                   = [module.vpc.private_subnet_cidr_block_3]
}

module "asg" {
  source                 = "./modules/asg"
  vpc_id                 = module.vpc.vpc_id
  launch_template_name   = "web-server-launch-template"
  image_id               = "ami-011899242bb902164"
  instance_type          = "t2.micro"
  key_name               = "aws-server"
  autoscaling_group_name = "web-server-autoscaling-group"
  max_size               = 4
  min_size               = 2
  desired_capacity       = 2
  vpc_zone_identifier    = [module.vpc.private_subnet_id_1, module.vpc.private_subnet_id_2]
  target_group_arn       = module.alb.target_group_arn
  alb_security_group_id  = module.alb.security_group_id
  rds_cidr_block         = "10.0.0.0/16"
}


module "rds" {
  source                 = "./modules/rds"
  engine                 = "mysql"
  engine_version         = "8.4.4"
  instance_class         = "db.t3.micro"
  allocated_storage      = 20
  port                   = 3306
  rds_security_group_ids = [module.asg.rds-security-group-id]
  skip_final_snapshot    = true
  private_subnet_ids     = [module.vpc.private_subnet_id_1, module.vpc.private_subnet_id_2, module.vpc.private_subnet_id_3]
  db_username            = var.db_username
  db_password            = var.db_password
}

Tests

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.