This weekend I started working on revamping my website. I decided to use Terraform's DigitalOcean Provider to generate a new droplet, import my domain name, and implement new DNS records and a firewall. First up, the provider (providers.tf) along with the variable to feed in the token (variables.tf).
provider "digitalocean" {
token = var.do_token
}
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
}
}
}
variable "do_token" {
type = string
}
You see where the token is injected allowing us to talk to DigitalOcean's API. This allows us to create our
droplet, as shown below (main.tf). Note the ssh_keys argument is the ID of the one I already set up on my
DigitalOcean
account.
resource "digitalocean_droplet" "web" {
image = "ubuntu-20-04-x64"
name = "bakey-us"
region = "nyc3"
size = "s-1vcpu-1gb"
ssh_keys = [
13895248
]
}
And what good is a server with no DNS record? We'll create that and some CAA records for LetsEncrypt (dns.tf).
resource "digitalocean_domain" "bakey-us" {
name = "bakey.us"
}
# Add an A record to the domain for www.bakey.us
resource "digitalocean_record" "www" {
domain = digitalocean_domain.bakey-us.name
type = "A"
name = "www"
value = digitalocean_droplet.web.ipv4_address
}
resource "digitalocean_record" "caa-wild" {
domain = digitalocean_domain.bakey-us.name
type = "CAA"
name = "*.bakey.us."
value = "letsencrypt.org."
tag = "issuewild"
flags = 0
}
resource "digitalocean_record" "caa" {
domain = digitalocean_domain.bakey-us.name
type = "CAA"
name = "www.bakey.us."
value = "letsencrypt.org."
tag = "issue"
flags = 0
}
Last we'll make sure our firewall is set up appropriately to allow web and ssh traffic inbound, as well as all
traffic outbound (firewall.tf).
resource "digitalocean_firewall" "www" {
name = "www-bakey-us"
droplet_ids = [ digitalocean_droplet.web.id ]
inbound_rule {
protocol = "tcp"
port_range = "22"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "icmp"
source_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "tcp"
port_range = "1-65535"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "udp"
port_range = "1-65535"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "icmp"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
}
All these get checked into GitHub and connected to a Terraform workspace at app.terrafrom.io. This takes me from an empty slate to a running machine I can SSH into
using a key I've already provided. This is important for part 2 coming next - configuring this droplet for
LetsEncrypt (certbot), Docker, and a GitHub runner using Ansible.
Posted 2021-01-31