~Launching Instances using an Auto Scaling Group with Terraform~

Asonti Ginn
Women in Technology

--

Today's Goals:

~ Create a S3 Bucket and set the bucket as the backend.

~ Create a new security group and attach it to the auto scaling group and launch template.

~ Have the Auto Scaling group span 2 subnets, have a max of 5 instances, and minimum of 2 instances.

Key Terms:

~ Terraform: Hashicorp Language that uses Infrastructure as Code and works with different providers to create resources, such as AWS.

~EC2 Instance: Stands for Elastic Compute Cloud which is a virtual server inside the AWS Cloud.

~ Sudo: Allows you to run commands as if you are the root user in a terminal.

~Auto Scaling Group: Helps you manage and scale the number of instances you need by implying the maximum and minimum amount of instances you want.

~Launch Template: Used to make instances with the same settings, similar to making your own personal default settings for your instances.

~Apache: A free Open-source web server, it can run on a wide range of Operating Systems, is highly customizable, and contains strong security features.

Prerequisites:

~ Have an AWS Account with a Cloud9 environment set up.

~ Terraform installed on your IDE if you are not using the Cloud9 environment.

S3 Bucket

In AWS we need to create an S3 bucket, the name must be globally uniqiue or it will not work. We will be using this bucket to store our terraform state files instead of inside your Cloud9 environment.

To keep up with the different versions of your terraform state file, I will suggest you turn on Bucket Versioning, this is an optional feature. Then you can create your bucket.

File Creation

In your Cloud9 environment create a new directory for this project then change to that location.

mkdir week21project
cd weekw21project

Then make new files for this project, we need 4 files.

touch variables.tf main.tf terraform.tf script.sh

terraform.tf

We are going to edit the terraform.tf file first. This file will hold our provider and our backend configuration. The provider is AWS and the backend will be the bucket we created above.

The key attribute for the bucket will be the name of the state file.

terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
}
}
backend "s3" {
bucket = "BUCKET-NAME"
key = "state"
region = "us-east-1"
}
}

Variables.tf

For the variables file we will define multiple variables that we will use inside our main.tf file. This is used to avoid hard coding information into the file. Each variable uses a default and a type to define the variable.

#Default VPC 
variable "vpc_id" {
type = string
default = "vpc-"
}
#Two subnets in the defualt VPC
variable "subnets" {
type = list(string)
default = ["subnet-", "subnet-"]
}
#amazon linux ami
variable "ami" {
type = string
default = "ami-09538990a0c4fe9be"
}
#ASG name
variable "name" {
type = string
default = "week21project"
}
#instance type
variable "type" {
type = string
default = "t2.micro"
}
#Port numbers
variable "ingressrule" {
type = list(number)
default = [80, 443, 22]
}
#all traffic CIDR Block
variable "block" {
default = ["0.0.0.0/0"]
}
#to/from port
variable "ports" {
type = number
default = 0
}
#true value
variable "enable" {
default = true
}
#traffic protocol for egress rule
variable "protocol" {
type = string
default = "-1"
}
#protocol for the dynamic block
variable "dynamic_protocol" {
type = string
default = "TCP"
}
#your default VPC CIDR block
variable "vpc_cidr" {
default = ["172.0.0.0/32"]
}
#max instances number
variable "max" {
type = number
default = 5
}
#min instance number
variable "min" {
type = number
default = 2
}
#your key pair
variable "key" {
type = string
default = "key-pair"

Script.sh

This script will update the server and install Apache with a custom Webpage. We will attach this file to our user data field in our main.tf file. I provided inline comments to inform you of what each line of code does.

#!/bin/bash
#This updates the server
yum update -y
#This installs apache
yum install -y httpd
systemctl start httpd
systemctl enable httpd
#This adds your custom webpage
sudo echo "<html><h1>This is my Week 21 project</h1></html>" > /var/www/html/index.html

Main.tf

We are working on our final file. The security group resource we will make first we need to add rules to allow internet access from ports http, ssh, and https. Our auto scaling group will have a maximum of 5 instances and a minimum of 2 instances. A launch template will also be made containing information about the instance and user data to be sure your instances have the same information. This makes for easier deployment.

#create a security group using variables
resource "aws_security_group" "internet-access" {
name = "ALL Traffic"
vpc_id = var.vpc_id
dynamic "ingress" {
iterator = port
for_each = var.ingressrule
content {
to_port = port.value
from_port = port.value
protocol = var.dynamic_protocol
cidr_blocks = var.block
}
}
ingress {
from_port = var.ports
to_port = var.ports
protocol = var.protocol
cidr_blocks = var.vpc_cidr
}
egress {
from_port = var.ports
to_port = var.ports
protocol = var.protocol
cidr_blocks = var.block
}
}

#module that will create a launch template and auto scaling group
module "asg" {
source = "terraform-aws-modules/autoscaling/aws"
version = "4.9.0"
name = var.name
vpc_zone_identifier = var.subnets
security_groups = [""]
min_size = var.min
max_size = var.max
desired_capacity = var.min
key_name = var.key
use_lt = var.enable
create_lt = var.enable
image_id = var.ami
instance_type = var.type
user_data = file("script.sh")
tags_as_map = {
Name = var.name
}
}

Now that we have everything added to our files lets format the files. This will make the files more readable and help with any code mistakes. If any files are edited the file name will be output.

terraform fmt

The Process

Next, we will start the resource creation process. Begin by running the init, this initializes the file so terraform will read the providers needed and see that we will be using S3 as a backend and not the local backend.

terraform init

Once it finishes the initialization, we need to plan but before we can do that we need to go inside a file and comment a line. This line causes an error if not commented and will not allow your configuration to work.

Run the following commands:

~ cd .terraform/modules/asg

~ vim main.tf

Once you are in the file type “448” this will take you to the tag line you simply need to turn this into a comment. Hit ‘i’ so you can insert the # in front. Then click “esc” and type “:wq” to save the work.

After exiting the file return back to your directory.

cd ../../..

Now remember we do not have the security group above, so we need to make that first. We will plan only for the security group.

terraform plan -target=aws_security_group.internet-access

Apply this plan only to the security group. When the security group is made it will provide the security group ID and you can put that inside your main.tf file.

terraform apply -target=aws_security_group.internet-access

After adding the security group to the auto scaling group, you can now create the rest of the remaining resources. Run another terraform apply and this time we should see that 2 resources will be created because we already made the security group. After you have read over what will be made you can type yes to apply the changes.

Is it Correct?

When it says the Apply is complete check in EC2 to see if you have 2 instances running. Terminate one of the instances and see if another instance is created this will ensure that your auto scaling group works.

Then try to connect to an instance via your browser.

You have successfully used terraform to make an Auto Scaling Group.

For more, easy to follow articles, follow me on Medium!

--

--

Asonti Ginn
Women in Technology

Hey! I am taking you on my Cloud engineering journey with easy to follow, how-to articles. All provided with an under 10-minute read and PLENTY of pictures!☁️