Home
Blog
Certifications
Openings
Refer & Earn
Help
October 07, 2021
Terraform - Getting Started
An intro to Terraform with AWS
Share
Share
What is Terraform?
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. It has an open-source infrastructure and a code software tool that provides a consistent CLI workflow to manage hundreds of cloud services. Basically, if you want to manage the entire infrastructure using CLI and have efficient rollbacks during errors, Terraform proves to be an amazing tool. Read the official docs here
Advantages of using Terraform:
- It works with a great number of the latest and most used cloud providers.
- It is very effective in managing the infrastructure directly from the CLI.
- It gives a deep understanding of how the deployment is working.
- It is smart enough to deal with failover, update, and deletion.
Alternatives for Terraform:
There are other great alternatives to Terraform like:
- AWS CloudFormation
- Serverless
- Pulumi
- Ansible
Some important terms to know before we start with Terraform:
- Provider: Providers are a logical abstraction of an upstream API. They are responsible for understanding API interactions and exposing resources. A list of providers is available here.
- Resource: Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects in the cloud provider.
- Output: Terraform output values allow you to export structured data about your resources. Outputs are also necessary to share data from a child module to your root module.
- Module: A module allows you to group resources together and reuse this group later, possibly many times.
So, this article will help you get started with Terraform which will help in manage AWS services. Follow the docs for the installation of Terraform. You can also do this by using Homebrew as shown below:
Copy
brew install terraform terraform -v ##checks the version
Implementation
Now, here we will try to launch an EC2 instance and carry out the entire process using terraform. A prerequisite is that you have an AWS account setup, know how to generate access keys and their configuration on the local system. Let's start off:
- Create a main.tf file and update its contents as follows while also defining the provider and specified account access as shown:
Copy
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.0" } } } # Configure the AWS Provider provider "aws" { region = "us-east-1" shared_credentials_file = "/Users/adityaprakash/.aws/credentials" profile = "default" }
"Never add hard coded values for the access key and credentials. Always try to use their reference."
Next, its is important to do some research before proceeding to set up the instance as shown below:
Copy
# VPC resource "aws_vpc" "prod" { cidr_block = "10.0.0.0/16" tags = { Name = "prod" } } # Internet Gateway resource "aws_internet_gateway" "gw" { vpc_id = aws_vpc.prod.id } # Custom route table resource "aws_route_table" "prod-route-table" { vpc_id = aws_vpc.prod.id route { cidr_block = "0.0.0.0/0" #send IPv4 traffic wherever this route points gateway_id = aws_internet_gateway.gw.id } route { ipv6_cidr_block = "::/0" gateway_id = aws_internet_gateway.gw.id } tags = { Name = "prod" } } # Create subnet resource "aws_subnet" "subnet-1" { vpc_id = aws_vpc.prod.id cidr_block = "10.0.1.0/24" availability_zone = "us-east-1a" tags = { Name = "prod-subnet" } } # Associate Subnet with Route Table resource "aws_route_table_association" "a" { subnet_id = aws_subnet.subnet-1.id route_table_id = aws_route_table.prod-route-table.id }
"The general syntax for defining a resource is aws_resource name you want to specify for the resource {.......} . Meanwhile, the syntax for referring to an earlier defined resource is referencing_resource = referred_resource . name . id "
In the next step, let's create a VPC (aws_vpc) wherein the entire workflow will take place. Then, we define an Internet Gateway(aws_internet_gateway) that will provide internet connectivity to the EC2 instance. Next, let's define a subnet(aws_subnet) and associate it to a route table(aws_route_table) that determines where network traffic from your subnet or gateway is directed. To associate, we use the (aws_route_table_association) resource.
After that, let's set up the security group, network interface, and elastic IP to be attached to the instance. Here, we have to define the security groups in order to define the inbound and outbound traffic. Next, define the required network interface and create an Elastic IP (static and allow will be reachable from the internet) to be attached to the instance. Look how it's done below:
Copy
# Network Interface resource "aws_network_interface" "nic" { subnet_id = aws_subnet.subnet-1.id private_ips = ["10.0.1.50"] security_groups = [aws_security_group.allow_web.id] } # Attach Elastic IP to n/w interface -------Req. deployment of IGW first as well as the EC2 instance being setup first. resource "aws_eip" "one" { vpc = true #wheteher in VPC or not network_interface = aws_network_interface.nic.id associate_with_private_ip = "10.0.1.50" depends_on = [aws_internet_gateway.gw, aws_instance.testIntance] }
"Note that here we have used the depends_on to ensure that the Elastic IP is to be created after the Internet gateway and EC2 instance has been set up."
- Let's go on to code the creation of the EC2 instance. Here, we create the script that downloads Apache on the instance and creates an index.html file to be rendered when the URL of the instance is hit. Learn how this is done by following the code below:
Copy
# EC2 Instance resource "aws_instance" "testIntance" { ami = "ami-02fe94dee086c0c37" instance_type = "t2.micro" availability_zone = "us-east-1a" key_name = "terraform" network_interface { device_index = 0 network_interface_id = aws_network_interface.nic.id } user_data = << - EOF #!/bin/bash sudo apt update -y sudo apt install apache2 -y sudo systemctl start apache2 sudo bash -c 'echo first web server > /var/www/html/index.html' EOF tags = { Name = "test-instance" } }
"It is important to ensure that you the correct ami-id of the instance you want to set up to AWS to the ami-ids of the instances."
Now, let's run the following commands to check the progress:
- terraform init to initialize the backend and download all the required plugins for the provider.
- terraform plan will show you all the resources that will be configured and set up in your AWS account but will not deploy them.
- terraform apply to deploy all the resources.
If everything goes fine, you will get the following output:
Finally, if you want to destroy all the resources created (Be careful here☠️), use terraform destroy
Discussing AWS without a serverless implementation feels incomplete. So, now let us deploy a basic Lambda function using Terraform as shown:
Let's look at how a hello_lambda.py file looks like:
Copy
import os def lambda_handler(event, context): return "{} from Lambda!".format(os.environ['greeting'])
Next, let's how a main.tf file looks like this:
Copy
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.0" } } } # Configure the AWS Provider provider "aws" { region = "us-east-1" shared_credentials_file = "/Users/adityaprakash/.aws/credentials" profile = "default" } provider "archive" {} data "archive_file" "zip" { type = "zip" source_file = "hello_lambda.py" output_path = "hello_lambda.zip" } resource "aws_iam_role" "iam_for_lambda" { name = "iam_for_lambda" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "lambda.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } EOF } resource "aws_lambda_function" "lambda" { function_name = "hello_lambda" filename = "${data.archive_file.zip.output_path}" source_code_hash = "${data.archive_file.zip.output_base64sha256}" role = aws_iam_role.iam_for_lambda.arn handler = "hello_lambda.lambda_handler" runtime = "python3.6" environment { variables = { greeting = "Hello" } } }
In this section, we do three major things:
- Firstly, we use data to input the Lambda file and output a zip file to be uploaded for the Lambda implementation.
- Second, we create an IAM role to be assumed by the lambda function.
- Finally, we create the Lambda function using the zip file we created above as its source code before running the following commands to deploy the function:
Copy
terrform init terraform plan terraform apply
"Whenever we update any particular resource, Terraform does not deploy all the resources again but it is smart enough to detect the resource that has been updated and carry out only the required changes. The same applies to the deletion of any resource."
To bring it to an end, I would just like to say that giving Terraform a try is worth a shot and will definitely help one to deeply understand the cloud services better. Hope this article helps you get started with it.
Thanks for reading. 😊
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Comments
Comments for this article will be shown here.
Please
sign in
to post a comment
Explore More
With our Recruiting AI.
Get hired quickly and reliably.
Set up your profile | Add skills | Take automated interviews.
2020 © All rights reserved. GeekyAnts India Pvt Ltd