# Using Terraform with DigitalOcean

In this post I’m going to use Terraform to define and launch a DigitalOcean server and a DNS DigitalOcean A Record.

### Prerrequisites

1. DigitalOcean Account.

## Terraform

Terraform is a tool created by HashiCorp, best known as the creators of Vagrant. Terraform allows you to define and launch your servers infrastructure, using a declarative language.

Some of the supported providers are: DigitalOcean, Azure, AWS , and Google Cloud just to name a few.

## Terraform Providers

A provider is responsible for understanding API interactions and exposing resources. For example, the DigitalOcean Provider can create resources such Servers and DNS records using the DigitalOcean API

## Terraform Resources

Resources are a component of your infrastructure. It might be some low level component such as a physical server, virtual machine, or container.

## Terraform Provisioners

When a resource is initially created, provisioners can be executed to initialize that resource.

### Installing Terraform

2. unzip in a directory referenced by PATH, so you can run the terraform command easily.
• eg.  unzip ~/Downloads/terraform_0.6.8_darwin_amd64.zip -d /usr/local/bin  Now you should be able to run the terraform command.
$terraform version$ Terraform v0.6.8


### Create a Terraform Configuration Project

mkdir ~/terraform-digitalocean-example
cd ~/terraform-digitalocean-example


### Create a provider configuration

Create a file called digitalocean-provider.tf:

vi digitalocean-provider.tf


variable "do_token" {} #Your DigitalOcean token
variable "pub_key" {}  #Public Key to be installed in your DigitalOcean server
variable "pvt_key" {}#Private Key Terraform will use to connect to your new server
variable "ssh_fingerprint" {}#SSH Fingerprint

provider "digitalocean" {
]

connection {
user = "root"
type = "ssh"
key_file = "${var.pvt_key}" timeout = "2m" } provisioner "remote-exec" { inline = [ "echo 'I might use puppet or ansible to provision my server here'", ] } }  connection: Allows Terraform to connect to your server via ssh. privisioner: You can run different types of provisioners to provision your server. ### Create a DNS A Record Resource I’m assuming that you own a domain and and it’s already managed with DigitalOcean, if you don’t you can follow this post. Create a file called example.mydomain.com: vi example.mydomain.com.tf  Add the following contents: resource "digitalocean_record" "A-example" { domain = "mydomain.com" type = "A" name = "example" value = "${digitalocean_droplet.example_jumlabs.ipv4_address}"
}


Note: Remember to change mydomain.com with your own domain name.

Assuming that your private key is located at ~/.ssh/id_rsa, run :

ssh-keygen -lf ~/.ssh/id_rsa.pub | awk '{print $2}'  This will output your Fingerprint. Something similar to this: e7:42:16:d7:e5:a0:43:23:82:7d:a3:59:cf:9e:92:f3  You will need this Fingerprint later. ### Define Configuration Variables Values Remember this? : variable "do_token" {} #Your DigitalOcean token variable "pub_key" {} #Public Key to be installed in your DigitalOcean server variable "pvt_key" {}#Private Key Terraform will use to connect to your new server variable "ssh_fingerprint" {}#SSH Fingerprint  We are almost ready to run our Terraform configuration, but we still need to define a value for this variables. Terraform has a few ways of passing the value of this variables when you finally apply your configurations, I personally liked the file option. Create a file called terraform.tfvars: vi terraform.tfvars  Add the follow contents do_token = "<your_digital_ocean_personal_token>" pub_key = "/Users/<user>/.ssh/id_rsa.pub" pvt_key = "/Users/<user>/.ssh/id_rsa" ssh_fingerprint = "<your_ssh_fingerprint>"  Warning: If you are going to version control your Terraform Configuration Project, you should add this file to .gitignore, since it contains personal sensitive information. ### Reviewing you Plan Run: terraform plan  It will output something like this: + digitalocean_droplet.example_mydomain image: "" => "ubuntu-14-04-x64" ipv4_address: "" => "<computed>" ipv4_address_private: "" => "<computed>" ipv6_address: "" => "<computed>" ipv6_address_private: "" => "<computed>" locked: "" => "<computed>" name: "" => "example.jumlabs.com" private_networking: "" => "1" region: "" => "nyc2" size: "" => "512mb" ssh_keys.#: "" => "1" ssh_keys.0: "" => "e7:42:16:d7:e5:a0:43:23:82:7d:a3:59:cf:9e:92:f3" status: "" => "<computed>" + digitalocean_record.A-example domain: "" => "mydomain.com" name: "" => "example" port: "" => "<computed>" priority: "" => "<computed>" type: "" => "A" value: "" => "${digitalocean_droplet.example_mydomain.ipv4_address}"
weight:   "" => "<computed>"

Plan: 2 to add, 0 to change, 0 to destroy.


It basically describes the actions Terraform will take at the time you actually apply it. If you have used git, you can think of this as a ‘git status’, something you might like to run before «committing» your changes.

So we are ready to actually create our resources.

Run:

terraform apply


Now yo can go a grab a cup of coffee while terraform applies your configuration.

At the end it will output something like this:

digitalocean_droplet.example_jumlabs:
id = <some_id>
image = ubuntu-14-04-x64
locked = false
name = example.mydomain.com
private_networking = true
region = nyc2
size = 512mb
ssh_keys.# = 1
ssh_keys.0 = <key_fingerprint>>
status = active
digitalocean_record.A-example:
id = <some_id>
domain = mydomain.com
name = example
port = 0
priority = 0
type = A
value = <some_ip>
weight = 0


Note: Remember that DigitalOcean might charge you for the time this resources are alive. If you don’t want to keep them you can

run:

terraform destroy


#### Terraform vs Ansible/Chef/Puppet

There’s actually a difference between Terraform and provisioning tools such Ansible. Terraform allows you to define your infrastructure resources, you still need something to provision those resources, in that case you can use something like Ansible to do that Job.

## Conclusion

Terraform is a tool for defining and manage infrastructure resources for several providers, from physical servers to the cloud. This allows easily reproduce common definitions to scale your infrastructure at will. You still need provisioning tools such Ansible to provision your servers.

I’ll write post about provisioning with Ansible later. Wait for it!!