Terraform

Prerequisites

For self-hosting You need a public IP address to reach services on Your network.

I do not have static public IP address, so I decided to buy1 a VPS service. I use Linode, but feel free to chose anything else or use Your own IP if You have one. This server is public, works as admin server and ingress for Netmaker, secondary DNS and other services.

If You have a public IP feel free to use some of Your computers for self hosting. For Netmaker You do not need anything beefy, some Raspberry Pi or alike can handle the job as well. Do not forget however that electricity is not free and it can be noisy, so do not put it in the bedroom.

WARNING: The code below is Linode specific. You do not have to use Linode, feel free to change these files, but I can not cover every provider here. Check out the terraform registry for details!

Configuring the admin server

I recommend downloading and altering my config:

git clone https://git.sr.ht/~voroskoi/infra

We will use Terraform for deploying our admin server. Let’s take a look at the code:

Variables starting with var will be explained below.

1provider "linode" {
2 token = var.linode_token # read token from variables.tf
3}
4
5terraform {
6 required_providers {
7 linode = {
8 source = "linode/linode"
9 version = "1.29.2"
10 }
11 }
12}
13
14resource "linode_instance" "admin-server" {
15 image = "linode/alpine3.16"
16 label = "${var.hostname}"
17 group = "Terraform"
18 region = "eu-central"
19 type = "g6-nanode-1"
20 authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICi3kEe8bc1C/knZtsD4qswDZj1wkwDuKDSwfhdCPtcU"]
21 root_pass = "${var.root_password}"
22 backups_enabled = false
23
24 connection {
25 type = "ssh"
26 user = "root"
27 password = "${var.root_password}"
28 host = self.ip_address
29 }
30
31 # remote-exec waits for the instance setup, so local-exec below will not fail immediatelly
32 provisioner "remote-exec" {
33 inline = [ "/bin/true" ]
34 }
35
36 provisioner "local-exec" {
37 command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -e 'wheel_login=${var.wheel_login} hostname=${self.label}' -u root -i '${self.ip_address},' admin-init.yml"
38 }
39}

I have highlighted the lines You should check before doing anything:

  • Line 15: Make sure You use the latest stable version available!
  • Line 18: Chose a region near to You!
  • Line 19: This is the cheapest, smallest one. Upgrade if You need more!
  • Line 20: That is my public key, change it unless You want me to login to Your server as root. :-)

You can inspect the available images with:

curl https://api.linode.com/v4/images |jq

These are the variables, taken from here.

variable "linode_token" {
  type = string
  description = "Linode token"
  default = "bab13e33ac5afbb6fed8b97374ff5dfac10a97d581a342aa4410ae08b1991a50" # revoked
}

variable "hostname" {
  type = string
  description = "hostname of admin server"
  # default = "kistasli"
  sensitive = false
}

variable "root_password" {
  type = string
  description = "root password"
  sensitive = true
}

variable "wheel_login" {
  type = string
  description = "User name for administrative user"
  sensitive = false
}

You can generate a token in Linode Cloud. You have to grant read/write permission to Events and Linodes.

WARNING: Please, do not forget to revoke Your API token after setting things up. You can recreate them anytime. And make sure You never-ever commit or paste them anywhere!

Deploying on Linode

Now, everything is set, time to deploy:

  • install Terraform and Ansible (apk add terraform ansible)
  • install community.general collection for Ansible (ansible-galaxy collection install community.general)
  • cd infra/kistasli
  • terraform init: this will download the Linode provider, do not remove the files it creates!
  • terraform apply: prints out what will happen. If You say yes then deploying (and billing) starts!

If something goes wrong terraform apply can modify, terraform destroy can erase the current image.

When Terraform finishes You have an Alpine Linux server in the cloud. \o/

First login

You can see the IP of Your Linode in terraform output or when You login to Linode Cloud.

For the first time You have to login with root:

ssh root@<my-brand-new-ip>

Make sure You do the following:

  • Change the password of the admin user we created with passwd user. The initial password is empty, so You can not use ssh with that login until You do this.
  • Before logging out as root, check if the user login works!
  • Disable root login and password login. (Recommended)

That’s it. Check out the next part!

1 Technically that is not true: There are plenty Linode (and other) VPS coupons which is a perfect opportunity for lurking around, but unless You want to move Your setup in every 2-3 month prepare for paying.