Terraform

Using Terraform to Launch a VPS Instance in Digital Ocean

Pinterest LinkedIn Tumblr

Terraform is an open-source infrastructure as code software tool created by HashiCorp. To use terraform, you define the resources you want to create using a declarative configuration language created by Hashicorp known as HashiCorp Configuration Language (HCL), or optionally JSON.

Digital ocean is a cloud provider like AWS, GCP or Azure but its relatively smaller and thus simpler to use and much cheaper. Digital ocean can be found in this website here.

In this guide, we will explore using terraform to launch a Virtual Private Server(VPS) in the Digital Ocean cloud.

Prerequisites

  • Terraform installed and accessible in $PATH
  • doctl – the digital ocean command like installed (Optional)
  • A Digital ocean account with enough funds to create a VPS (Use this link here to create an account and earn $100 introduction credit)

Installing terraform

Terraform is available as a single binary that can be downloaded from the terraform website’s downloads page here. Download the correct file for your OS from that page and install it in your system.

Once terraform is installed, use the following command to check the version:

➜ terraform version
Terraform v1.0.5
on darwin_amd64

I am using terraform v1.0.5 in this guide.

Installing doctl

doctl is the official command-line interface (CLI) for the DigitalOcean API. Its an executable binary file that once authenticated, can be used to query digital ocean’s API.

The command is written in golang thus compiles to a single binary. To install it, head over to its github releases page here and grab the correct file for your OS.

Remember to add it to $PATH and confirm that its been installed by checking the version using this command:

❯ doctl version
doctl version 1.64.0-release
Git commit hash: 84fb2307

Generate token in api -> Generate new token:

Then auth:

❯ doctl auth init
Please authenticate doctl for use with your DigitalOcean account. You can generate a token in the control panel at https://cloud.digitalocean.com/account/api/tokens

Enter your access token:
Validating token... OK

Creating a VPS

To create an instance, we have to know a couple of things:

  • Which image to use
  • How big the instance will be
  • The region to launch that instance

The best and simple way to know such is by using the installed doctl command to query.

Please note that you will have to authenticate before using the doctl command. You will need an access token to authenticate that can be obtained from the digital ocean’s UI, Click this link here to access that page once logged in.

Click on the generate new button in the top right corner of the page and you will be welcomed by this page:

Digital Ocean Generate New Access Token
Digital Ocean Generate New Access Token

Once you enter the name click the Generate Token button. This will generate a token that is shown once the pop up dissapears, you will be advised to copy and keep the token safe since it will dissapears once you reload or navigate away from the page.

Authenticate

Use this command to authenticate, supply the token generated above:

doctl auth init

You should see an output similar to this:

❯ doctl auth init
Please authenticate doctl for use with your DigitalOcean account. You can generate a token in the control panel at https://cloud.digitalocean.com/account/api/tokens

Enter your access token:
Validating token... OK

Getting information using doctl

Get a list of public images that can be used to launch instances:

➜ doctl compute image list --public

➜ doctl compute image list --public | grep rocky
89199942    RockyLinux 8.4 x64                                               snapshot    Rocky Linux     rockylinux-8-x64                             true      15

Geting the region list:

➜ doctl compute region list
Slug    Name               Available
nyc1    New York 1         true
sfo1    San Francisco 1    false
nyc2    New York 2         false
ams2    Amsterdam 2        false
sgp1    Singapore 1        true
lon1    London 1           true
nyc3    New York 3         true
ams3    Amsterdam 3        true
fra1    Frankfurt 1        true
tor1    Toronto 1          true
sfo2    San Francisco 2    true
blr1    Bangalore 1        true
sfo3    San Francisco 3    true

Get digital ocean size list:

➜ doctl compute size list
Slug                 Memory    VCPUs    Disk    Price Monthly    Price Hourly
s-1vcpu-1gb          1024      1        25      5.00             0.007440
s-1vcpu-1gb-amd      1024      1        25      6.00             0.008930
s-1vcpu-1gb-intel    1024      1        25      6.00             0.008930
s-1vcpu-2gb          2048      1        50      10.00            0.014880
s-1vcpu-2gb-amd      2048      1        50      12.00            0.017860
s-1vcpu-2gb-intel    2048      1        50      12.00            0.017860
s-2vcpu-2gb          2048      2        60      15.00            0.022320
s-2vcpu-2gb-amd      2048      2        60      18.00            0.026790
s-2vcpu-2gb-intel    2048      2        60      18.00            0.026790
s-2vcpu-4gb          4096      2        80      20.00            0.029760

Creating terraform code

To create the resources, we need to give terraform instructions using the HashiCorp Configuration Language(HCL). Terraform will look for hcl logic in all files in the current directory with the extention .tf.

Terraform providers

A Terraform Provider represents an integration that is responsible for understanding API interactions with the underlying infrastructure. In our case its Digital ocean.

This code logic defines digital ocean provider:

terraform {
  required_providers {
    digitalocean = {
      source  = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

Variables

Terraform Variables are a way to define centrally controlled reusable values. It is essentially inputs that are passed when executing the terraform scripts or to a module.

Lets define variables in our code:

variable "do_token" {}

The variable defined above is for the token that will be used to authenticate with Digital Ocean.

Terraform data

Terraform data block requests that Terraform read from a given data source and export the result under the given local name. In this example, lets use data to read an already created ssh key in digital ocean called my-pub. This will be exported under the name my_key so it can be accessed using data.digitalocean_ssh_key.my_key:

data "digitalocean_ssh_key" "my_key" {
  name = "my-pub"
}

Digital ocean droplet

Lets now create a droplet pasing in the required inputs such as name, image, region, size and ssh keys to use when creating it. The values such as image, region, and size can be obtained using doctl command as shown above.

resource "digitalocean_droplet" "app_server" {
  image              = "rockylinux-8-x64"
  name               = "app-server"
  region             = "fra1"
  size               = "s-2vcpu-2gb"
  private_networking = true
  monitoring         = true

  ssh_keys = [
    data.digitalocean_ssh_key.my_key.id
  ]
}

Terraform outputs

Terraform output values allow you to export structured data about your resources. In our case, we can use outputs to export data about the instance we just created like the IP that it has been assignend, any private IPs, the server id, etc:

output "app_server_id" {
  value = digitalocean_droplet.app_server.id
}

output "app_server_name" {
  value = digitalocean_droplet.app_server.name
}

output "app_server_ipv4" {
  value = digitalocean_droplet.app_server.ipv4_address
}

output "app_server_ipv4_private" {
  value = digitalocean_droplet.app_server.ipv4_address_private
}

output "app_server_price_hourly" {
  value = digitalocean_droplet.app_server.price_hourly
}

output "app_server_price_monthly" {
  value = digitalocean_droplet.app_server.price_monthly
}

output "app_server_size" {
  value = digitalocean_droplet.app_server.size
}

output "app_server_disk" {
  value = digitalocean_droplet.app_server.disk
}

output "app_server_vcpus" {
  value = digitalocean_droplet.app_server.vcpus
}

Final code

This is the whole code. It can be saved in a single file in the current directory.

terraform {
  required_providers {
    digitalocean = {
      source  = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

variable "do_token" {}

provider "digitalocean" {
  token = var.do_token
}

data "digitalocean_ssh_key" "my_key" {
  name = "my-pub"
}

resource "digitalocean_droplet" "app_server" {
  image              = "rockylinux-8-x64"
  name               = "app-server"
  region             = "fra1"
  size               = "s-2vcpu-2gb"
  private_networking = true
  monitoring         = true

  ssh_keys = [
    data.digitalocean_ssh_key.my_key.id
  ]
}

output "app_server_id" {
  value = digitalocean_droplet.app_server.id
}

output "app_server_name" {
  value = digitalocean_droplet.app_server.name
}

output "app_server_ipv4" {
  value = digitalocean_droplet.app_server.ipv4_address
}

output "app_server_ipv4_private" {
  value = digitalocean_droplet.app_server.ipv4_address_private
}

output "app_server_price_hourly" {
  value = digitalocean_droplet.app_server.price_hourly
}

output "app_server_price_monthly" {
  value = digitalocean_droplet.app_server.price_monthly
}

output "app_server_size" {
  value = digitalocean_droplet.app_server.size
}

output "app_server_disk" {
  value = digitalocean_droplet.app_server.disk
}

output "app_server_vcpus" {
  value = digitalocean_droplet.app_server.vcpus
}

Executing terraform

To create the defined resources, execute the terraform code with the following commands passing the defined token as a variable. The variable is exported as an env variable with the bash export DO_TOKEN=xxxxx command:

Running the plan

terraform plan -destroy -out=terraform.tfplan \
  -var "do_token=${DO_TOKEN}" \

To view the current state of your changes, use the following command:

terraform show terraform.tfstate

Applying the changes

export DO_TOKEN=xxxxx
terraform apply \
  -var "do_token=${DO_TOKEN}" 

# Or this using the output state file
terraform apply terraform.tfplan

Conclusion

In this guide we went through the steps needed to create a vps in digital ocean.

I am a Devops Engineer, but I would describe myself as a Tech Enthusiast who is a fan of Open Source, Linux, Automations, Cloud and Virtualization. I love learning and exploring new things so I blog in my free time about Devops related stuff, Linux, Automations and Open Source software. I can also code in Python and Golang.

Write A Comment