Automatic Deployments with Terraform
Published on
Updated on
I have recently written about Packer to create system images or snapshots. This post will go over another HashiCorp project named Terraform that we can use to deploy that image to a VPS. Like before, I am going to go over how to setup this up in DigitalOcean. Check out this list for documentation on your favorite cloud provider.
Variables
To protect against committing secrets like API keys, we’re going to create a file that only stores variables. For it to be loaded automatically, it needs to be named terraform.tfvars
. Here is an example configuration:
region = "nyc3"
size = "512mb"
domain = "example.com"
subdomain = "temp"
# Secrets
do_token = "DO-TOKEN-HERE"
key_name = "SSH-KEY-NAME-ON-DO"
Now to define the variables in HCL, we need to create a separate variables.tf
file defining their types
variable "do_token" {
type = string
}
variable "domain" {
type = string
}
variable "key_name" {
type = string
}
variable "subdomain" {
type = string
}
variable "region" {
type = string
}
variable "size" {
type = string
}
Configuration
Now let’s create a file called do.tf
. We need to start off by stating which provider we are using
provider "digitalocean" {
token = var.do_token
}
If you want to hook up your SSH key, then we need to query the Digital Ocean API for its ID.
data "digitalocean_ssh_key" laptop {
name = var.key_name
}
We need to also query the API for the packer snapshot we created. Replace this with any standard image like "ubuntu-20-04-x64"
if you don’t want to use a snapshot.
data "digitalocean_droplet_snapshot" "packer_snapshot" {
name = "packer-example"
most_recent = true
}
Now we can create the droplet
resource "digitalocean_droplet" "web" {
name = "tf-1"
image = data.digitalocean_droplet_snapshot.packer_snapshot.id
region = var.region
size = var.size
ssh_keys = [data.digitalocean_ssh_key.laptop.id]
backups = false
}
Attach a domain to the droplet
resource "digitalocean_record" "www" {
domain = var.domain
type = "A"
name = var.subdomain
value = digitalocean_droplet.web.ipv4_address
}
Output useful pieces of information like the new system’s IP address and the domain
output "ip" {
value = digitalocean_droplet.web.ipv4_address
}
output "domain" {
value = "${digitalocean_record.www.name}.${digitalocean_record.www.domain}"
}
The whole configuration file for your convenience:
provider "digitalocean" {
token = var.do_token
}
data "digitalocean_ssh_key" laptop {
name = var.key_name
}
data "digitalocean_droplet_snapshot" "packer_snapshot" {
name = "packer-example"
most_recent = true
}
# Create a droplet
resource "digitalocean_droplet" "web" {
name = "tf-1"
image = data.digitalocean_droplet_snapshot.packer_snapshot.id
region = var.region
size = var.size
ssh_keys = [data.digitalocean_ssh_key.laptop.id]
backups = false
}
# Attach a subdomain
resource "digitalocean_record" "www" {
domain = var.domain
type = "A"
name = var.subdomain
value = digitalocean_droplet.web.ipv4_address
}
output "ip" {
value = digitalocean_droplet.web.ipv4_address
}
output "domain" {
value = "${digitalocean_record.www.name}.${digitalocean_record.www.domain}"
}
Deploy
Check if your configuration is valid
terraform plan
Deploy!
terraform apply
Take down when done
terraform destroy