Skip to content

Commit

Permalink
Merge pull request #38 from wenzel-felix/feature/bootstrap_option
Browse files Browse the repository at this point in the history
Feature/bootstrap option
  • Loading branch information
wenzel-felix committed Mar 3, 2023
2 parents 2e15d6b + c247df9 commit 1e0bda3
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 154 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
This module allows you to create a manually-scalable high-availability nomad cluster on Hetzner Cloud.
You only need to provide a API token as variable and a default cluster with 3 servers and 1 client will be created.

## Dependencies
- [jq](https://stedolan.github.io/jq/)

## Advanced Usage

The module is mainly addressed to people who want to test the technology running terraform on their local PC, but it can be used in professional workflows as well.
4 changes: 0 additions & 4 deletions examples/advanced-setup/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ output "server_info" {
value = module.hetzner-nomad-consul.server_info
}

output "nomad_token" {
value = module.hetzner-nomad-consul.nomad_token
}

output "nomad_address" {
value = module.hetzner-nomad-consul.nomad_address
}
Expand Down
Empty file modified examples/advanced-setup/nomad/jobs/demo-webapp.nomad
100644 → 100755
Empty file.
Empty file modified examples/advanced-setup/nomad/jobs/traefik.nomad
100644 → 100755
Empty file.
Empty file modified examples/advanced-setup/nomad/main.tf
100644 → 100755
Empty file.
3 changes: 0 additions & 3 deletions hcloud_load_balancer.tf
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
resource "hcloud_load_balancer" "load_balancer" {
depends_on = [
null_resource.fetch_nomad_token
]
name = "nomad-load-balancer"
load_balancer_type = "lb11"
location = var.hetzner_datacenter
Expand Down
28 changes: 7 additions & 21 deletions hcloud_server.tf
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ resource "hcloud_server" "main" {
ipv6_enabled = false
}

user_data = file("${path.module}/scripts/base_configuration.sh")
user_data = templatefile("${path.module}/scripts/base_configuration.sh", {
CONSUL_VERSION = var.apt_consul_version
NOMAD_VERSION = var.apt_nomad_version
})

provisioner "remote-exec" {
inline = [
"echo 'Waiting for cloud-init to complete...'",
"cloud-init status --wait > /dev/null",
"echo 'Completed cloud-init!'",
"echo 'Completed cloud-init!'"
]

connection {
Expand All @@ -53,11 +56,13 @@ resource "null_resource" "deployment" {
provisioner "file" {
content = each.value.type == "server" ? templatefile("${path.module}/scripts/server_setup.sh",
{
bootstrap = var.bootstrap
SERVER_COUNT = length(local.Server_Count)
IP_RANGE = local.IP_range
SERVER_IPs = jsonencode([for key, value in local.Extended_Aggregator_IPs : value.private_ipv4[0] if value.type == "server"])
}) : templatefile("${path.module}/scripts/client_setup.sh",
{
bootstrap = var.bootstrap
SERVER_COUNT = length(local.Server_Count)
IP_RANGE = local.IP_range
SERVER_IPs = jsonencode([for key, value in local.Extended_Aggregator_IPs : value.private_ipv4[0] if value.type == "server"])
Expand All @@ -73,24 +78,6 @@ resource "null_resource" "deployment" {
}
}

resource "time_sleep" "wait_60_seconds" {
depends_on = [null_resource.deployment]
create_duration = "60s"
}

resource "null_resource" "fetch_nomad_token" {
depends_on = [time_sleep.wait_60_seconds]

provisioner "local-exec" {
command = <<EOF
for i in ${join(" ", [for server in hcloud_server.main : server.ipv4_address if length(regexall("server.*", server.name)) > 0])}
do
ssh -i ${path.root}/certs/machines.pem -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null" root@$i curl --request POST http://localhost:4646/v1/acl/bootstrap | jq -r -R 'fromjson? | .SecretID?' >> ${path.root}/certs/nomad_token
done
EOF
}
}

resource "local_file" "private_key" {
content = tls_private_key.machines.private_key_openssh
filename = "${path.root}/certs/machines.pem"
Expand All @@ -109,7 +96,6 @@ resource "hcloud_ssh_key" "default" {
resource "null_resource" "clean_up" {
provisioner "local-exec" {
command = <<EOF
rm -f ${path.root}/certs/nomad_token
rm -f ${path.root}/certs/machines.pem
EOF
when = destroy
Expand Down
8 changes: 4 additions & 4 deletions output.tf
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ output "server_info" {
}
}

output "nomad_token" {
value = fileexists("certs/nomad_token") ? trimspace(file("certs/nomad_token")) : "Could not find nomad token file from initial bootstrap. If this is your initial apply, please create a GitHub issue."
}

output "nomad_address" {
value = "http://${hcloud_load_balancer.load_balancer.ipv4}:80"
}

output "network_id" {
value = hcloud_network.network.id
}

output "tls_private_key" {
value = tls_private_key.machines.private_key_pem
}
129 changes: 23 additions & 106 deletions scripts/base_configuration.sh
Original file line number Diff line number Diff line change
@@ -1,110 +1,27 @@
#!/bin/bash

# Update the server and install needed packages
apt update
apt upgrade -y
apt install unzip jq -y
cd /root/

# To install HashiCorp Consul, we need to download and install the respective binary. First, define the version and host in an environment variable
export CONSUL_VERSION="1.14.3"
export CONSUL_URL="https://releases.hashicorp.com/consul"

# Download the binary, decompress it and install it on your server
curl --silent --remote-name ${CONSUL_URL}/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip
unzip consul_${CONSUL_VERSION}_linux_amd64.zip
chown root:root consul
mv consul /usr/local/bin/
rm consul_${CONSUL_VERSION}_linux_amd64.zip

# We can now add autocomplete functionality for Consul (optional)
consul -autocomplete-install
complete -C /usr/local/bin/consul consul

# Create a user for Consul
useradd --system --home /etc/consul.d --shell /bin/false consul
mkdir --parents /opt/consul
chown --recursive consul:consul /opt/consul

# Prepare the Consul configuration
mkdir --parents /etc/consul.d
touch /etc/consul.d/consul.hcl
chown --recursive consul:consul /etc/consul.d
chmod 640 /etc/consul.d/consul.hcl

# Similar to the Consul binary, we first define the version as a variable
export NOMAD_VERSION="1.4.3"

# Download and install the binary
curl --silent --remote-name https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/nomad_${NOMAD_VERSION}_linux_amd64.zip
unzip nomad_${NOMAD_VERSION}_linux_amd64.zip
chown root:root nomad
mv nomad /usr/local/bin/
rm nomad_${NOMAD_VERSION}_linux_amd64.zip

# Add autocomplete functionality to nomad (optional)
nomad -autocomplete-install
complete -C /usr/local/bin/nomad nomad

# Prepare the data directory
mkdir --parents /opt/nomad

# Create the basic configuration file for nomad
mkdir --parents /etc/nomad.d
chmod 700 /etc/nomad.d
curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -
apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
apt-get update
apt-get upgrade -y
apt-get install jq -y
apt-get install -y consul=${CONSUL_VERSION}
apt-get install -y nomad=${NOMAD_VERSION}


chown -R consul:consul /etc/consul.d
chmod -R 640 /etc/consul.d/*


chown -R nomad:nomad /etc/nomad.d
chmod -R 640 /etc/nomad.d/*

cat <<EOF > /etc/nomad.d/nomad.hcl
datacenter = "dc1"
data_dir = "/opt/nomad"
EOF

# Consul and Nomad should start automatically after boot. To enable this, create a systemd service for both of them.
cat <<EOF > /etc/systemd/system/consul.service
[Unit]
Description="HashiCorp Consul - A service mesh solution"
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/consul.d/consul.hcl
[Service]
Type=exec
User=consul
Group=consul
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d/
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

cat <<EOF > /etc/systemd/system/nomad.service
[Unit]
Description=Nomad
Documentation=https://www.nomadproject.io/docs
Wants=network-online.target
After=network-online.target
[Service]
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/nomad agent -config /etc/nomad.d
KillMode=process
KillSignal=SIGINT
LimitNOFILE=infinity
LimitNPROC=infinity
Restart=on-failure
RestartSec=2
StartLimitBurst=3
StartLimitIntervalSec=10
TasksMax=infinity
[Install]
WantedBy=multi-user.target
EOF

# Configure auto updates and security patches
apt install unattended-upgrades -y

Expand All @@ -115,17 +32,17 @@ EOF

cat <<EOF > /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
"\${distro_id}:\${distro_codename}";
"\${distro_id}:\${distro_codename}-security";
"\$${distro_id}:\$${distro_codename}";
"\$${distro_id}:\$${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"\${distro_id}ESMApps:\${distro_codename}-apps-security";
"\${distro_id}ESM:\${distro_codename}-infra-security";
"\${distro_id}:\${distro_codename}-updates";
"\${distro_id}:\${distro_codename}-proposed";
// "\${distro_id}:\${distro_codename}-backports";
"\$${distro_id}ESMApps:\$${distro_codename}-apps-security";
"\$${distro_id}ESM:\$${distro_codename}-infra-security";
"\$${distro_id}:\$${distro_codename}-updates";
"\$${distro_id}:\$${distro_codename}-proposed";
// "\$${distro_id}:\$${distro_codename}-backports";
};
// Python regular expressions, matching packages to exclude from upgrading
Expand Down
2 changes: 1 addition & 1 deletion scripts/client_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ client {
}
acl {
enabled = true
%{ if bootstrap }enabled = false%{ else }enabled = true%{ endif }
}
EOF

Expand Down
13 changes: 1 addition & 12 deletions scripts/server_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ server {
}
acl {
enabled = true
%{ if bootstrap }enabled = false%{ else }enabled = true%{ endif }
}
EOF

Expand All @@ -55,15 +55,4 @@ systemctl enable nomad
systemctl start consul
systemctl start nomad

# consul acl bootstrap -format=json | jq -r -R 'fromjson? | .SecretID?' > /etc/consul.d/acl_master_token
# export CONSUL_HTTP_TOKEN=$(cat /etc/consul.d/acl_master_token)
# export CONSUL_HTTP_ADDR="http://127.0.0.1:8500"
# To check the cluster, run the following command on one of your servers
#consul members
#sleep 10
#curl --request POST http://localhost:4646/v1/acl/bootstrap | jq -r '.SecretID' > nomad_token

# Since we use ACLs (Access Control Lists) on Nomad, we have to get the bootstrap token first, before checking the status here as well.
#nomad server members

#reboot
18 changes: 18 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,26 @@ variable "hetzner_datacenter" {
default = "hel1"
}

variable "bootstrap" {
type = bool
description = "Bootstrap Nomad without ACLs"
default = true
}

variable "hetzner_network_zone" {
type = string
description = "Hetzner Cloud Network Zone"
default = "eu-central"
}

variable "apt_consul_version" {
type = string
description = "Consul version to install"
default = "1.15.0-1"
}

variable "apt_nomad_version" {
type = string
description = "Nomad version to install"
default = "1.5.0-1"
}

0 comments on commit 1e0bda3

Please sign in to comment.