Deploying a 3-Tier AWS VPC Architecture Using Terraform

#15
Topic created · 1 Posts · 27 Views
  • Prerequisites: Terraform locally installed, AWS account with AWS CLI configured, IDE (VSCode, Atom, etc.) with Terraform installed.

    This project was completed in Visual Studio Code. By using an IDE, you may find it easier to format properly, and having the language preset to Terraform (along with autocompletion, etc.).

    Step 1: Deploy a VPC with CIDR 10.0.0.0/16 with 2 public subnets and 1 private subnet. The public subnets have CIDR 10.0.1.0/24 and 10.0.2.0/24. The private subnet has a CIDR of 10.0.3.0/24.

    Step 2: Create an RDS MySQL Instance (t3.micro).

    Step 3: Create a Load Balancer that directs traffic to the public subnets.

    In Visual Studio Code (or your preferred IDE), create a working folder with three .tf files inside: main.tf, outputs.tf, and versions.tf.

    Step 1: Deploy VPC with CIDR 10.0.0.0/16

    In main.tf, state the provider in the first block, then create a module block for the VPC.

    **provider** "aws" {  
    region = "us-west-1"  
    }
    
    **module** "vpc" {  
    source = "terraform-aws-modules/vpc/aws"  
    name = "17vpc"  
    cidr = "10.0.0.0/16"
    

    Step 2: Add 2 public subnets with CIDR’s 10.0.1.0/24 and 10.0.2.0/24. Add private subnet with CIDR 10.0.3.0/24

    azs             = ["us-west-1a", "us-west-1b"]  
    public\_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]  
    private\_subnets = ["10.0.3.0/24"]
    


    This is what the main.tf file should look like with all the above commands put together.

    Complete the module block with the below code and run a terraform init, terraform fmt, terraform plan, and terraform apply.

    enable\_ipv6 = true
    
    enable\_nat\_gateway = false  
    single\_nat\_gateway = true
    
    public\_subnet\_tags = {  
    Name = "Public-Subnets"  
    }
    
    tags = {  
    Owner       = "user"  
    Environment = "dev"  
    }
    
    vpc\_tags = {  
    Name = "W17VPC"
    
    }
    
    }
    


    Final module block.

    Step 3: Create an RDS MySQL Instance with t3.micro

    _\# Create a database server_
    
    **resource** "aws\_db\_instance" "default" {  
    allocated\_storage = 5  
    engine         = "mysql"  
    engine\_version = "8.0.20"  
    instance\_class = "db.t3.micro"  
    name           = "initial\_db"  
    username       = "<your-aws-username"  
    password       = "<your-aws-password"  
    }
    


    MySQL Database Block

    Step 4: Create a load balancer that will direct traffic to the public subnets

    _\# Create an Network Load Balancer_
    
    **resource** "aws\_lb" "NLB17" {  
    name = "NLB17"  
    internal = false  
    load\_balancer\_type = "network"  
    subnets = ["<your-public-subnet-here>", "<your-public-subnet-here>"]  
    enable\_deletion\_protection = false #true if you are not planning on destroying your load balancer  
    }
    


    Network Load Balancer Block

    In the outputs.tf file, insert the below code:

    _\# VPC_
    
    **output** "vpc\_id" {  
    description = "The ID of the VPC"  
    value       = module.vpc.vpc\_id  
    }
    
    _\# CIDR blocks_
    
    **output** "vpc\_cidr\_block" {  
    description = "The CIDR block of the VPC"  
    value       = module.vpc.vpc\_cidr\_block  
    }
    
    _\# Subnets_
    
    **output** "private\_subnets" {  
    description = "List of IDs of private subnets"  
    value       = module.vpc.private\_subnets  
    }
    
    **output** "public\_subnets" {  
    description = "List of IDs of public subnets"  
    value       = module.vpc.public\_subnets  
    }
    
    _\# NAT gateways_
    
    **output** "nat\_public\_ips" {  
    description = "List of public Elastic IPs created for AWS NAT Gateway"  
    value       = module.vpc.nat\_public\_ips  
    }
    
    _\# AZs_
    
    **output** "azs" {  
    description = "A list of availability zones spefified as argument to this module"  
    value       = module.vpc.azs  
    }
    

    In the versions.tf file, input the below code:

    **terraform** {
    
    required\_version = ">= 0.12.26"
    
    **required\_providers** {  
    aws = {  
    source  = "hashicorp/aws"  
    version = ">= 3.15"  
    }  
    }  
    }
    

    Now run a terraform init, terraform fmt, terraform plan, and finally, a terraform apply. Applies may take several minutes, so be patient with the process.

    Let’s check to see how our AWS Account looks!


    VPC created with correct CIDR!

    2 public and 1 private subnet created with correct CIDR’s!

    MySQL RDS Database created!

    Load Balancer created!

    Now that all of our tasks are successfully completed, it is time to destroy our module, and double check our AWS account is clean and free from being charged in the future! In VSCode Terminal, perform a terraform destroy (may take several minutes to complete).

    Great work! Thanks for following along with me. Be sure to connect with me on LinkedIn — linkedin.com/in/helenccampbell

Log in to reply