IaC – Terraform: Provisioning AWS

Infrastructure as a code (IaC) is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools. Some of the major providers of the IaC are Puppet, Salt Stack, Terraform, Ansible, etc. IaC are an important part of the DevOps culture in bringing visibility to the state and configuration of servers.

In this blog, I will try to provide the steps for provisioning AWS EC2 instances using Terraform. The blog will also try to highlight some of the challenges faced during the provisioning.

a. Installing Terraform

For provisioning terraform you would need to first install terraform onto your local computer or laptop. Go to the Terraform download link and select the operating system of your choice and download terraform. Install the software and set the PATH variable of your system.

If you are having Mac, then you could brew install terraform:

$ brew install terraform

Verify Installation : For verifying if you have successfully installed, run the below code

$ terraform --version
Terraform v0.12.24

You should be able to see a version of the terraform.

b. Setting up AWS Terraform User

Since we would be provisioning EC2 instance, we need to first create an user called “TerraformUser” into the AWS with limited permission. As part of this demo, I will provide EC2 full admin access, but in a production environment you should always set it to least privilege policy. Or you could either consult your cloud admin to create a new role.

{for admins only} For creating AWS role, log into the AWS console using an Admin account and select IAM service. Click on User and “Add User”. Select the policy as “EC2 Full Access”. Once you are done, you should see a new user created as below:

Sample Terraform User with EC2 Full Access

Once the user is created, you should be receiving AWS Secret Key ID and AWS Secret Access Key. Download these key and save it safely into your local system (DONOT SHARE).

  • Note :
    • You should always set AWS users with the least permission policy. Provide access to the services that it would require and nothing else.
    • Do not share your AWS Secret Key ID and AWS Secret Access Key with anyone.

c. Setting up AWS Secret Key

This step is important as it would enable you to provision EC2 instance using Terraform without passing in your AWS Secret credentials into the code.

There are couple of ways to do this. One of the most popular way (which I will explain) is to set up aws secret key as aws credentials environment variables. Terraform will search for the environment variable before starting the plan. In order to set up the environment variables, follow the below steps:

$ cd ~/.aws
$ vi credentials

Next add the below lines of code in the credentials file:

aws_access_key_id     = <1:TerraformUser Secret Access key id goes in here>
aws_secret_access_key = <2:TerraformUser Secret Access key goes in here>

In the sections <1> and <2>; you need to place the AWS Secret Key ID and AWS Secret Access Key of the TerraformUser as you might have got in step b of this blog. Save and exit.

d. Setting up Terraform project

Lets create a simple terraform project using any IDE of your choice. I am using Visual Studio Code.

The project name is called “TerraformDemoProject” under which we create 2 files:

  • terraform-ec2-provision.tf : The main terraform file that will be used in the plan to provision aws ec2 instance.
  • terraform-ec2-provision-variables.tfvars : [Optional] This is the variable file that holds the variables. Though this is an optional file, but parameterizing your terraform script makes it powerful in terms of re-usability.
  • ec2_user_data: [Optional] This is a directory where I would keep user data scripts required for launching ec2 instances.

e. Write Terraform Code

Now comes the exciting bit of the blog, the actual code. This is where I will write all the code required for provisioning ec2 instance and also explain the steps. I will break this into 2 sections to explain it better:

Part 1: Defining the variable : terraform-ec2-provision-variables.tfvars

For the first steps, let us setup some variables which we might need. To do that first open the variables file : terraform-ec2-provision-variables.tfvars. Add the below:

Code available in GitHub

Sample .tfvar file for aws ec2

The names of the variables depends on you. It can be any name of your choice until you refer it properly in the main terraform file. Explanation for the keys that I have added in the var file:

profile[Required] This is the profile you want to trigger. For this Demo it is set as “default”. This is essentially the profile which you have in your credentials file.
region[Required] The region of AWS where you want your EC2 instance be created. Mine is us-east-1 (Northern Virginia). It could be different for you. But ensure you know the AWS available regions for EC2 instances.
aws_credentials[Required] The location of the credentials file as created in step c.
aws_instance_count[Optional] The total number of AWS instances you would need to provision. Default is 1.
aws_ami_instance[Required] The AMI instance which would be provisioned. For getting the instance id, the easiest way is to log into console and get the linux id. More on ami instance in official aws doc.
aws_instance_type[Required] The instance type defines the hardware configuration of AMI instance. For free tier, “t2.micro” is permissible. More on instance types in official aws doc.
aws_iam_instance_profile[Required] The instance type defines the hardware configuration of AMI instance. For free tier, “t2.micro” is permissible. More on instance types in official aws doc.
aws_ec2_keyname[Optional] The name of the instance.
aws_ec2_sgrp[Optional] This is for the Security Group attached to the AWS instance. You would need to open port for SSH, HTTPS and HTTP to enable installation of user data. In this example, I provided the name of security group I have already created in AWS.
aws_ec2_tag_name[Optional] The name of the instance.
aws_ec2_userdata_file_location[Optional] The location of the script or the user data that needs to be executed once AWS instance is booted. I have a shell script that does “sudo yum update” and “install python3”.

For the second step, we would require to add the steps in the main terraform file: terraform-ec2-provision.tf.

Code available in GitHub

Main Terraform Execution File : terraform-ec2-provision.tf

The terraform-ec2-provision.tf file provisions the AWS instance. There are couple of main parts to this file which defines the whole infrastructure as a code.

Provider section of the main file defines which cloud provider is to be initialised. In this demo, we had our provider set to AWS. This allows terraform to know it need to provision for the AWS cloud provider.

Resource section of the code define what sort of resource is to be provisioned. In the demo we are going to provision AWS EC2 instance, hence the resource we would be looking for is “aws_instance”.

f. Initializing Terraform

The first thing which you would have to do is to initialise terraform. Run the below code on your local system:

$ terraform init

This initialise the aws and downloads all the necessary packages. Log will look as below:

Sample Terraform init log

g. Terraform Plan

The next step would be create a terraform plan. The plan create an execution pipeline to be executed for provisioning ec2 instances based on the .tf file created.

$ terraform plan --var-file="terraform-ec2-provision-variables.tfvars" --out terraform-ec2-plan.out

the arguments: –var-file is for referring to the variable file we created earlier. The –out argument is for writing the output into a file.

Note: This is essential as the terraform apply doesn’t guarantee the plan to be executed properly until there is a plan written out.

h. Terraform Apply

The final step of provisioning ec2 instance is to apply the configuration based on the plan.

$ terraform apply "terraform-ec2-plan.out"

Log will look something like below:

Sample AWS Instance created terraform log

Now when you check the AWS Console, you would find 2 instances of AWS EC2 instances are created. The details of which will be the same as per the given configuration.

AWS Console with 2 new Instances created

i. Terraform Destroy

Now if you want to destroy these instances once your work is complete, then terraform allows you to destroy these instances.

$ terraform destroy -var-file="terraform-ec2-provision-variables.tfvars"

Once you confirm these all the instances will be destroyed.

Terraform destroy to stop the resources
Final Words and reference links

Terraform can do a lot more than just provisioning AWS EC2 instances. You can provision and configure a whole lot of different services across multi-cloud environments. Below are some of the links as reference.

Do comment in your thoughts or question. I will try to answer to be best possible.

Success! You're on the list.

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s