Terraform for beginners - installation and provisioning a resource on DigitalOcean
Tags: codenewbie, tutorial, devops
Published: 2020-10-21 18:44:29

# Introduction

Hey, $users! Recently I started working with Terraform and taught there is no better way to recap my knowledge but to create a blog post on it! I hope it turns out great and you learn something. In this tutorial-like adventure, we will do the following:
* Understand Infrastructure As Code (IAC) and Terraform
* Install Terraform
* Understanding the basic functionality of Terraform
* Provision a free resource on DigitalOcean (with free $100 as a starting account)

I hope you are ready to learn an awesome tool and without further due - let's start!

## What is Infrastructure As Code (IAC)

Okay, I've been working as an admin for a while (1y) and I know my way around provisioning Linux and Windows machines in the cloud or on-prem. What I usually do, is get a distro image I would like to install, go create a resource in the platform I use, install the OS and I'm ready and set. However, this process can get quite chaotic if you try to set-up big infrastructures with complex plans. Only if there was a way to define what I need and it magically appears... oh, wait, THERE IS - Infrastructure as Code!

Yup, there is such a way and it is pretty popular already. It's called Infrastructure as Code and one of the main (more likely THE MAIN) companies that provide such service is Hashicorp. Their IAC service is called Terraform. So it works like this:
1. You define your infrastructure in a file/files with code blocks
2. You execute the code
3. *puff* You have your infrastructure

It really is as easy as it sounds! And that's basically it. You provide your "endpoint", you execute the code you wrote, and you are there. You simply manage your infrastructure in files, rather than manually configuring it.

Anyway, I think the best way of understanding something, is to get your hands dirty so let's advance.

## Install Terraform

To use Terraform we have to install Terraform. We can do so from [their official website](https://www.terraform.io/downloads.html). Select the OS you are using and download it. As I am doing it on Windows, I receive an archive with a *.exe* file named *terraform.exe*. Don't forget to put the file in your system path:
* [How to set path in Windows](https://docs.alfresco.com/4.2/tasks/fot-addpath.html)
* [How to set path in Linux](https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix)

Now restart your terminal / PowerShell and type
```
terraform
```
to validate it's working system-wide.

Good job, you installed Terraform on your system!

## Understanding the basic functionality of Terraform

Hey now, let's dive a little deeper. Let's talk a little bit about what Terraform provides and why it is so good.

### Terraform state

As stated by Hashicorp themselves: *"Terraform must store state about your managed infrastructure and configuration. This state is used by Terraform to map real-world resources to your configuration, keep track of metadata, and to improve performance for large infrastructures."*

So basically, the state is a way for Terraform to keep track of where your infrastructure currently is. In simple words, a *save game* button for Terraform.

### Terraform basic functionality

In Terraform there are three things that you absolutely need to remember:
* The main file - main.tf
* Variables
* Outputs

#### The main file - main.tf

This is the file that Terraform reads and applies resources creation upon it.

#### Variables

Variables are just what you imagine - variables. You can define variables in the **main.tf** file, or in a **variables.tf** file. You can use variables and pass data from module to module, or simply input the variable yourself.

#### Outputs

Outputs are the *save game* button for us. You can output data from your resources directly in the terminal after the deploy is done. You can define outputs the same as variables - in a file named **outputs.tf** or in the **main.tf** file.

### Modules

You can also create modules to reuse in your infrastructure. For example, if I want to create 5 Linux VMs in Azure, I will create a module and simply use variables to change some of the values on my VMs. Modules are defined in different folders and are called with
```source = "path/to/module/directory"```
If you want to know more about modules, please refer to [Hashicorp's official documentation](https://www.terraform.io/docs/modules/index.html)

Okay, we now know what variables, outputs, and modules are. We also know we must create a *main.tf* file and define our infrastructure there. We are now ready to get to work!

## Provision a free resource on DigitalOcean (with free $100 as a starting account)

You can get $100 free on DigitalOcean to use in your first month with your first registration from [this link](https://m.do.co/c/0afa6ab0aa5a).

We will start by creating our folder structure for our project. As we are not going to do anything fancy, we need a **main.tf**, **outputs.tf** and **variables.tf** file.

#### main.tf file configuration

```
terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
    }
  }
  required_version = ">= 0.13"
}
```
We define the cloud provider we are going to use - DigitalOcean, and the required Terraform version.

```
provider "digitalocean" {
    token = var.do_token
}
```
With this block, we define our DigitalOcean API token. [With this link](https://www.digitalocean.com/docs/apis-clis/api/create-personal-access-token/#:~:text=To%20generate%20a%20personal%20access,the%20Generate%20New%20Token%20button.) you can check how to create a personal API token. Notice how we have *var.do_token*. We are going to define this variable in our *variables.tf* file and use it.

```
resource "digitalocean_droplet" "web" {
    image  = "centos-6-x64"
    name   = var.droplet_name
    region = "lon1"
    size   = "s-1vcpu-1gb"
}
```
Full **main.tf** file should look like this:
```
terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
    }
  }
  required_version = ">= 0.13"
}

provider "digitalocean" {
    token = var.do_token
}

resource "digitalocean_droplet" "web" {
    image  = "centos-6-x64"
    name   = var.droplet_name
    region = "lon1"
    size   = "s-1vcpu-1gb"
}
```
This is a very basic droplet creation block. We create a CentOS 6 droplet in London and its size is 1 VCPU and 1 GB ram. We also have a *var.droplet_name* variable, which we will define in our *variables.tf* file.

And we are done with our **main.tf** file. Now let's advance further.

#### variables.tf

In our *variables.tf* file, input the following code:
```
variable "do_token" {
    default = "yourAPItoken92349032f8932h9f02130fh382h98h93h2f9"
}
```
Replace *yourAPItoken92349032f8932h9f02130fh382h98h93h2f9* with your API token.
```
variable "droplet_name" {
    default = "my-terraform-droplet"
}
```
We declate the *droplet_name* variable and give it a name of "my-terraform-droplet". And we are done with our variables. Full code should look like this:
```
variable "do_token" {
    default = "yourAPItoken92349032f8932h9f02130fh382h98h93h2f9"
}

variable "droplet_name" {
    default = "my-terraform-droplet"
}
```

#### outputs.tf

In our outputs file, we declare the data that we want to be outputted after our code executes. In our case, we will output the droplet name.
```
output "droplet_name" {
    value = var.droplet_name
}
```

### Validating and executing the code

Okay, now open a terminal and navigate to the directory where your *main.tf* file stands. Execute the following command:
```
terraform init
```
We initialize our infrastructure and a *terraform.tfstate* file gets created. We then validate our code with:
```
terraform validate
```
We get a green message saying **Success! The configuration is valid.**. This means everything is fine. We finally apply the code with:
```
terraform apply
```
When the code finishes the execution, we are done! We have our droplet created and we have a green "Outputs:" text with the following - *droplet_name = my-terraform-droplet*. This way, we can validate our *outputs.tf* file is working as well.

Oh, and I almost forgot. Let's delete this droplet so it doesn't generate costs (don't worry, if you clicked the link, you have $100 free for a month but in case you forget, please delete your droplet):
```
terraform destroy
```

## Conclusion

That's all $users. We learned a bit about what IAC is, what Terraform is, how to use it, and use it! If you are interested in learning more, Hashicorp has wonderful documentation and I highly recommend you [to go check it out!](https://www.terraform.io/docs/index.html).

If you enjoyed this post, consider following me and I promise, I won't spam your feed (much)!

If you want to drop me a line, you can do so in the comments or/and on [Twitter](https://twitter.com/Denislav__).

Thanks for reading and continue on being awesome!