Skip to main content

Command Palette

Search for a command to run...

Terraform Day 8: Project: Modularized Infrastructure Setup

Updated
β€’4 min read
Terraform Day 8: Project: Modularized Infrastructure Setup
K

"Hello, I'm Kiran Pawar, a passionate Cloud and Devops Engineer with a strong background in cloud automation, configuration, and deployment. My journey in the world of technology has been a thrilling adventure, where I've had the privilege to work with cutting-edge tools and practices.

πŸš€ As a DevOps Engineer:

I specialize in automating, configuring, and deploying instances in cloud environments and data centers. My expertise extends to DevOps, GitOps, CI/CD pipeline management, HashiCorp Terraform, and containerization. I'm proficient in AWS and Linux/Unix administration, ensuring robust infrastructure and application performance.

πŸ”§ My Tech Stack:

Front-end skills: HTML, CSS, SCSS, Tailwind CSS, Bootstrap, React, Material-UI, JavaScript DevOps toolbox: GIT, OWASP,Nexus,Trivy, Github, Gitlab, Terraform, Ansible, Docker, Kubernetes, Helm, Jenkins, Prometheus, Grafana, Argo CD, AWS EKS.

🌐 My Cloud Expertise:

I have hands-on experience managing AWS services, including EC2, S3, EBS, VPC, ELB, RDS, IAM, Route53, and more.

πŸ”’ Networking and Security:

My skills include managing networking concepts such as TCP/IP protocols, security policies, and subnet interfacing. I have a strong understanding of infrastructure and networking, covering topics like firewalls, IP addressing, DNS, and more.

πŸ’‘ What Sets Me Apart:

I bring a positive attitude, a strong work ethic, and a collaborative spirit to every project. I'm a self-starter, a fast learner, and an effective team player with strong interpersonal skills. In addition to my DevOps skills, I've developed shell scripts (Bash) for automating tasks and have proficiency in Python scripting. My ability to communicate and manage projects, along with a track record of resolving client issues, adds value to every team I work with. If you're looking for a DevOps engineer who is also well-versed in front-end technologies, feel free to connect with me. Let's explore new possibilities and create exceptional technical solutions together!"

This Blog demonstrates how to modularize Terraform code for a scalable, manageable infrastructure deployment across multiple environments (e.g., dev, QA, production). The key idea is to break down the Terraform code into modules for various infrastructure components like networking, compute, security groups, load balancers, and NAT gateways. This modular approach minimizes manual changes and overhead when switching between environments.

Problem Overview

In typical infrastructure deployments, environments like dev, QA, and production might have different requirements (e.g., dev doesn’t need a load balancer or Route53). Managing these differences with a single Terraform codebase can lead to manual changes, which is inefficient. By breaking the code into modules, you can dynamically include/exclude components based on environment requirements, making the infrastructure easier to manage.

Solution

We break the infrastructure into the following modules:

  • Network: VPC, subnets, routing

  • Compute: EC2 instances (public and private)

  • Security Groups (SG): For securing VPC resources

  • NAT: NAT gateway for private instance internet access

  • ELB: Elastic Load Balancers (optional)

  • IAM: Identity and Access Management

Folder Structure

/modules
  β”œβ”€β”€ network
  β”œβ”€β”€ compute
  β”œβ”€β”€ sg
  β”œβ”€β”€ nat
  β”œβ”€β”€ elb
  β”œβ”€β”€ iam
/development
  β”œβ”€β”€ main.tf
  β”œβ”€β”€ infra.tf
  β”œβ”€β”€ sg.tf
  β”œβ”€β”€ variables.tf
  β”œβ”€β”€ terraform.tfvars
  └── ec2.tf
/production
  β”œβ”€β”€ main.tf
  β”œβ”€β”€ infra.tf
  β”œβ”€β”€ sg.tf
  β”œβ”€β”€ variables.tf
  β”œβ”€β”€ terraform.tfvars
  └── ec2.tf

Step-by-Step Setup

1. Create Network Module

  1. Files in /modules/network:

    • vpc.tf: Defines the VPC and internet gateway.

    • public_subnets.tf: Public subnets configuration.

    • private_subnets.tf: Private subnets configuration.

    • routing.tf: Routing tables for public and private subnets.

    • variables.tf: Define necessary input variables.

    • output.tf: Export important values (e.g., VPC ID, subnet IDs).

    • local.tf: Set local values for environment or naming conventions

      .

  2. Import Network Module in Development:

    • In /development/infra.tf, import the network module:

        module "dev_vpc_1" {
          source             = "../modules/network"
          vpc_cidr           = "10.0.0.0/16"
          vpc_name           = "dev_vpc_1"
          environment        = "developement"
          public_cird_block  = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
          private_cird_block = ["10.0.10.0/24", "10.0.20.0/24", "10.0.30.0/24"]
          azs                = ["us-east-1a", "us-east-1b", "us-east-1c"]
        }
      
  3. Deploy the Network Module:

     cd development
     terraform init
     terraform fmt
     terraform validate
     terraform apply
    

2. Configure for Production

  • Copy Files: Copy the infrastructure setup from development to production.

    • Ensure variable values are updated (e.g., CIDR blocks should not overlap between environments).
  • Customize Values: Modify terraform.tfvars and variables.tf in the production folder to match production settings (e.g., CIDR range, environment = "production").

cd production
terraform init
terraform fmt
terraform apply

3. Add Security Groups Module

  1. Create /modules/sg:

    • sg.tf: Security group configurations.

    • variables.tf: Define necessary input variables.

    • outputs.tf: Export security group IDs.

  2. Import in Development:

    • Add the security group module to development's sg.tf:

        module "dev_sg_1" {
          source        = "../modules/sg"
          vpc_name      = module.dev_vpc_1.vpc_name
          vpc_id        = module.dev_vpc_1.vpc_id
          environment   = module.dev_vpc_1.environment
          service_ports = ["80", "443", "445", "8080", "22", "3389"]
        }
      
  3. Deploy SG Module:

     cd development
     terraform get
     terraform apply
    
  4. Replicate for Production: Similarly, copy the security group module to production, making necessary adjustments

    .

4. EC2 (Compute) Module

  1. Create /modules/compute:

    • private_ec2.tf: For private EC2 instances.

    • public_ec2.tf: For public EC2 instances.

    • variables.tf: Define EC2-related variables.

    • output.tf: Export EC2 instance IDs or other resources

      .

  2. Deploy in Development: Add EC2 configuration in development/ec2.tf, referencing the module:

     module "dev_compute_1" {
       source      = "../modules/compute"
       environment = module.dev_vpc_1.environment
       amis = {
         us-east-1 = "ami-04505e74c0741db8d" # ubuntu 20.04 LTS
         us-east-2 = "ami-04505e74c0741db90" # ubuntu 20.04 LTS
       }
       aws_region    = var.aws_region
       instance_type = "t2.micro"
       key_name      = "devops"
       public_subnet  = module.dev_vpc_1.public-subnet
       private_subnet = module.dev_vpc_1.private-subnet
       sg_id          = module.dev_sg_1.sg_id
       vpc_name       = module.dev_vpc_1.vpc_name
     }
    

  3. Replicate for Production: Follow the same process for production, customizing as needed.

5. NAT Gateway Module

  1. Create /modules/nat:

    • natgw.tf: Defines the NAT gateway.

    • variables.tf: Input variables like subnet ID.

    • outputs.tf: Export NAT gateway ID

      .

  2. Deploy NAT in Development and Production:

    • Ensure the NAT module is added in both environments, with appropriate changes in terraform.tfvars

      .

Final Steps

  • Destroy: To clean up, run the following in both environments:

      cd production
      terraform destroy -auto-approve
      cd development
      terraform destroy -auto-approve
    

Notes on Output Values

The output.tf files in each module play a crucial role in passing data between modules. For example, the VPC module exports the vpc_id, which is consumed by the Security Group module and EC2 module. This modular approach helps ensure that all components are properly linked, and their dependencies are clear.

Conclusion

This repository demonstrates how to efficiently manage and deploy infrastructure across multiple environments using Terraform modules. By breaking infrastructure code into reusable modules, we reduce complexity, manual work, and potential errors, leading to a more scalable and maintainable solution.

Mastering Terraform

Part 2 of 9

This series dives deep into mastering Infrastructure as Code (IaC) with Terraform, starting from the basics and advancing to real-world implementations. Whether you're a beginner or looking to refine your skills.

Up next

Terraform Day 7: Terraform Functions Part: 2

This Blog demonstrates the usage of various Terraform functions such as lookup, count, and condition, along with implementing file provisioners (remote-exec, local-exec). The goal is to dynamically manage infrastructure using variables, conditional l...

More from this blog

Kiran Pawar's Blog

122 posts