Devops tool have become quite popular in the last few years. Infrastructure automation tools like Chef, Ansible, Cloudformation and Terraform are increasingly being used to provision cloud infrastructure. Once only used for provisioning compute resources but nowadays due to the agile data analytics organizational need even resources like Data warehouses are being added to the devops cycle. Most of these tools eg: Saltstack, Ansible, Chef, Puppet etc are widely used in the industry one of them stands out among the rest : Terraform.
What makes
Terraform different from others including our very own Cloudformation is
it’s declarative nature, most of infrastructure automation tools are
procedural in nature not declarative. Let me explain the difference
between declarative and procedural
Lets say you want to
provision 10 ec2 instances using an automation approach. With a tool
like Ansible your template would like something below using a procedural
declaration.
– ec2:
count: 10
image: ami-v1
instance_type: t2.micro
Same code in Terraform using a declarative approach looks like
resource “aws_instance” “example” {
count = 10
ami = “ami-v1”
instance_type = “t2.micro”
}
The
difference is that even though both approaches look similar, lets say
you want to add additional 5 servers to the configuration. The ansible
code is essentially useless since ansible does not maintain state. For
ansible if you change the count and increase it to 15, it will create 15
new additional EC2 instances. Ansible has no way to know what it did in
the past. For creating total 15 servers you need to add additional 5.
– ec2:
count: 5
image: ami-v1
instance_type: t2.micro
With Terraform this is the big game changer. Terraform maintains state
of your infrastructure. Terraform is aware of any state it created in
the past. Therefore, to deploy additional 5 more servers, all you have
to do is go back to the same Terraform template and update the count
from 10 to 15:
resource “aws_instance” “example” {
count = 15
ami = “ami-v1”
instance_type = “t2.micro”
}
When
you execute this template Terraform knows it created 10 instances
before so it will add only the 5 new instances. With declarative
approach the end goal matters. This makes Terraform the winner IMHO from
all others. So in this example once we are done with the test , to
delete the cluster we just have to run one command without specifying
any additional details. Becuase Terraform maintains a record that it
created a Redshift cluster with so and so name.
Let’s now jump in and create a Redshift dc1.large cluster in region ‘us-east-1’ using Terraform
1. Download and Install Terraform for Linux from the Terraform Website : https://www.terraform.io/downloads.html
Note : Install awscli and configure your AWS credentials before we begin
On Linux the download is a zip file containing only 1 file. Unzip to any directory and copy the file ‘terraform’ to /usr/bin
2. Create a Terraform configuration file in a new directory
mkdir redshift_tf
cd redshift_tf
vim redshift.tf
provider “aws” {
region = “us-east-1”
}
resource “aws_redshift_cluster” “default” {
cluster_identifier = “terraform-rs-cluster”
database_name = “testdb”
master_username = “awsuser”
master_password = “SomePassword1”
node_type = “dc1.large”
cluster_type = “single-node”
skip_final_snapshot = true
}
3. Initiate Terraform
$ terraform init
Initializing the backend…
Initializing provider plugins…
– Checking for available provider plugins…
– Downloading plugin for provider “aws” (terraform-providers/aws) 2.14.0…
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = “…” constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = “~> 2.14”
Terraform has been successfully initialized!
4. Apply Terraform Configuration
Note 1: From Terraform 0.11 and above you do not have to run ‘terraform plan’ command
Note
2 : For security purpose it is not good practice to store access_key or
secret_key in the .tf file. If you have installed awscli then Terraform
will take your AWS credentials from ‘~/.aws/credentials’ or IAM
credentials.
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_redshift_cluster.default will be created
+ resource “aws_redshift_cluster” “default” {
+ allow_version_upgrade = true
+ automated_snapshot_retention_period = 1
+ availability_zone = (known after apply)
+ bucket_name = (known after apply)
+ cluster_identifier = “terraform-rs-cluster”
+ cluster_parameter_group_name = (known after apply)
+ cluster_public_key = (known after apply)
+ cluster_revision_number = (known after apply)
+ cluster_security_groups = (known after apply)
+ cluster_subnet_group_name = (known after apply)
+ cluster_type = “single-node”
+ cluster_version = “1.0”
+ database_name = “testdb”
+ dns_name = (known after apply)
+ enable_logging = (known after apply)
+ encrypted = false
+ endpoint = (known after apply)
+ enhanced_vpc_routing = (known after apply)
+ iam_roles = (known after apply)
+ id = (known after apply)
+ kms_key_id = (known after apply)
+ master_password = (sensitive value)
+ master_username = “awsuser”
+ node_type = “dc1.large”
+ number_of_nodes = 1
+ port = 5439
+ preferred_maintenance_window = (known after apply)
+ publicly_accessible = true
+ s3_key_prefix = (known after apply)
+ skip_final_snapshot = false
+ vpc_security_group_ids = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_redshift_cluster.default: Creation complete after 3m33s [id=terraform-rs-cluster]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
5. Check the state of your infrastructure
You can go
check
in your AWS console > Redshift Dashboard and you will see the
cluster. To see it from terraform run the below command
$ terraform show
6. Destroy the Redshift cluster
Like i mentioned in the beginning of this article, the beauty of Terraform is it maintains
state of your infrastructure. You can remove the Redshift cluster by running
just one simple command
$ terraform destroy