What is Terraform and How to perform Autoscaling using terrform

Posted By :Baldev Pal |20th April 2021

 

 

Autoscalling Using Terraform

 

What is Terraform:

       i. Terraform is an open-source tool and supports multiple clouds.

      ii. It covers almost all services and features provided by AWS and other cloud providers.

      iii. With the help of Terraform we can codify our infrastructure. Infrastructure means our components like EC2, LB, VPC, Autoscaling, RT, etc.

 

What is the provider:

    i. Provider selection depends upon what kind of infrastructure you want to create, you have to select that provider.

   ii. For example. I will create AWS infrastructure have to choose a provider as an AWS.

   iii. With the provider, we need to add the tokens(secret key && access key ) or username & password which will be used for authentication.

   iv. The syntax for defining provider in Terraform.

                                   Provider “aws”{

                                                 .....................................

                                                .....................................

                                                             }

 

What is the resource:

       i. Whatever we want to create/delete/update the infrastructure through terraform needs to be defined in

          the resource block.

      ii. Resources are the components of our infrastructure.

      iii. In each resource block, you will describe one or more infrastructure objects, such as virtual network,

           compute instance, or higher-level components such as DNS records.

     iv. Each resource belongs to a provider, and the type of the resource is suffixed with the provider's name.

     v. Syntax:   resource “provider-name_resource-type” “local-name”{

                                                                                                        .........................................................

                                                                                                        .........................................................

                                                                                                                 }

 

What are the Modules:

       The module is the container for the multiple resources that are used to combine together.

         It can be used to create a light-weight abstraction so that you can describe your infrastructure in terms of its

        architecture, rather than directly in terms of a physical object     

 

What is terraform init:

   i. Terraform init command will download required plugins and initialize the providers.

    ii. With the command of terraforming init, we can initialize all resource, provider, modules and contain the terraform configuration file.

 

What is Terraform plan:

   i. The plan shows what will happen.

   ii. you can save plans to guarantee the predictions.

   iii. Plan show the reason for a certain action (such as recreate)

   iv + Indicates a resource will be created.

   v - Indicates a resource will be destroyed.

   vi. ~ Indicates a resource will be updated in the plan.

   Vii. -/+ Indicates a resource will be destroyed and re-created.

 

What is terraform apply:

   i. Eixeute changes to reach the desired state.

   ii. Parallelism changes when possible.

   iii. Update Existing resources when updates are allowed.

   iv. Re-creates existing resources when an update is not allowed

 

What is Autoscaling:

     i. Creating a group of EC2 instances that can scale up or down depending on conditions you set.

     ii. Autoscaling helps you save cost by cutting down the number of ec2 instances when note needed and scaling out to add more instances only when it is required.

     iii. Autoscaling ensures that you have the right number of AWS ec2 instances for you needs at all time.

 

Autoscaling Components:

    i. Launch configuration: Like Instance type, AMI keypair security group.

   ii. Autoscaling Group: Group name, Group size, VPC, Subnet, Health Check Period.

   iii. Scaling Policy: Metric type, Target value.

 

Create Autoscaling using Terraform Script.

Step1. Create autoscaling.tf file.

      $ nano autoscaling.tf 

 

resource "aws_launch_configuration" "Launch_config" {                        
  name = var.Name1                                                           
  image_id = var.image_id                                                    
  instance_type = var.instance_type                                          
  security_groups = [aws_security_group.security_group-Launch_config.id]     
  key_name = var.Launch-config-name                                          
}                                                                            
resource "aws_autoscaling_group" "autoscal_group" {                          
  launch_configuration = aws_launch_configuration.Launch_config.name         
  vpc_zone_identifier = [var.public_subnet1,var.public_subnet2]              
  health_check_grace_period = var.Autoscal-group-health_check                
  desired_capacity = var.Autoscal-group-desired_capacity                     
  force_delete = var.Autoscal-group-force_delete                             
  max_size = var.Autoscal-group-max_size                                     
  min_size = var.Autoscal-group-min_size                                     
  tag {                                                                      
    key = var.Autoscal-group-tag_key                                         
    value = var.Autoscal-group-tag_value                                     
    propagate_at_launch = var.Autoscal-group-tag_propagate_at_launch         
  }                                                                          
}                                                                            
#cpu scale-up policy                                                         
resource "aws_autoscaling_policy" "autoscale_up" {                           
  autoscaling_group_name = aws_autoscaling_group.autoscal_group.name         
  name = var.autoscale_up-name                                               
  scaling_adjustment = var.autoscale_up-scaling_adjustment                   
  adjustment_type = var.autoscale_up-adjustment_type                         
  cooldown = var.autoscale_up-cooldown                                       
  policy_type = var.autoscale_up-policy_type                                 
}                                                                            
resource "aws_cloudwatch_metric_alarm" "up" {                                
  alarm_name = var.cloudwatch_metric_alarm-up-alarm_name                     
  alarm_description = var.cloudwatch_metric_alarm-up-alarm_description       
  comparison_operator = var.cloudwatch_metric_alarm-up-comparison_operator   
  evaluation_periods = var.cloudwatch_metric_alarm-up-evaluation_periods     
  metric_name = var.cloudwatch_metric_alarm-up-metric_name                   
  namespace = var.cloudwatch_metric_alarm-up-namespace                       
  period = var.cloudwatch_metric_alarm-up-period                             
  threshold = var.cloudwatch_metric_alarm-up-threshold                       
  statistic = var.cloudwatch_metric_alarm-up-statistic                       
  dimensions = {                                                             
    AutoScalingGroupName = aws_autoscaling_group.autoscal_group.name         
  }                                                                          
  actions_enabled = var.cloudwatch_metric_alarm-up-actions_enabled           
  alarm_actions = [aws_autoscaling_policy.autoscale_up.arn]                  
}                                                                            
#cpu scale-down policy                                                       
resource "aws_autoscaling_policy" "autoscale_down" {                         
    name = var.autoscale_down-name                                           
    scaling_adjustment = var.autoscale_down-scaling_adjustment               
    adjustment_type = var.autoscale_down-adjustment_type                     
    cooldown = var.autoscale_down-cooldown                                   
    autoscaling_group_name = aws_autoscaling_group.autoscal_group.name       
    policy_type = var.autoscale_down-policy_type                             
}                                                                            
resource "aws_cloudwatch_metric_alarm" "down" {                              
  alarm_name = var.cloudwatch_metric_alarm-down-alarm_name                   
  comparison_operator = var.cloudwatch_metric_alarm-down-comparison_operator 
  evaluation_periods = var.cloudwatch_metric_alarm-down-evaluation_periods   
  metric_name = var.cloudwatch_metric_alarm-down-metric_name                 
  namespace = var.cloudwatch_metric_alarm-down-namespace                     
  period = var.cloudwatch_metric_alarm-down-period                           
  statistic = var.cloudwatch_metric_alarm-down-statistic                     
  threshold = var.cloudwatch_metric_alarm-down-threshold                     
  dimensions = {                                                             
    AutoScalingGroupName = aws_autoscaling_group.autoscal_group.name         
  }                                                                          
  actions_enabled = var.cloudwatch_metric_alarm-down-actions_enabled         
  alarm_actions = [aws_autoscaling_policy.autoscale_down.arn]                
}                                                                            
resource "aws_security_group" "security_group-Launch_config" {               
  name = var.security_group-Launch_config-name                               
  vpc_id = var.vpc_id                                                        
  # http                                                                     
  ingress {                                                                  
    # What range of ports are we opening up?                                 
    from_port = var.ingress-http-from_port                                   
    to_port = var.ingress-http-to_port                                       
    protocol = var.ingress-http-protocol                                     
    cidr_blocks = ["0.0.0.0/0"] # who can access it? The world!              
  }                                                                          
                                                                             
  # SSH                                                                      
  ingress {                                                                  
    from_port = var.ingress-ssh-from_port                                    
    to_port = var.ingress-ssh-to_port                                        
    protocol = var.ingress-ssh-protocol                                      
    description = var.ingress-ssh-description                                
    cidr_blocks = ["0.0.0.0/0"]                                              
  }                                                                          
                                                                             
  # Outgoing traffic                                                         
  egress {                                                                   
    from_port       = var.egress-from_port                                   
    to_port         = var.egress-to_port                                     
    protocol        = var.egress-protocol                                    
    cidr_blocks     = ["0.0.0.0/0"]                                          
  }                                                                          
}                                                                            
        

Step2: Create Variable.tf file.

$ nano var.tf   

variable "Name1" {                                                           
  default = "Launch-config-1"                                                
}                                                                            
variable "image_id" {                                                        
  default = "ami-013f17f36f8b1fefb"                                          
}                                                                            
variable "instance_type" {}                                                  
variable "vpc_id" {}                                                         
variable "public_subnet1" {}                                                 
variable "public_subnet2" {}                                                 
variable "Launch-config-name" {                                              
  default = "hello"                                                          
}                                                                            
variable "Autoscal-group-health_check" {                                     
  default = "50"                                                             
}                                                                            
variable "Autoscal-group-desired_capacity" {                                 
  default = "2"                                                              
}                                                                            
variable "Autoscal-group-force_delete" {                                     
  default = "true"                                                           
}                                                                            
variable "Autoscal-group-max_size" {                                         
  default = "4"                                                              
}                                                                            
variable "Autoscal-group-min_size" {                                         
  default = "2"                                                              
}                                                                            
variable "Autoscal-group-tag_key" {                                          
  default = "Autoscaling"                                                    
}                                                                            
variable "Autoscal-group-tag_value" {                                        
  default = "ec2-instance"                                                   
}                                                                            
variable "Autoscal-group-tag_propagate_at_launch" {                          
  default = "true"                                                           
}                                                                            
variable "autoscale_up-name" {                                               
  default = "autoscale_up"                                                   
}                                                                            
variable "autoscale_up-scaling_adjustment" {                                 
  default = "1"                                                              
}                                                                            
variable "autoscale_up-adjustment_type" {                                    
  default = "ChangeInCapacity"                                               
}                                                                            
variable "autoscale_up-cooldown" {                                           
  default = "50"                                                             
}                                                                            
variable "autoscale_up-policy_type" {                                        
  default = "SimpleScaling"                                                  
}                                                                            
variable "cloudwatch_metric_alarm-up-alarm_name" {                           
  default = "cpu-alarm-up"                                                   
}                                                                            
variable "cloudwatch_metric_alarm-up-alarm_description" {                    
  default = "cpu-alarm-policy"                                               
}                                                                            
variable "cloudwatch_metric_alarm-up-comparison_operator" {                  
  default = "GreaterThanOrEqualToThreshold"                                  
}                                                                            
variable "cloudwatch_metric_alarm-up-evaluation_periods" {                   
  default = "2"                                                              
}                                                                            
variable "cloudwatch_metric_alarm-up-metric_name" {                          
  default = "CPUUtilization"                                                 
}                                                                            
variable "cloudwatch_metric_alarm-up-namespace" {                            
  default = "AWS/EC2"                                                        
}                                                                            
variable "cloudwatch_metric_alarm-up-period" {                               
  default = "60"                                                             
}                                                                            
variable "cloudwatch_metric_alarm-up-threshold" {                            
  default = "80"                                                             
}                                                                            
variable "cloudwatch_metric_alarm-up-statistic" {                            
  default = "Average"                                                        
}                                                                            
 variable "cloudwatch_metric_alarm-up-actions_enabled" {                     
   default = "true"                                                          
 }                                                                           
variable "autoscale_down-name" {                                             
  default = "autoscale-down"                                                 
}                                                                            
variable "autoscale_down-scaling_adjustment" {                               
  default = "-1"                                                             
}                                                                            
variable "autoscale_down-adjustment_type"{                                   
default = "ChangeInCapacity"                                                 
}                                                                            
variable "autoscale_down-cooldown" {                                         
  default = "50"                                                             
}                                                                            
variable "autoscale_down-policy_type" {                                      
default = "SimpleScaling"                                                    
}                                                                            
variable "cloudwatch_metric_alarm-down-alarm_name"{                          
default = "cpu-alarm-down"                                                   
}                                                                            
variable "cloudwatch_metric_alarm-down-comparison_operator"{                 
default = "LessThanOrEqualToThreshold"                                       
}                                                                            
variable "cloudwatch_metric_alarm-down-evaluation_periods" {                 
  default = "3"                                                              
}                                                                            
variable "cloudwatch_metric_alarm-down-metric_name" {                        
  default = "CPUUtilization"                                                 
}                                                                            
variable "cloudwatch_metric_alarm-down-namespace" {                          
  default = "AWS/EC2"                                                        
}                                                                            
variable "cloudwatch_metric_alarm-down-period" {                             
  default = "60"                                                             
}                                                                            
variable "cloudwatch_metric_alarm-down-statistic" {                          
  default = "Average"                                                        
}                                                                            
variable "cloudwatch_metric_alarm-down-threshold" {                          
  default = "80"                                                             
}                                                                            
variable "cloudwatch_metric_alarm-down-actions_enabled" {                    
  default = "true"                                                           
}                                                                            
variable "security_group-Launch_config-name" {                               
  default = "security_group-Launch_config"                                   
}                                                                            
variable "ingress-http-from_port" {                                          
  default = "80"                                                             
}                                                                            
variable "ingress-http-to_port" {                                            
  default = "80"                                                             
}                                                                            
variable "ingress-http-protocol" {                                           
  default = "tcp"                                                            
}                                                                            
variable "ingress-ssh-from_port" {                                           
  default = "22"                                                             
}                                                                            
variable "ingress-ssh-to_port" {                                             
  default = "22"                                                             
}                                                                            
variable "ingress-ssh-protocol" {                                            
  default = "tcp"                                                            
}                                                                            
variable "ingress-ssh-description" {                                         
  default = "SSH"                                                            
}                                                                            
variable "egress-from_port" {                                                
  default = "0"                                                              
}                                                                            
variable "egress-to_port" {                                                  
  default = "0"                                                              
}                                                                            
variable "egress-protocol" {                                                 
  default = "-1"                                                             
}                                                                            

 

Step3. Create OutPut.tf file.

$ nano output.tf

output "launch-config" {                                                     
  value = "${aws_launch_configuration.Launch_config.name}"                   
}                                                                            
output "autoscal_group" {                                                    
  value = "${aws_autoscaling_group.autoscal_group.name}"                     
}                                                                            
output "autoscale_up" {                                                      
  value = "${aws_autoscaling_policy.autoscale_up.name}"                      
}                                                                            
output "autoscale_down" {                                                    
  value = "${aws_autoscaling_policy.autoscale_down.name}"                    
}                                                                            

Step4: The Create Main.tf file.

# nano main.tf

 

provider "aws" {                                                             
  region = var.region                                                        
   access_key = var.access_key                                               
  secret_key = var.secret_key                                                
                                                                             
}                                                                            
                                                                             
module "VPC" {                                                               
  source          = "../VPC"                                                 
  vpc_cidr        = var.vpc_cidr                                             
  public_cidrs    = var.public_cidrs                                         
  private_cidrs   = var.private_cidrs                                        
  cidr_blocks    = var.cidr_blocks                                           
}                                                                            
module "autoscalling" {                                                      
  source = "../AutoScalling"                                                 
  image_id = "ami-0bdd2a6d19092a117"                                         
  instance_type = var.instance_type                                          
  vpc_id = module.VPC.vpc_id                                                 
  public_subnet1 = module.VPC.public_subnet1                                 
  public_subnet2 = module.VPC.public_subnet2                                 
}                                                                            

Step5:Create Variable.tf file.

$ nano var.tf

 

variable "region" {                                                          
  default = "us-east-1"                                                      
}                                                                            
variable "access_key" {                                                      
  default = "AKIA52TM6V26IT6ANIRQ"                                           
}                                                                            
variable "secret_key" {                                                      
  default = "AE8jYGMphT/U7h/Nb0wcybDsOFIBDAeICeeinpL1"                       
}                                                                            
variable "instance_type" {                                                   
        default = "t2.micro"                                                 
}                                                                            
variable "vpc_cidr" {                                                        
  default = "10.0.0.0/16"                                                    
}                                                                            
variable "public_cidrs" {                                                    
  default = ["10.0.1.0/24","10.0.2.0/24"]                                    
}                                                                            
variable "private_cidrs" {                                                   
  default = ["10.0.3.0/24","10.0.4.0/24"]                                    
}                                                                            
variable "ami_id" {                                                          
  default = " ami-013f17f36f8b1fefb"                                         
}                                                                            
variable "cidr_blocks" {                                                     
  default = "0.0.0.0/0"                                                      
}                                                                            

Step6: Now after writing the script on Terraform some command has to be run 

      $ terraform init

      $ terraform plan

      $ terraform apply

 

 

 


About Author

Baldev Pal

Baldev is a DevOps Engineer. He has Knowledge of Linux, AWS, Docker, Jenkins, Kubernetes, Terraform, and Git.

Request For Proposal

[contact-form-7 404 "Not Found"]

Ready to innovate ? Let's get in touch

Chat With Us