ansible cleanup
This commit is contained in:
parent
8e6d434386
commit
b80b2a9967
46 changed files with 611 additions and 209 deletions
32
ansible/.gitignore
vendored
32
ansible/.gitignore
vendored
|
|
@ -1,3 +1,33 @@
|
||||||
|
# Ansible runtime files
|
||||||
|
ansible-playbook.log
|
||||||
|
*.retry
|
||||||
site.retry
|
site.retry
|
||||||
fact_cache
|
|
||||||
|
# Fact cache
|
||||||
|
fact_cache/
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
|
||||||
|
# Editor files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Sensitive files
|
||||||
|
*.key
|
||||||
|
*.pem
|
||||||
|
vault-password.txt
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
|
||||||
|
|
|
||||||
104
ansible/CLAUDE.md
Normal file
104
ansible/CLAUDE.md
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Repository Overview
|
||||||
|
|
||||||
|
This is an Ansible infrastructure management repository that manages a mixed environment including network services, monitoring, VPN infrastructure, and web applications. The codebase supports multiple operating systems (Debian, Ubuntu, AlmaLinux) and uses a role-based architecture for modularity.
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
### Bootstrap New Hosts
|
||||||
|
```bash
|
||||||
|
# Initial bootstrap (requires password)
|
||||||
|
make bootstrap-init HOSTNAME=hostname ANSIBLE_HOST=ip_address
|
||||||
|
|
||||||
|
# Full bootstrap with network config and reboot
|
||||||
|
make bootstrap HOSTNAME=hostname ANSIBLE_HOST=ip_address
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Playbooks
|
||||||
|
```bash
|
||||||
|
# Run main playbook
|
||||||
|
./run.sh
|
||||||
|
|
||||||
|
# Run all playbooks on specific host
|
||||||
|
make run-all HOSTNAME=hostname ANSIBLE_HOST=ip_address
|
||||||
|
|
||||||
|
# Run general playbook
|
||||||
|
ansible-playbook general.yml
|
||||||
|
|
||||||
|
# Run specific tags
|
||||||
|
ansible-playbook -t caddy general.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Tasks
|
||||||
|
```bash
|
||||||
|
# Gather facts from all hosts
|
||||||
|
make facts
|
||||||
|
|
||||||
|
# Test changes on specific host
|
||||||
|
ansible-playbook -l hostname playbook.yml
|
||||||
|
|
||||||
|
# Check syntax
|
||||||
|
ansible-playbook --syntax-check playbook.yml
|
||||||
|
|
||||||
|
# Dry run
|
||||||
|
ansible-playbook --check playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Playbook Structure
|
||||||
|
- `playbook.yml` - Main playbook for common configuration, DNS, Tailscale, Caddy
|
||||||
|
- `general.yml` - General system setup including SNMP, K3s, Docker, syslog
|
||||||
|
- `bootstrap.yml` - Initial host preparation
|
||||||
|
|
||||||
|
### Role Organization
|
||||||
|
Roles follow a standard structure with:
|
||||||
|
- `tasks/main.yml` - Main task list
|
||||||
|
- `handlers/main.yml` - Service restart handlers
|
||||||
|
- `templates/` - Jinja2 templates for config files
|
||||||
|
- `vars/` - Role-specific variables
|
||||||
|
- `defaults/` - Default variable values
|
||||||
|
|
||||||
|
### Key Roles
|
||||||
|
- `base` - Combined base configuration (users, SSH, sudo, packages)
|
||||||
|
- `general` - General system configurations (motd, network, syslog)
|
||||||
|
- `caddy` - Web server and reverse proxy
|
||||||
|
- `ns` - Nameserver configuration
|
||||||
|
- `resolvers` - DNS resolver setup (Unbound)
|
||||||
|
- `docker` - Docker installation (stub)
|
||||||
|
- `k3s_servers` - Kubernetes K3s setup (stub)
|
||||||
|
- `snmp_clients` - SNMP client configuration (stub)
|
||||||
|
|
||||||
|
### Variable Precedence
|
||||||
|
1. Host-specific vars in `host_vars/`
|
||||||
|
2. Group vars in `group_vars/`
|
||||||
|
3. Role defaults in `roles/*/defaults/`
|
||||||
|
4. Base variables in `vars/`
|
||||||
|
|
||||||
|
### Service Dependencies
|
||||||
|
- SSH configuration managed by common role
|
||||||
|
- Firewall rules (firewalld) applied before service configs
|
||||||
|
- Handlers ensure services restart when configs change
|
||||||
|
- Tailscale VPN requires `TAILSCALE_KEY` environment variable
|
||||||
|
|
||||||
|
## Key Patterns
|
||||||
|
|
||||||
|
### User Management
|
||||||
|
- Ansible user (UID 10001) created on all hosts
|
||||||
|
- SSH keys fetched from GitHub for authentication
|
||||||
|
- Passwordless sudo configured for automation
|
||||||
|
|
||||||
|
### Network Services
|
||||||
|
- DNS resolvers use Unbound
|
||||||
|
- Nameservers configured via ns role
|
||||||
|
- Caddy serves as reverse proxy for web services
|
||||||
|
- Tailscale provides VPN connectivity
|
||||||
|
|
||||||
|
### Configuration Management
|
||||||
|
- Templates use host-specific variables
|
||||||
|
- Handlers manage service restarts
|
||||||
|
- Fact caching improves performance
|
||||||
|
- Collections required: ansible.posix, netbox.netbox
|
||||||
|
|
@ -45,8 +45,13 @@ bootstrap-reboot:
|
||||||
bootstrap-init:
|
bootstrap-init:
|
||||||
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_user=graham -e ansible_host=$(ANSIBLE_HOST) -k -K bootstrap.yml
|
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_user=graham -e ansible_host=$(ANSIBLE_HOST) -k -K bootstrap.yml
|
||||||
|
|
||||||
|
bootstrap-init-root:
|
||||||
|
ANSIBLE_CONFIG=ansible-bootstrap.cfg $(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_user=root -e ansible_host=$(ANSIBLE_HOST) -e ansible_become=no bootstrap.yml
|
||||||
|
|
||||||
bootstrap: bootstrap-init bootstrap-network bootstrap-reboot
|
bootstrap: bootstrap-init bootstrap-network bootstrap-reboot
|
||||||
|
|
||||||
|
bootstrap-root: bootstrap-init-root bootstrap-network bootstrap-reboot
|
||||||
|
|
||||||
run-all:
|
run-all:
|
||||||
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_host=$(ANSIBLE_HOST) general.yml
|
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_host=$(ANSIBLE_HOST) general.yml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,60 @@
|
||||||
Ansible things
|
# Ansible Infrastructure Management
|
||||||
|
|
||||||
|
This repository contains Ansible playbooks and roles for managing infrastructure across multiple environments.
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
├── playbook.yml # Main playbook for common configuration
|
||||||
|
├── general.yml # General system setup playbook
|
||||||
|
├── bootstrap.yml # Bootstrap playbook for new hosts
|
||||||
|
├── roles/ # Ansible roles
|
||||||
|
│ ├── base/ # Base configuration (users, SSH, system)
|
||||||
|
│ ├── general/ # General system configurations
|
||||||
|
│ ├── caddy/ # Caddy web server
|
||||||
|
│ ├── ns/ # Nameserver configuration
|
||||||
|
│ ├── resolvers/ # DNS resolver setup
|
||||||
|
│ └── ... # Other roles
|
||||||
|
├── group_vars/ # Group-specific variables
|
||||||
|
├── host_vars/ # Host-specific variables
|
||||||
|
└── hosts # Inventory file
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Bootstrap a new host
|
||||||
|
```bash
|
||||||
|
# For hosts with existing user access
|
||||||
|
make bootstrap-init HOSTNAME=hostname ANSIBLE_HOST=ip_address
|
||||||
|
|
||||||
|
# For hosts with only root access
|
||||||
|
make bootstrap-init-root HOSTNAME=hostname ANSIBLE_HOST=ip_address
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run playbooks
|
||||||
|
```bash
|
||||||
|
# Run main playbook
|
||||||
|
./run.sh
|
||||||
|
|
||||||
|
# Run on specific host
|
||||||
|
ansible-playbook -l hostname playbook.yml
|
||||||
|
|
||||||
|
# Run with specific tags
|
||||||
|
ansible-playbook -t caddy playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Inventory Groups
|
||||||
|
|
||||||
|
- `vntx_servers` - VNTX network services
|
||||||
|
- `app_servers` - Application servers
|
||||||
|
- `home_servers` - Home network devices
|
||||||
|
- `tailscale_home` - Devices using Tailscale VPN
|
||||||
|
- `caddy_servers` - Servers running Caddy web server
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- Automated user management with GitHub SSH key integration
|
||||||
|
- Base package installation across all systems
|
||||||
|
- Role-based configuration management
|
||||||
|
- Support for multiple OS families (Debian, Ubuntu, AlmaLinux)
|
||||||
|
- Tailscale VPN integration
|
||||||
|
- Caddy web server with reverse proxy configuration
|
||||||
|
|
|
||||||
7
ansible/ansible-bootstrap.cfg
Normal file
7
ansible/ansible-bootstrap.cfg
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
[defaults]
|
||||||
|
host_key_checking = False
|
||||||
|
inventory = hosts
|
||||||
|
interpreter_python = auto_silent
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
pipelining = true
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
hosts: all
|
hosts: all
|
||||||
tags: bootstrap
|
tags: bootstrap
|
||||||
roles:
|
roles:
|
||||||
- bootstrap
|
- base
|
||||||
become: yes
|
become: yes
|
||||||
# become_method: "{{ 'su' if (ansible_distribution | default('')) == 'Debian' else 'sudo' }}"
|
# become_method: "{{ 'su' if (ansible_distribution | default('')) == 'Debian' else 'sudo' }}"
|
||||||
# become_method: "sudo"
|
# become_method: "sudo"
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
become_method: sudo
|
become_method: sudo
|
||||||
roles:
|
roles:
|
||||||
- general
|
- general
|
||||||
vars_files:
|
|
||||||
- vars/base.yml
|
|
||||||
tags:
|
tags:
|
||||||
- base
|
- base
|
||||||
|
|
||||||
|
|
@ -41,8 +39,6 @@
|
||||||
hosts: netboot
|
hosts: netboot
|
||||||
become: yes
|
become: yes
|
||||||
become_method: sudo
|
become_method: sudo
|
||||||
vars_files:
|
|
||||||
- vars/base.yml
|
|
||||||
- vars/netboot.yml
|
- vars/netboot.yml
|
||||||
- vars/network.yml
|
- vars/network.yml
|
||||||
vars:
|
vars:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
# Global variables for all hosts
|
||||||
|
|
||||||
|
# Timezone configuration
|
||||||
|
timezone: America/Chicago
|
||||||
|
|
||||||
|
# GitHub usernames for SSH key retrieval
|
||||||
|
github_users:
|
||||||
|
- username: graham
|
||||||
|
github: gmcintire
|
||||||
|
- username: andy
|
||||||
|
github: nsnw
|
||||||
|
|
||||||
|
# Base packages to install on all systems
|
||||||
|
base:
|
||||||
|
packages:
|
||||||
|
- git
|
||||||
|
- fzf
|
||||||
|
- zsh
|
||||||
|
- jq
|
||||||
|
- sysstat
|
||||||
|
- smartmontools
|
||||||
|
- lm-sensors
|
||||||
|
- debconf-utils
|
||||||
|
- ntp
|
||||||
|
- ntpdate
|
||||||
|
- samba
|
||||||
|
- samba-common
|
||||||
|
- sssd
|
||||||
|
- krb5-user
|
||||||
|
- zsh
|
||||||
|
- wget
|
||||||
|
- vim
|
||||||
|
- htop
|
||||||
|
- mosh
|
||||||
|
- tmux
|
||||||
|
|
||||||
|
ntp:
|
||||||
|
server: 0.us.pool.ntp.org
|
||||||
|
|
||||||
|
# SSH service name (varies by distribution)
|
||||||
|
ssh_service: "{{ 'ssh' if ansible_os_family == 'Debian' else 'sshd' }}"
|
||||||
|
|
||||||
|
# NTP service name (varies by distribution)
|
||||||
|
ntp_service: "{{ 'ntp' if ansible_os_family == 'Debian' else 'ntpd' }}"
|
||||||
6
ansible/group_vars/netbox.yml
Normal file
6
ansible/group_vars/netbox.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
# Netbox server configuration
|
||||||
|
netbox:
|
||||||
|
domain: netbox.vntx.net
|
||||||
|
port: 8001
|
||||||
|
bind_address: tcp4/0.0.0.0
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
- name: Restart ntp
|
|
||||||
ansible.builtin.service:
|
|
||||||
name: ntp
|
|
||||||
state: restarted
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Restart ssh
|
|
||||||
ansible.builtin.service:
|
|
||||||
name: ssh
|
|
||||||
state: restarted
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Restart unbound
|
|
||||||
ansible.builtin.service:
|
|
||||||
name: unbound
|
|
||||||
state: restarted
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Restart firewalld
|
|
||||||
ansible.builtin.service:
|
|
||||||
name: firewalld
|
|
||||||
state: restarted
|
|
||||||
become: true
|
|
||||||
3
ansible/host_vars/dallas.aprs2.net.yml
Normal file
3
ansible/host_vars/dallas.aprs2.net.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Host-specific variables for dallas.aprs2.net
|
||||||
|
ansible_host: 204.110.191.232
|
||||||
3
ansible/host_vars/g.w5isp.com.yml
Normal file
3
ansible/host_vars/g.w5isp.com.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Host-specific variables for g.w5isp.com
|
||||||
|
ansible_user: ansible
|
||||||
3
ansible/host_vars/lab01.w5isp.com.yml
Normal file
3
ansible/host_vars/lab01.w5isp.com.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Host-specific variables for lab01.w5isp.com
|
||||||
|
ansible_host: 10.0.16.231
|
||||||
3
ansible/host_vars/lab02.w5isp.com.yml
Normal file
3
ansible/host_vars/lab02.w5isp.com.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Host-specific variables for lab02.w5isp.com
|
||||||
|
ansible_host: 10.0.16.232
|
||||||
3
ansible/host_vars/lab03.w5isp.com.yml
Normal file
3
ansible/host_vars/lab03.w5isp.com.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Host-specific variables for lab03.w5isp.com
|
||||||
|
ansible_host: 10.0.16.233
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[vntx]
|
[vntx_servers]
|
||||||
#logs.vntx.net
|
#logs.vntx.net
|
||||||
#unimus.vntx.net
|
#unimus.vntx.net
|
||||||
monitor.vntx.net
|
monitor.vntx.net
|
||||||
|
|
@ -10,25 +10,25 @@ ns1.vntx.net
|
||||||
ns2.vntx.net
|
ns2.vntx.net
|
||||||
#ntp.vntx.net
|
#ntp.vntx.net
|
||||||
|
|
||||||
[common]
|
[app_servers]
|
||||||
#aprs.me
|
#aprs.me
|
||||||
dallas.aprs2.net ansible_host=204.110.191.232
|
dallas.aprs2.net
|
||||||
apps.w5isp.com
|
apps.w5isp.com
|
||||||
|
|
||||||
[home]
|
[home_servers]
|
||||||
skippy.w5isp.com
|
skippy.w5isp.com
|
||||||
g.w5isp.com ansible_user=ansible
|
|
||||||
|
|
||||||
#[proxmox]
|
|
||||||
#lab01 ansible_host=10.0.16.231 #ansible_user=root
|
|
||||||
#lab02 ansible_host=10.0.16.232 #ansible_user=root
|
|
||||||
#lab03 ansible_host=10.0.16.233 #ansible_user=root
|
|
||||||
|
|
||||||
[tailscale_home]
|
|
||||||
lab01.w5isp.com ansible_host=10.0.16.231 #ansible_user=root
|
|
||||||
lab02.w5isp.com ansible_host=10.0.16.232 #ansible_user=root
|
|
||||||
lab03.w5isp.com ansible_host=10.0.16.233 #ansible_user=root
|
|
||||||
g.w5isp.com
|
g.w5isp.com
|
||||||
|
|
||||||
[caddy]
|
#[proxmox]
|
||||||
g.w5isp.com ansible_user=ansible
|
#lab01.w5isp.com
|
||||||
|
#lab02.w5isp.com
|
||||||
|
#lab03.w5isp.com
|
||||||
|
|
||||||
|
[tailscale_home]
|
||||||
|
lab01.w5isp.com
|
||||||
|
lab02.w5isp.com
|
||||||
|
lab03.w5isp.com
|
||||||
|
g.w5isp.com
|
||||||
|
|
||||||
|
[caddy_servers]
|
||||||
|
g.w5isp.com
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,14 @@
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
remote_user: ansible
|
remote_user: ansible
|
||||||
roles:
|
roles:
|
||||||
- common
|
- base
|
||||||
vars_files:
|
|
||||||
- vars/common.yml
|
|
||||||
tags:
|
tags:
|
||||||
- common
|
- common
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Set timezone
|
- name: Set timezone
|
||||||
community.general.timezone:
|
community.general.timezone:
|
||||||
name: America/Chicago
|
name: "{{ timezone }}"
|
||||||
|
|
||||||
- name: Install Graham SSH keys
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: graham
|
|
||||||
state: present
|
|
||||||
key: https://github.com/gmcintire.keys
|
|
||||||
|
|
||||||
- name: Install Andys SSH keys
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: andy
|
|
||||||
state: present
|
|
||||||
key: https://github.com/nsnw.keys
|
|
||||||
|
|
||||||
- name: Apply resolver config
|
- name: Apply resolver config
|
||||||
hosts: resolvers
|
hosts: resolvers
|
||||||
|
|
@ -53,8 +39,8 @@
|
||||||
caddy_systemd_capabilities_enabled: true
|
caddy_systemd_capabilities_enabled: true
|
||||||
caddy_systemd_capabilities: "CAP_NET_BIND_SERVICE"
|
caddy_systemd_capabilities: "CAP_NET_BIND_SERVICE"
|
||||||
caddy_config: |
|
caddy_config: |
|
||||||
netbox.vntx.net {
|
{{ netbox.domain }} {
|
||||||
bind tcp4/0.0.0.0
|
bind {{ netbox.bind_address }}
|
||||||
log {
|
log {
|
||||||
level error
|
level error
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +51,7 @@
|
||||||
}
|
}
|
||||||
@notStatic not path /static*
|
@notStatic not path /static*
|
||||||
encode gzip zstd
|
encode gzip zstd
|
||||||
reverse_proxy @notStatic http://localhost:8001 {
|
reverse_proxy @notStatic http://localhost:{{ netbox.port }} {
|
||||||
header_up Host {http.request.host}
|
header_up Host {http.request.host}
|
||||||
header_up X-Real-IP {http.request.remote.host}
|
header_up X-Real-IP {http.request.remote.host}
|
||||||
header_up X-Forwarded-For {http.request.remote.host}
|
header_up X-Forwarded-For {http.request.remote.host}
|
||||||
|
|
@ -78,6 +64,8 @@
|
||||||
hosts: netbox
|
hosts: netbox
|
||||||
become: true
|
become: true
|
||||||
# remote_user: graham
|
# remote_user: graham
|
||||||
|
handlers:
|
||||||
|
- import_tasks: playbook_handlers.yml
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Permit traffic in default zone for http service
|
- name: Permit traffic in default zone for http service
|
||||||
|
|
@ -110,7 +98,7 @@
|
||||||
msg: "Key exists and starts with: {{ lookup('ansible.builtin.env', 'TAILSCALE_KEY')[0:10] }}..."
|
msg: "Key exists and starts with: {{ lookup('ansible.builtin.env', 'TAILSCALE_KEY')[0:10] }}..."
|
||||||
|
|
||||||
- name: Install and configure Caddy
|
- name: Install and configure Caddy
|
||||||
hosts: caddy
|
hosts: caddy_servers
|
||||||
become: true
|
become: true
|
||||||
roles:
|
roles:
|
||||||
- caddy
|
- caddy
|
||||||
|
|
|
||||||
8
ansible/playbook_handlers.yml
Normal file
8
ansible/playbook_handlers.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# Handlers for tasks in playbook.yml
|
||||||
|
|
||||||
|
- name: Restart firewalld
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: firewalld
|
||||||
|
state: restarted
|
||||||
|
become: true
|
||||||
10
ansible/roles/base/handlers/main.yml
Normal file
10
ansible/roles/base/handlers/main.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
- name: restart ntp
|
||||||
|
service:
|
||||||
|
name: "{{ ntp_service | default('ntp') }}"
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: restart ssh
|
||||||
|
service:
|
||||||
|
name: "{{ ssh_service | default('sshd') }}"
|
||||||
|
state: restarted
|
||||||
38
ansible/roles/base/tasks/main.yml
Normal file
38
ansible/roles/base/tasks/main.yml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
# Base role - combines bootstrap and common functionality
|
||||||
|
|
||||||
|
# Initial system information
|
||||||
|
- name: Show hostname
|
||||||
|
debug:
|
||||||
|
msg: "{{ ansible_hostname }}"
|
||||||
|
|
||||||
|
- name: Show IPv4 address
|
||||||
|
debug:
|
||||||
|
msg: "{{ ansible_default_ipv4.address }}"
|
||||||
|
when: ansible_default_ipv4.address is defined
|
||||||
|
|
||||||
|
- name: Show IPv6 address
|
||||||
|
debug:
|
||||||
|
msg: "{{ ansible_default_ipv6.address }}"
|
||||||
|
when: ansible_default_ipv6.address is defined
|
||||||
|
|
||||||
|
# User and group setup
|
||||||
|
- import_tasks: users.yml
|
||||||
|
tags:
|
||||||
|
- users
|
||||||
|
- bootstrap
|
||||||
|
|
||||||
|
# Base system configuration
|
||||||
|
- import_tasks: system.yml
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
- common
|
||||||
|
|
||||||
|
# OS-specific configurations
|
||||||
|
- include_role:
|
||||||
|
name: almalinux
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
|
||||||
|
- include_role:
|
||||||
|
name: debian
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
31
ansible/roles/base/tasks/system.yml
Normal file
31
ansible/roles/base/tasks/system.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
# System configuration tasks
|
||||||
|
|
||||||
|
- name: Install SSH banner
|
||||||
|
template:
|
||||||
|
src: issue.net.j2
|
||||||
|
dest: /etc/issue.net
|
||||||
|
mode: '0644'
|
||||||
|
tags:
|
||||||
|
- ssh
|
||||||
|
|
||||||
|
- name: Configure SSH to use banner
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^Banner'
|
||||||
|
line: 'Banner /etc/issue.net'
|
||||||
|
state: present
|
||||||
|
notify: restart ssh
|
||||||
|
tags:
|
||||||
|
- ssh
|
||||||
|
|
||||||
|
# Uncomment if you want to disable root SSH access
|
||||||
|
# - name: Disallow root SSH access
|
||||||
|
# lineinfile:
|
||||||
|
# path: /etc/ssh/sshd_config
|
||||||
|
# regexp: "^PermitRootLogin"
|
||||||
|
# line: "PermitRootLogin no"
|
||||||
|
# state: present
|
||||||
|
# notify: restart ssh
|
||||||
|
# tags:
|
||||||
|
# - ssh
|
||||||
66
ansible/roles/base/tasks/users.yml
Normal file
66
ansible/roles/base/tasks/users.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
# User and group management tasks
|
||||||
|
|
||||||
|
- name: Install sudo package (Debian)
|
||||||
|
apt:
|
||||||
|
name: sudo
|
||||||
|
state: present
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
|
||||||
|
- name: Create ansible group
|
||||||
|
group:
|
||||||
|
name: ansible
|
||||||
|
gid: 10001
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create ansible user
|
||||||
|
user:
|
||||||
|
name: ansible
|
||||||
|
group: ansible
|
||||||
|
uid: 10001
|
||||||
|
shell: /bin/bash
|
||||||
|
home: /home/ansible
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create graham user
|
||||||
|
user:
|
||||||
|
name: graham
|
||||||
|
shell: /bin/bash
|
||||||
|
home: /home/graham
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create andy user
|
||||||
|
user:
|
||||||
|
name: andy
|
||||||
|
shell: /bin/bash
|
||||||
|
home: /home/andy
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Set up SSH key for ansible user
|
||||||
|
authorized_key:
|
||||||
|
user: ansible
|
||||||
|
key: "{{ lookup('file', 'ansible.pub') }}"
|
||||||
|
exclusive: true
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Configure sudo for ansible user
|
||||||
|
template:
|
||||||
|
src: sudoers_ansible.j2
|
||||||
|
dest: /etc/sudoers.d/ansible
|
||||||
|
mode: '0440'
|
||||||
|
validate: 'visudo -cf %s'
|
||||||
|
|
||||||
|
- name: Enable passwordless sudo for %sudo
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/sudoers
|
||||||
|
state: present
|
||||||
|
regexp: '^%sudo'
|
||||||
|
line: '%sudo ALL=(ALL) NOPASSWD: ALL'
|
||||||
|
validate: 'visudo -cf %s'
|
||||||
|
|
||||||
|
- name: Install SSH keys from GitHub
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ item.username }}"
|
||||||
|
state: present
|
||||||
|
key: "https://github.com/{{ item.github }}.keys"
|
||||||
|
loop: "{{ github_users }}"
|
||||||
1
ansible/roles/base/templates/sudoers_ansible.j2
Normal file
1
ansible/roles/base/templates/sudoers_ansible.j2
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
ansible ALL=NOPASSWD: ALL
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
- name: Install sudo
|
|
||||||
apt:
|
|
||||||
name: sudo
|
|
||||||
when: ansible_distribution == "Debian"
|
|
||||||
|
|
||||||
- name: Ensure the 'ansible' group exists
|
|
||||||
group:
|
|
||||||
name: ansible
|
|
||||||
gid: 10001
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Ensure the 'ansible' user exists
|
|
||||||
user:
|
|
||||||
name: ansible
|
|
||||||
comment: Ansible User
|
|
||||||
uid: 10001
|
|
||||||
group: ansible
|
|
||||||
|
|
||||||
- name: Ensure the 'graham' user exists
|
|
||||||
user:
|
|
||||||
name: graham
|
|
||||||
comment: Graham
|
|
||||||
|
|
||||||
- name: Ensure the 'andy' user exists
|
|
||||||
user:
|
|
||||||
name: andy
|
|
||||||
comment: Andy
|
|
||||||
|
|
||||||
- name: Ensure that 'authorized_keys' is set correctly for the 'ansible' user
|
|
||||||
authorized_key:
|
|
||||||
user: ansible
|
|
||||||
state: present
|
|
||||||
key: "{{ lookup('file', 'files/ansible.pub') }}"
|
|
||||||
|
|
||||||
- name: Ensure sudo is configured for the 'ansible' user
|
|
||||||
template:
|
|
||||||
src: templates/etc/sudoers.d/ansible
|
|
||||||
dest: /etc/sudoers.d/ansible
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '0440'
|
|
||||||
tags:
|
|
||||||
- sudoers
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
- name: Dump host information
|
|
||||||
debug:
|
|
||||||
msg:
|
|
||||||
- "Host : {{ inventory_hostname }}"
|
|
||||||
# - "Distro : {{ ansible_lsb.id }}"
|
|
||||||
# - "Release: {{ ansible_lsb.codename }}"
|
|
||||||
- "IPv4 : {{ ansible_all_ipv4_addresses }}"
|
|
||||||
- "IPv6 : {{ ansible_all_ipv6_addresses }}"
|
|
||||||
|
|
||||||
- name: Ansible setup
|
|
||||||
import_tasks: ansible.yml
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{{ inventory_hostname }}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
127.0.0.1 localhost
|
|
||||||
::1 localhost ip6-localhost ip6-loopback
|
|
||||||
ff02::1 ip6-allnodes
|
|
||||||
ff02::2 ip6-allrouters
|
|
||||||
|
|
||||||
127.0.1.1 {{ inventory_hostname }} {{ inventory_hostname | split('.') | first }}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
ansible ALL=NOPASSWD: ALL
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb Ansible SSH Key
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
---
|
|
||||||
# Handler to handle common notifications. Handlers are called by other plays.
|
|
||||||
# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
|
|
||||||
|
|
||||||
- name: Restart ntp
|
|
||||||
ansible.builtin.service:
|
|
||||||
name: ntp
|
|
||||||
state: restarted
|
|
||||||
become: true
|
|
||||||
# - name: Restart ssh
|
|
||||||
# ansible.builtin.service:
|
|
||||||
# name: ssh
|
|
||||||
# state: restarted
|
|
||||||
# become: true
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
- name: "Enable passwordless sudo"
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
path: /etc/sudoers
|
|
||||||
state: present
|
|
||||||
regexp: "^%sudo"
|
|
||||||
line: "%sudo ALL=(ALL) NOPASSWD: ALL"
|
|
||||||
validate: "visudo -cf %s"
|
|
||||||
|
|
||||||
- name: "Apply AlmaLinux specific config"
|
|
||||||
when: ansible_distribution == 'AlmaLinux'
|
|
||||||
ansible.builtin.import_role:
|
|
||||||
name: almalinux
|
|
||||||
|
|
||||||
- name: "Apply Debian specific config"
|
|
||||||
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
|
|
||||||
ansible.builtin.import_role:
|
|
||||||
name: debian
|
|
||||||
|
|
||||||
- name: Install sshd banner
|
|
||||||
ansible.builtin.template:
|
|
||||||
src: issue.net.j2
|
|
||||||
dest: /etc/issue.net
|
|
||||||
mode: "644"
|
|
||||||
|
|
||||||
- name: Setup sshd banner
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
dest: /etc/ssh/sshd_config
|
|
||||||
line: "Banner /etc/issue.net"
|
|
||||||
state: present
|
|
||||||
notify: Restart ssh
|
|
||||||
# - name: Disallow root SSH access
|
|
||||||
# ansible.builtin.lineinfile:
|
|
||||||
# dest: /etc/ssh/sshd_config
|
|
||||||
# regexp: "^PermitRootLogin"
|
|
||||||
# line: "PermitRootLogin no"
|
|
||||||
# state: present
|
|
||||||
# notify: Restart ssh
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
8b d8
|
|
||||||
`8b d8'
|
|
||||||
`8b d8'
|
|
||||||
`8b d8' ,adPPYba, 8b,dPPYba, ,adPPYba, 8b,dPPYba, ,adPPYYba,
|
|
||||||
`8b d8' a8P_____88 88P' "Y8 a8" "8a 88P' `"8a "" `Y8
|
|
||||||
`8b d8' 8PP""""""" 88 8b d8 88 88 ,adPPPPP88
|
|
||||||
`888' "8b, ,aa 88 "8a, ,a8" 88 88 88, ,88
|
|
||||||
`8' `"Ybbd8"' 88 `"YbbdP"' 88 88 `"8bbdP"Y8
|
|
||||||
|
|
||||||
888b 88 88
|
|
||||||
8888b 88 ,d 88
|
|
||||||
88 `8b 88 88 88
|
|
||||||
88 `8b 88 ,adPPYba, MM88MMM 8b db d8 ,adPPYba, 8b,dPPYba, 88 ,d8 ,adPPYba,
|
|
||||||
88 `8b 88 a8P_____88 88 `8b d88b d8' a8" "8a 88P' "Y8 88 ,a8" I8[ ""
|
|
||||||
88 `8b 88 8PP""""""" 88 `8b d8'`8b d8' 8b d8 88 8888[ `"Y8ba,
|
|
||||||
88 `8888 "8b, ,aa 88, `8bd8' `8bd8' "8a, ,a8" 88 88`"Yba, aa ]8I
|
|
||||||
88 `888 `"Ybbd8"' "Y888 YP YP `"YbbdP"' 88 88 `Y8a `"YbbdP"'
|
|
||||||
|
|
||||||
###############################################################
|
|
||||||
# Welcome to Verona Networks #
|
|
||||||
# All connections are monitored and recorded #
|
|
||||||
# Disconnect IMMEDIATELY if you are not an authorized user! #
|
|
||||||
###############################################################
|
|
||||||
|
|
||||||
|
|
||||||
3
ansible/roles/docker/tasks/main.yml
Normal file
3
ansible/roles/docker/tasks/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Docker installation and configuration tasks
|
||||||
|
# TODO: Implement Docker installation
|
||||||
35
ansible/roles/general/tasks/main.yml
Normal file
35
ansible/roles/general/tasks/main.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
# General role - system-wide configurations
|
||||||
|
|
||||||
|
# Import Debian-specific tasks
|
||||||
|
- import_tasks: debian/misc.yml
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- misc
|
||||||
|
|
||||||
|
- import_tasks: debian/motd.yml
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- motd
|
||||||
|
|
||||||
|
- import_tasks: debian/network.yml
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- network
|
||||||
|
|
||||||
|
- import_tasks: debian/syslog.yml
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- syslog
|
||||||
|
|
||||||
|
- import_tasks: debian/icinga2.yml
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- icinga2
|
||||||
|
- monitoring
|
||||||
|
|
||||||
|
- import_tasks: debian/k3s.yml
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- k3s
|
||||||
|
- kubernetes
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
ansible ALL=NOPASSWD: ALL
|
|
||||||
3
ansible/roles/k3s_servers/tasks/main.yml
Normal file
3
ansible/roles/k3s_servers/tasks/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# K3s server configuration tasks
|
||||||
|
# TODO: Implement K3s server installation and configuration
|
||||||
3
ansible/roles/netboot_servers/tasks/main.yml
Normal file
3
ansible/roles/netboot_servers/tasks/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Netboot server configuration tasks
|
||||||
|
# TODO: Implement netboot server configuration
|
||||||
3
ansible/roles/snmp_clients/tasks/main.yml
Normal file
3
ansible/roles/snmp_clients/tasks/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# SNMP client configuration tasks
|
||||||
|
# TODO: Implement SNMP client configuration
|
||||||
3
ansible/roles/syslog_servers/tasks/main.yml
Normal file
3
ansible/roles/syslog_servers/tasks/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Syslog server configuration tasks
|
||||||
|
# TODO: Implement syslog server configuration
|
||||||
3
ansible/vars/common.yml
Normal file
3
ansible/vars/common.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Common variables used across playbooks
|
||||||
|
# Add common configuration here
|
||||||
5
ansible/vars/netboot.yml
Normal file
5
ansible/vars/netboot.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
# Netboot server configuration
|
||||||
|
netboot:
|
||||||
|
dist: []
|
||||||
|
arch: []
|
||||||
3
ansible/vars/network.yml
Normal file
3
ansible/vars/network.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
# Network configuration variables
|
||||||
|
# Add network-related configuration here
|
||||||
97
terraform/CLAUDE.md
Normal file
97
terraform/CLAUDE.md
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### Terraform Workflow
|
||||||
|
```bash
|
||||||
|
# Initialize terraform providers
|
||||||
|
terraform init
|
||||||
|
|
||||||
|
# Validate configuration
|
||||||
|
terraform validate
|
||||||
|
|
||||||
|
# Plan changes
|
||||||
|
terraform plan
|
||||||
|
|
||||||
|
# Apply changes
|
||||||
|
terraform apply
|
||||||
|
|
||||||
|
# Show current state
|
||||||
|
terraform show
|
||||||
|
|
||||||
|
# Format terraform files
|
||||||
|
terraform fmt
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Management
|
||||||
|
```bash
|
||||||
|
# List resources in state
|
||||||
|
terraform state list
|
||||||
|
|
||||||
|
# Show specific resource
|
||||||
|
terraform state show <resource_name>
|
||||||
|
|
||||||
|
# Import existing resources
|
||||||
|
terraform import <resource_type>.<name> <id>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
This Terraform codebase manages DNS infrastructure across multiple providers:
|
||||||
|
|
||||||
|
### DNS Providers
|
||||||
|
- **DNSimple**: Primary domain registrar and DNS hosting
|
||||||
|
- **Porkbun**: Alternative DNS provider
|
||||||
|
- **PowerDNS**: Manages reverse DNS zones (204.110.188-191.x ranges)
|
||||||
|
|
||||||
|
### File Organization
|
||||||
|
- `main.tf`: Provider configurations and requirements
|
||||||
|
- `vars.tf`: Variable definitions (⚠️ contains hardcoded credentials that should be moved to environment variables)
|
||||||
|
- `dns_*.tf`: DNS zone and record configurations organized by domain/provider
|
||||||
|
- State is managed locally (`terraform.tfstate`)
|
||||||
|
|
||||||
|
### Managed Domains
|
||||||
|
- w5isp.com
|
||||||
|
- manero.org
|
||||||
|
- mcintire.me
|
||||||
|
- vntx.net, vntx.org
|
||||||
|
- gridmap.org
|
||||||
|
- Reverse DNS zones for 204.110.188-191.x IP ranges
|
||||||
|
|
||||||
|
### Security Considerations
|
||||||
|
**Critical**: API keys and tokens are hardcoded in `vars.tf` defaults. When making changes:
|
||||||
|
1. Never commit new credentials to the repository
|
||||||
|
2. Use environment variables: `export TF_VAR_variable_name=value`
|
||||||
|
3. Or use `-var` flags: `terraform apply -var="dnsimple_token=xxx"`
|
||||||
|
|
||||||
|
### Common Tasks
|
||||||
|
|
||||||
|
#### Adding DNS Records
|
||||||
|
1. Identify the appropriate `dns_*.tf` file for the domain
|
||||||
|
2. Add the record using the appropriate resource type:
|
||||||
|
```hcl
|
||||||
|
resource "dnsimple_zone_record" "example" {
|
||||||
|
zone_name = "domain.com"
|
||||||
|
name = "subdomain"
|
||||||
|
value = "192.168.1.1"
|
||||||
|
type = "A"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Importing Existing DNS Records
|
||||||
|
```bash
|
||||||
|
# DNSimple records
|
||||||
|
terraform import dnsimple_zone_record.name {zone_id}_{record_id}
|
||||||
|
|
||||||
|
# PowerDNS records
|
||||||
|
terraform import powerdns_record.name zone.com.:record_name:type
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Notes
|
||||||
|
- No modules are used; resources are organized by domain/function
|
||||||
|
- No automated testing or CI/CD pipeline exists
|
||||||
|
- Direct commits to main branch are the current workflow
|
||||||
|
- Run `terraform fmt` before committing to ensure consistent formatting
|
||||||
Loading…
Add table
Reference in a new issue