My Home Server Setup: Part 2/N
In this part, I’ll be setting up Nomad and Consul cluster communicating internally using Tailscale VPN.
so I can schedule different workloads (I’ll discuss them in coming parts) on them.
I’ve added ansible for the all the parts of the installation which can be found in my DragonBallWorld GitHub repo
Below is HLD of the Nomad and Consul architecture which I’ve chosen for my Home Server.

Tailscale Setup
I’ve written a ansible role to setup tailscale on my nodes. It can be found here.
Initially we’ll require non tailscale IP (ofc !) to run ansible on the nodes. I’ve my ~/.ssh/config
to take care of username and ip
Host goku
hostname SOMEIP1
user itsjwala
Host gohan
hostname SOMEIP2
user itsjwala
To add tailcale_auth_key
inside your `secrets.yml` variable file head over to tailscale admin panel and generate an auth key, you can decide between one-off or reusable key.

- include_vars: secrets.yml
tags:
- always
# ... skipped for brevity
- name: Install Tailscale
apt:
name: tailscale
state: present
update_cache: yes
notify: enable tailscaled service
# ....
- name: Bring Tailscale Up
become: yes
command: tailscale up --authkey={{ tailscale_auth_key }}
register: tailscale_start
when: '"100." not in tailscale_status.stdout'
notify: Confirm Tailscale is Connected
Once tailscale is setup, you can see it in by sshing into the node, or inside tailscale admin panel or on other clients ( my mac from which I’m running the ansible).. neat!


I updated my ~/.ssh/config
to use tailscale IP now, so no changing of routers allocated IP going forward ( yeah I can do static IP on router page 😃)
Consul Setup
Ansible setup here
we’ll be required to setup consul first so Nomad can use it to do service discovery of Nomad nodes.
jinja templated consul config file.
datacenter = "DragonBallWorld"
data_dir = "/opt/consul/data"
encrypt = "{{ consul_encryption_key }}"
{% if is_server is defined and is_server %}
server = true
bootstrap_expect = 1
{% endif %}
client_addr = "{{ ansible_facts.tailscale0.ipv4.address }}"
bind_addr = "{{ ansible_facts.tailscale0.ipv4.address }}"retry_join = ["{{ hostvars['gohan']['ansible_facts']['tailscale0']['ipv4']['address'] }}"]
ui = true
This line will ask consul agents to connect to gohan
which is consul server
retry_join = ["{{ hostvars['gohan']['ansible_facts']['tailscale0']['ipv4']['address'] }}"]
is_server
is picked up based on inventory hosts
file
[DragonBallWorld]
goku
gohan is_server=True
consul_encrytion_key
was generated using, this will ensure encrypted gossiping between accross network (overkill for now, can be skipped)
itsjwala@goku:~$ consul keygen
6vgkXs8JjT7tiDTXq9AWeVcl81zMkhyp6cN88kIZQk4=
The Beautiful UI looks something like this!

Nomad Setup
Ansible setup here
going through the config file
data_dir = "/opt/nomad/data"
bind_addr = "{{ ansible_facts.tailscale0.ipv4.address }}"
datacenter = "DragonBallWorld"
{% if is_server is defined and is_server %}
server {
enabled = true
bootstrap_expect = 1
encrypt = "{{ nomad_encryption_key }}"
}
{% endif %}client {
enabled = true
host_network "tailscale" {
cidr = "{{ ansible_facts.tailscale0.ipv4.address }}/32"
reserved_ports = "22"
} # ^^^ ignore for now, I'll use this host_network to schedule
# internal applications}
plugin "docker" { # <---- Install docker for this
config {
volumes {
enabled = true
}
}
}
plugin "raw_exec" {
config {
enabled = true
}
}
telemetry {
collection_interval = "15s"
disable_hostname = true
prometheus_metrics = true
publish_allocation_metrics = true
publish_node_metrics = true
}
consul {
address = "{{ ansible_facts.tailscale0.ipv4.address }}:8500"
}# ^^^ The consul agent which resides on each node
After Nomad is restarted. It will ask Consul for Nomad Clients discovery so they could form a cluster. and it happens automagically!

Since Nomad is binded on tailscale
interface we’ll require to update NOMAD_ADDR
to access nomad interface using cli

Also can be navigated using the Beautiful UI!

Now that this is done, I’m also planning to add samba server
on RPi.
I also plan to set up a few applications on them, the first being Caddyserver
which is feature-rich (proxy, TLS certs auto-rotation, what not!)
more on it in later parts, till then see yeah 👋