Initial IaC setup: Nomad, Consul, Terraform, Ansible
- Ansible roles for Nomad and Consul installation - Nomad job specs for Traefik and monitoring stack - Terraform configuration for Nomad job management - Enterprise naming convention inventory - HashiCorp stack deployment playbook
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
---
|
||||
# Hobbs.farm Infrastructure Inventory
|
||||
# Naming: <location>-<type><function>-<sequence>
|
||||
|
||||
all:
|
||||
vars:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
domain: hobbs.farm
|
||||
timezone: America/Chicago
|
||||
|
||||
# HashiCorp versions
|
||||
nomad_version: "1.7.3"
|
||||
consul_version: "1.17.2"
|
||||
vault_version: "1.15.4"
|
||||
|
||||
# Cluster settings
|
||||
datacenter: hf-dc1
|
||||
|
||||
# Data paths
|
||||
nomad_data_dir: /opt/nomad
|
||||
consul_data_dir: /opt/consul
|
||||
vault_data_dir: /opt/vault
|
||||
|
||||
children:
|
||||
# =========================================
|
||||
# Nomad Cluster
|
||||
# =========================================
|
||||
nomad_servers:
|
||||
hosts:
|
||||
hf-pdocker-01:
|
||||
nomad_server: true
|
||||
nomad_client: true
|
||||
nomad_bootstrap_expect: 1
|
||||
|
||||
nomad_clients:
|
||||
hosts:
|
||||
hf-pdocker-01:
|
||||
nomad_client: true
|
||||
nomad_node_class: "primary"
|
||||
hf-pdocker-02:
|
||||
nomad_client: true
|
||||
nomad_node_class: "secondary"
|
||||
|
||||
# =========================================
|
||||
# Consul Cluster
|
||||
# =========================================
|
||||
consul_servers:
|
||||
hosts:
|
||||
hf-pdocker-01:
|
||||
consul_server: true
|
||||
consul_bootstrap_expect: 1
|
||||
|
||||
consul_clients:
|
||||
hosts:
|
||||
hf-pdocker-01:
|
||||
hf-pdocker-02:
|
||||
|
||||
# =========================================
|
||||
# Vault Cluster
|
||||
# =========================================
|
||||
vault_servers:
|
||||
hosts:
|
||||
hf-pdocker-01:
|
||||
vault_server: true
|
||||
|
||||
# =========================================
|
||||
# Physical Hosts
|
||||
# =========================================
|
||||
physical:
|
||||
children:
|
||||
docker_hosts:
|
||||
hosts:
|
||||
hf-pdocker-01:
|
||||
ansible_host: 192.168.86.192
|
||||
ansible_user: glyptic
|
||||
ansible_become_password: "{{ vault_sudo_password }}"
|
||||
legacy_name: hobbs
|
||||
role: primary
|
||||
|
||||
hf-pdocker-02:
|
||||
ansible_host: 192.168.86.45
|
||||
ansible_user: glyptic
|
||||
ansible_ssh_private_key_file: ~/.ssh/id_docker_server
|
||||
legacy_name: peggy
|
||||
role: secondary
|
||||
status: degraded
|
||||
|
||||
nvr_hosts:
|
||||
hosts:
|
||||
hf-pnvr-01:
|
||||
ansible_host: 192.168.86.181
|
||||
ansible_user: glyptic
|
||||
ansible_ssh_private_key_file: ~/.ssh/id_docker_server
|
||||
legacy_name: bart
|
||||
|
||||
# =========================================
|
||||
# Network & Storage (reference only)
|
||||
# =========================================
|
||||
network:
|
||||
hosts:
|
||||
hf-nfw-01:
|
||||
ansible_host: 192.168.86.1
|
||||
legacy_name: firewalla
|
||||
|
||||
storage:
|
||||
hosts:
|
||||
hf-snas-01:
|
||||
ansible_host: 192.168.86.30
|
||||
legacy_name: nas
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
# Install HashiCorp Stack (Nomad, Consul, Vault)
|
||||
# Run: ansible-playbook -i inventory/hosts.yml playbooks/hashicorp-stack.yml
|
||||
|
||||
- name: Install Consul
|
||||
hosts: consul_servers:consul_clients
|
||||
become: yes
|
||||
roles:
|
||||
- consul
|
||||
tags: [consul]
|
||||
|
||||
- name: Install Vault
|
||||
hosts: vault_servers
|
||||
become: yes
|
||||
roles:
|
||||
- vault
|
||||
tags: [vault]
|
||||
|
||||
- name: Install Nomad
|
||||
hosts: nomad_servers:nomad_clients
|
||||
become: yes
|
||||
roles:
|
||||
- nomad
|
||||
tags: [nomad]
|
||||
|
||||
- name: Bootstrap Nomad cluster
|
||||
hosts: nomad_servers[0]
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Wait for Nomad to be ready
|
||||
ansible.builtin.uri:
|
||||
url: "http://{{ ansible_host }}:4646/v1/status/leader"
|
||||
method: GET
|
||||
status_code: 200
|
||||
register: nomad_leader
|
||||
until: nomad_leader.status == 200
|
||||
retries: 30
|
||||
delay: 5
|
||||
|
||||
- name: Display Nomad leader
|
||||
ansible.builtin.debug:
|
||||
msg: "Nomad leader: {{ nomad_leader.json }}"
|
||||
tags: [nomad, bootstrap]
|
||||
|
||||
- name: Verify cluster health
|
||||
hosts: nomad_servers[0]
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Check Nomad node status
|
||||
ansible.builtin.command: nomad node status
|
||||
register: nomad_nodes
|
||||
changed_when: false
|
||||
|
||||
- name: Display nodes
|
||||
ansible.builtin.debug:
|
||||
var: nomad_nodes.stdout_lines
|
||||
|
||||
- name: Check Consul members
|
||||
ansible.builtin.command: consul members
|
||||
register: consul_members
|
||||
changed_when: false
|
||||
|
||||
- name: Display Consul members
|
||||
ansible.builtin.debug:
|
||||
var: consul_members.stdout_lines
|
||||
tags: [verify]
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Restart Consul
|
||||
ansible.builtin.systemd:
|
||||
name: consul
|
||||
state: restarted
|
||||
daemon_reload: yes
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
# Consul Installation Role
|
||||
|
||||
- name: Add HashiCorp GPG key
|
||||
ansible.builtin.apt_key:
|
||||
url: https://apt.releases.hashicorp.com/gpg
|
||||
state: present
|
||||
|
||||
- name: Add HashiCorp repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb https://apt.releases.hashicorp.com {{ ansible_distribution_release }} main"
|
||||
state: present
|
||||
filename: hashicorp
|
||||
|
||||
- name: Install Consul
|
||||
ansible.builtin.apt:
|
||||
name: "consul={{ consul_version }}-1"
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Create Consul directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: consul
|
||||
group: consul
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "{{ consul_data_dir }}"
|
||||
- "{{ consul_data_dir }}/data"
|
||||
- /etc/consul.d
|
||||
|
||||
- name: Configure Consul
|
||||
ansible.builtin.template:
|
||||
src: consul.hcl.j2
|
||||
dest: /etc/consul.d/consul.hcl
|
||||
owner: consul
|
||||
group: consul
|
||||
mode: '0640'
|
||||
notify: Restart Consul
|
||||
|
||||
- name: Configure Consul server (if server)
|
||||
ansible.builtin.template:
|
||||
src: server.hcl.j2
|
||||
dest: /etc/consul.d/server.hcl
|
||||
owner: consul
|
||||
group: consul
|
||||
mode: '0640'
|
||||
when: consul_server | default(false)
|
||||
notify: Restart Consul
|
||||
|
||||
- name: Enable and start Consul
|
||||
ansible.builtin.systemd:
|
||||
name: consul
|
||||
enabled: yes
|
||||
state: started
|
||||
@@ -0,0 +1,34 @@
|
||||
# Consul Configuration
|
||||
# Managed by Ansible
|
||||
|
||||
datacenter = "{{ datacenter }}"
|
||||
data_dir = "{{ consul_data_dir }}/data"
|
||||
node_name = "{{ inventory_hostname }}"
|
||||
|
||||
bind_addr = "{{ ansible_host }}"
|
||||
client_addr = "0.0.0.0"
|
||||
|
||||
ui_config {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
# DNS settings
|
||||
dns_config {
|
||||
allow_stale = true
|
||||
}
|
||||
|
||||
# Service mesh
|
||||
connect {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
# Telemetry
|
||||
telemetry {
|
||||
prometheus_retention_time = "24h"
|
||||
disable_hostname = true
|
||||
}
|
||||
|
||||
# Performance
|
||||
performance {
|
||||
raft_multiplier = 1
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# Consul Server Configuration
|
||||
|
||||
server = true
|
||||
bootstrap_expect = {{ consul_bootstrap_expect | default(1) }}
|
||||
|
||||
# Raft settings
|
||||
raft_protocol = 3
|
||||
|
||||
# Autopilot
|
||||
autopilot {
|
||||
cleanup_dead_servers = true
|
||||
last_contact_threshold = "200ms"
|
||||
max_trailing_logs = 250
|
||||
server_stabilization_time = "10s"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Restart Nomad
|
||||
ansible.builtin.systemd:
|
||||
name: nomad
|
||||
state: restarted
|
||||
daemon_reload: yes
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
# Nomad Installation Role
|
||||
|
||||
- name: Install dependencies
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- curl
|
||||
- gnupg
|
||||
- lsb-release
|
||||
- apt-transport-https
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Add HashiCorp GPG key
|
||||
ansible.builtin.apt_key:
|
||||
url: https://apt.releases.hashicorp.com/gpg
|
||||
state: present
|
||||
|
||||
- name: Add HashiCorp repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb https://apt.releases.hashicorp.com {{ ansible_distribution_release }} main"
|
||||
state: present
|
||||
filename: hashicorp
|
||||
|
||||
- name: Install Nomad
|
||||
ansible.builtin.apt:
|
||||
name: "nomad={{ nomad_version }}-1"
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Create Nomad directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: nomad
|
||||
group: nomad
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "{{ nomad_data_dir }}"
|
||||
- "{{ nomad_data_dir }}/data"
|
||||
- /etc/nomad.d
|
||||
|
||||
- name: Configure Nomad
|
||||
ansible.builtin.template:
|
||||
src: nomad.hcl.j2
|
||||
dest: /etc/nomad.d/nomad.hcl
|
||||
owner: nomad
|
||||
group: nomad
|
||||
mode: '0640'
|
||||
notify: Restart Nomad
|
||||
|
||||
- name: Configure Nomad server (if server)
|
||||
ansible.builtin.template:
|
||||
src: server.hcl.j2
|
||||
dest: /etc/nomad.d/server.hcl
|
||||
owner: nomad
|
||||
group: nomad
|
||||
mode: '0640'
|
||||
when: nomad_server | default(false)
|
||||
notify: Restart Nomad
|
||||
|
||||
- name: Configure Nomad client
|
||||
ansible.builtin.template:
|
||||
src: client.hcl.j2
|
||||
dest: /etc/nomad.d/client.hcl
|
||||
owner: nomad
|
||||
group: nomad
|
||||
mode: '0640'
|
||||
when: nomad_client | default(false)
|
||||
notify: Restart Nomad
|
||||
|
||||
- name: Enable and start Nomad
|
||||
ansible.builtin.systemd:
|
||||
name: nomad
|
||||
enabled: yes
|
||||
state: started
|
||||
@@ -0,0 +1,34 @@
|
||||
# Nomad Client Configuration
|
||||
|
||||
client {
|
||||
enabled = true
|
||||
|
||||
node_class = "{{ nomad_node_class | default('default') }}"
|
||||
|
||||
# Resource reservations
|
||||
reserved {
|
||||
cpu = 500
|
||||
memory = 512
|
||||
}
|
||||
|
||||
# Host volumes for persistent data
|
||||
host_volume "docker-data" {
|
||||
path = "/mnt/nas/docker"
|
||||
read_only = false
|
||||
}
|
||||
|
||||
host_volume "media" {
|
||||
path = "/mnt/nas/media"
|
||||
read_only = false
|
||||
}
|
||||
|
||||
# Meta information
|
||||
meta {
|
||||
"rack" = "{{ rack | default('rack-1') }}"
|
||||
"datacenter" = "{{ datacenter }}"
|
||||
"legacy_name" = "{{ legacy_name | default('unknown') }}"
|
||||
}
|
||||
|
||||
# Network interface
|
||||
network_interface = "{{ ansible_default_ipv4.interface | default('eth0') }}"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# Nomad Configuration
|
||||
# Managed by Ansible - Do not edit manually
|
||||
|
||||
datacenter = "{{ datacenter }}"
|
||||
data_dir = "{{ nomad_data_dir }}/data"
|
||||
bind_addr = "0.0.0.0"
|
||||
|
||||
advertise {
|
||||
http = "{{ ansible_host }}"
|
||||
rpc = "{{ ansible_host }}"
|
||||
serf = "{{ ansible_host }}"
|
||||
}
|
||||
|
||||
# Enable ACLs (after bootstrap)
|
||||
# acl {
|
||||
# enabled = true
|
||||
# }
|
||||
|
||||
# Consul integration
|
||||
consul {
|
||||
address = "127.0.0.1:8500"
|
||||
|
||||
server_service_name = "nomad"
|
||||
client_service_name = "nomad-client"
|
||||
|
||||
auto_advertise = true
|
||||
server_auto_join = true
|
||||
client_auto_join = true
|
||||
}
|
||||
|
||||
# Vault integration (after Vault setup)
|
||||
# vault {
|
||||
# enabled = true
|
||||
# address = "http://127.0.0.1:8200"
|
||||
# }
|
||||
|
||||
telemetry {
|
||||
collection_interval = "10s"
|
||||
disable_hostname = true
|
||||
prometheus_metrics = true
|
||||
publish_allocation_metrics = true
|
||||
publish_node_metrics = true
|
||||
}
|
||||
|
||||
plugin "docker" {
|
||||
config {
|
||||
allow_privileged = true
|
||||
volumes {
|
||||
enabled = true
|
||||
}
|
||||
extra_labels = ["job_name", "task_group_name", "task_name", "namespace", "node_name"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# Nomad Server Configuration
|
||||
|
||||
server {
|
||||
enabled = true
|
||||
bootstrap_expect = {{ nomad_bootstrap_expect | default(1) }}
|
||||
|
||||
# Raft settings
|
||||
raft_protocol = 3
|
||||
|
||||
# Server join (for multi-server setup)
|
||||
# server_join {
|
||||
# retry_join = ["hf-pdocker-01.hobbs.farm"]
|
||||
# }
|
||||
}
|
||||
Reference in New Issue
Block a user