My first take on terraform

On my previous company, I had the opportunity to learn and do some DevOps work. Thanks to some amazing colleagues I was able to pick up some concepts and experience regarding infrastructure as code, docker, kubernetes, yaml files and others. Back then we didn’t use Terraform as it was not fully compatible with Azure at the time (I might be wrong about this) and we used plain old ARM Templates to describe infrastructure and bash scripts with tools like Azure CLI and Kubectl to automate the provision and deploy of resources/applications into Azure and Kubernetes.

This week I decided to take a first look at Terraform and AWS, and also to check how familiar I still was with the concepts previously mentioned. So these were my steps…

Since I’m new to AWS the first step should be…

  1. create an account at
  2. create a user with “Programmatic access
  3. create a new group ( didn’t check any policies), didn’t add any tags
  4. And at the end save the “Access key ID” and “Secret access key”.

Now … to get Terraform, since I’m on a Windows machine and I have Chocolatey installed

choco install terraform
terraform version
From what I understand Terraform (.tf) files are divided into 4 sections, variables, providers, resources and outputs. Given this simple .tf file
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "private_key_path" {}
variable "key_name" {}

provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "us-east-1"

resource "aws_instance" "nginx" {
ami = "ami-c58c1dd3"
instance_type = "t2.micro"
key_name = "${var.key_name}"

  connection {
    user        = "ec2-user"
    private_key = "${file(var.private_key_path)}"

  provisioner "remote-exec" {
    inline = [
      "sudo yum install nginx -y",
      "sudo service nginx start"

output "aws_instance_public_dns" {
    value = "${aws_instance.nginx.public_dns}"
We can easily figure out what it does… It has some variables for values like keys and secrets, it uses provider “aws” and for that provider, we have an aws_instance resource with the name “nginx”. We have “ami”, the name of the image to provision the instance and the “instance_type” of that instance. We’re also describing how a connection can be made, with user and a private_key. Using that connection after the resource is provisioned we’re going to remote-exec a couple of commands.

At the end we want the provider to output the “aws_instance_public_dns”.

Simple enough right?

There are many ways you can pass values to the .ts files, to start I choose to have a .tfvars file. Fill up with your values

aws_access_key = ""
aws_secret_key = ""
private_key_path = ""

With both files in place to “execute” them is as simple as

terraform init

terraform plan -var-file=terraform.tfvars

terraform apply -var-file=terraform.tfvars

If everything goes as planned you will have the output with a public DNS that you can browse to… *

“Welcome to nginx on the Amazon Linux AMI!”

And the always usefull $$$$$

terraform destroy -var-file=terraform.tfvars

Notes :

Now… I did have some issues with the keys.

Next steps :

  • Provide de security group and inbound rules as a resource in the file
  • use Azure as a provider
  • remove the prompt ???

Hope you find it useful …


This entry was posted in continuous delivery, continuous integration, devops, Tools. Bookmark the permalink.

Leave a Reply

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

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

Google photo

You are commenting using your Google 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

This site uses Akismet to reduce spam. Learn how your comment data is processed.