Terraform on Linode Notes
Posted on
Over vacation I worked through a small project to use Terraform on Linode to provision a new webserver for my personal website. The following is a collection of notes and resources from the experience.
Project Goals / Areas of Improvement:
- Since the addition of the
guildflow.comstatic website, anyone who was attempting to load a HTTPS version ofmikezornek.comwould be met with a security warning as the browser was attempting to load the SSL cert forguildflow.comwhen serving upmikezornek.com. - The lack of SSL to
mikezornek.comhas historically been intentional. - The Linode serving my static sites uses Ubuntu 16.04 LTS, which is going to be EOL on April 30, 2021 and so it’d be good to get one a new LTS version.
- This is a good excuse to experiment with Terraform, which is something I’ve been learning in support of some possible Guildflow infrastructure updates.
Quick Review of the MikeZornek.com Infrastructure and Deployment
- MikeZornek is a static site. I like static sites as they are cheaper to serve and easier to keep secure. I have used WordPress in the distant pass but I was lazy at keeping it updated and eventually it was hacked.
- Hugo is used to help build the static site.
- The git repo is public and hosted on GitHub.
- I’ve setup CircleCI to detect changes on the repo’s
masterbranch and deploy any changes. - The deploy is pretty basic but there are a few HTML/link checks.
- Once generated, the static files are copied to my Linode using
rsync. - The historic Linode was hand crafted and used Apache as it’s web server.
Learning Terraform Resources
- Linode-specific tutorials
- Learn the Linode regions or instance types through it’s API.
- The Terraform Book
- Linode Terraform provider docs.
- Linode Community Questions: how to debug stack scripts
- Certbot for Ubuntu / ngnix prefers snap now.
- Managing multiple SSH keys.
My Terraform Script
provider "linode" {
# API Token
token = "abc123"
}
resource "linode_sshkey" "mikezornek_linode_ssh_key" {
label = "mikezornek_linode_ssh_key"
ssh_key = chomp(file("~/.ssh/id_rsa_linode_mikezornek.pub"))
}
resource "linode_stackscript" "setup_mikezornek_prod" {
label = "setup_mikezornek_prod"
description = "setups nginx and certbot for mikezornek"
script = file("files/setup.sh")
images = ["linode/ubuntu20.04"]
is_public = false
}
resource "linode_instance" "mikezornek_prod" {
image = "linode/ubuntu20.04"
label = "mikezornek_prod"
group = "mikezornek"
region = "us-east"
type = "g6-nanode-1"
authorized_keys = [linode_sshkey.mikezornek_linode_ssh_key.ssh_key]
# Leave the root password unset if want to keep it random
root_pass = "abc123"
backups_enabled = true
stackscript_id = linode_stackscript.setup_mikezornek_prod.id
}
output "server_ip" {
value = linode_instance.mikezornek_prod.ip_address
}
The output is useful if you want to ssh into your new linode instance right away with:
$ ssh root@(terraform output server_ip)
My setup bash script
#!/bin/bash
# strict mode
set -xeo pipefail
exec > >(tee -i /var/log/stackscript.log)
FQDN=mikezornek.com
echo Setting hostname to ${FQDN}
hostnamectl set-hostname ${FQDN}
echo Running apt-get update and upgrade
apt update && apt upgrade -y
echo Installing nginx
apt install -y nginx
echo Prep snap
snap install core; snap refresh core
echo Install certbot
snap install --classic certbot
# echo Setup certbot for nginx for the domain ${FQDN}
# we will do this manually after setup since the
# domain should be pointing at this machine at the time of setup
# certbot --nginx --agree-tos -m zorn@zornlabs.com --verbose -d mikezornek.com
echo Starting nginx
sudo service nginx start
echo ALL DONE!
Observe the log file on your new server with:
$ tail -f /var/log/stackscript.log
About the Author. Mike Zornek is a developer and teacher focusing on product design and development with a heavy focus on Elixir and LiveView. In between his projects, Mike helps other teams through consulting. During off hours, he enjoyed watching Phillies baseball and playing relaxing video games.
Hopefully, you found interest in my scribbles. If you have commentary or a response, I'd love to hear it.