All Case Studies Design Development Interviews Our Way Project Management

How I Terraformed My AWS Amazon Account

With the growing number of projects and required resources, my ongoing AWS management became more and more of an uphill struggle. That's why I began looking for a better solution than repetitive commands and clicks, keeping in mind the current trends in DevOps environment.

Why have I started searching for a better alternative

I'm sure you have felt the struggle of creating X ec2 instances and Y rds instances at some point, hooking up security groups and access policies multiple times, let alone S3 buckets or Elasticache. You could achieve it in three ways:

  1. Click through the AWS web management console
  2. Execute commands through AWS CLI (with possible usage of scripts)
  3. Use CloudFormation to deploy the whole stack

All of those had some cons, such as executing dozens of commands or endless clicking through a GUI. Using CloudFormation appears to be the most sensible option, although let’s be honest: writing your whole stack (including dependencies) in YAML, doesn't seem to be the most pleasant thing you can do with your time.

Some of you will be familiar with the following concept: Infrastructure as Code (IaC). If you’re not, let me explain it in a nutshell. Infrastructure as Code stands for the situation when you manage your servers using some kind of configuration files. Adding specific snippets to your configuration will result in creating a new server, depending on your intent of course. It will allow the server configuration to be safely kept in Github or SVN and deployed with Jenkins, CircleCI or TravisCI. IaC is now a prominent trend in the DevOps community.

That's when Terraform kicked in

When I was looking for the alternative to the time-consuming AWS procedures, I stumbled upon Terraform by Hashicorps.

Terraform allows us to create an infrastructure based on configuration defined in the main.tf file. On top of that, it allows for planning your infrastructure deployment. In some ways, Terraform is similar to CloudFormation (and it actually uses CloudFormation). In contrast to CloudFormation’s YAML, Terraform uses HCL, a language developed by Hashicorps, which is more accessible for the user.

How does Terraform tick?

Terraform uses .tf files to store the necessary configuration, usually following the structure outlined below:


├── main.tf
├── output.tf
├── terraform.tfvars
└── variables.tf

 

  • main.tf stores basic infrastructure configuration;
  • variables.tf defines the variables used in main.tf;
  • output.tf defines what information should be shown after the infrastructure deployment;
  • terraform.tfvars stores variable values, so as to avoid typing them each time Terraform deploys.

Basic Terraform commands

  • terraform plan: it's a mandatory command, which scans the current .tfstate file and creates a potential plan, showing what will be created, destroyed and changed;
  • terraform apply: deploys the configuration defined in .tf files and creates a .tfstate file with the current state of infrastructure;
  • terraform destroy: destroys all resources created by Terraform.

Of course, there are more commands, but these are the most basic and most often used.

Sample AWS infrastructure configuration

main.tf

provider "aws" {
 region = "us-east-1"
}
resource "aws_instance" "example" {
 ami = "ami-2d39803a"
 instance_type = "t2.micro"
}

Now you only need to execute:

  • terraform plan
  • terraform apply

Making a Terraform repository reusable

This is when modules come to play. You can define your resources just like you used to, but you can also create a project configuration. It has to be in a different directory, and terraform.tfvars has to be in the project directory.

 

├── modules
│   ├── module_1
│   │   ├── main.tf
│   │   ├── output.tf
│   │   └── variables.tf
│   ├── module_2
│   │   ├── main.tf
│   │   ├── output.tf
│   │   └── variables.tf
└── project_1
    ├── main.tf
    ├── output.tf
    ├── terraform.tfstate
    ├── terraform.tfstate.backup
    ├── terraform.tfvars
    └── variables.tf

 

You can then refer to your resources as if you were referring to modules:

main.tf

module "module_1" {
 source = "../modules/module_1"
 var_1  = "${var.project_var_1}"
 var_2  = "${var.project_var_2}"
}

This kind of structure also allows us to keep the project-specific .tfstate file separately. It's also possible to configure Terraform to download and upload .tfstate file automatically to S3 bucket, since it is a more secure place.

Nice! But what if I want to use a different provider?

It isn't an issue at all. Terraform permits using most of the top-tier providers. Even if your favourite provider isn't listed, you can still add your own provider, as long as it offers some kind of an API. Terraform is written in Golang, and both the developers and the community are quite active and friendly.

What if I want to learn more?

I recommend having a browse of Terraform’s documentation, which is vast. You might also want to visit the excellent blog by Gruntwork. Gruntwork’s co-founder, Yevgeniy Brikman, also wrote "Terraform: Up & Running" – a blog and a book that still remain amazingly useful.

Why it is impossible to hire quality engineers in London and how to deal with it
Follow Netguru
Join our Newsletter

Scaling SaaS
READ ALSO FROM DevOps
Read also
Need a successful project?
Estimate project or contact us