feat: Add Proxmox LXC container provisioning playbook, related secrets, and documentation.
This commit is contained in:
28
README.md
28
README.md
@@ -19,3 +19,31 @@ This Ansible setup is designed to automate the configuration and maintenance of
|
|||||||
```bash
|
```bash
|
||||||
ansible-playbook -i inventory/hosts.ini playbooks/apt_upgrade.yml
|
ansible-playbook -i inventory/hosts.ini playbooks/apt_upgrade.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Proxmox Integration Setup
|
||||||
|
|
||||||
|
To use the provisioning playbooks (`create_lxc.yml`), you must configure Proxmox API access.
|
||||||
|
|
||||||
|
### 1. Requirements on Control Node
|
||||||
|
Install `community.general` collection:
|
||||||
|
```bash
|
||||||
|
ansible-galaxy collection install community.general
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create Proxmox User & Token
|
||||||
|
1. **Create User**: In Proxmox, go to **Datacenter > Permissions > Users** and add `ansible@pve` (Proxmox VE authentication).
|
||||||
|
2. **Create Token**: Go to **API Tokens**, add a token for `ansible@pve` (e.g., `ansible-token`). **Save the Secret!**
|
||||||
|
3. **Permissions**: Go to **Permissions**, add User Permission for `ansible@pve`:
|
||||||
|
- Path: `/`
|
||||||
|
- Role: `Administrator` (or a custom role with VM/CT creation privileges).
|
||||||
|
|
||||||
|
### 3. Configure Secrets
|
||||||
|
Update your `secrets.yml` (do not commit this file!) with the credentials:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
proxmox_api_user: "ansible@pve"
|
||||||
|
proxmox_api_token_id: "ansible-token"
|
||||||
|
proxmox_api_token_secret: "YOUR_SECRET_HERE"
|
||||||
|
proxmox_node: "proxmox"
|
||||||
|
proxmox_storage: "local"
|
||||||
|
```
|
||||||
|
|||||||
@@ -4,4 +4,11 @@ ansible_password: 'REPLACE_WITH_ROOT_PASSWORD'
|
|||||||
zabbix_server_address: 'x.x.x.x'
|
zabbix_server_address: 'x.x.x.x'
|
||||||
zabbix_psk_identity: '<zabbix_psk_identity'
|
zabbix_psk_identity: '<zabbix_psk_identity'
|
||||||
zabbix_proxy_hostname: '<zabbix_proxy_hostname>' # if needed, in the actual playbook it is set to the hostname of the target
|
zabbix_proxy_hostname: '<zabbix_proxy_hostname>' # if needed, in the actual playbook it is set to the hostname of the target
|
||||||
zabbix_proxy_psk: 'REPLACE_WITH_ZABBIX_PSK'
|
zabbix_proxy_psk: 'REPLACE_WITH_ZABBIX_PSK'
|
||||||
|
|
||||||
|
# Proxmox parameters for connecting to Proxmox server
|
||||||
|
proxmox_api_user: "ansible@pve"
|
||||||
|
proxmox_api_token_id: "ansible-token"
|
||||||
|
proxmox_api_token_secret: "YOUR_SECRET_HERE"
|
||||||
|
proxmox_node: "proxmox"
|
||||||
|
proxmox_storage: "local" # or specific storage for users
|
||||||
57
playbooks/README.md
Normal file
57
playbooks/README.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Ansible Playbooks
|
||||||
|
|
||||||
|
This directory contains automation playbooks for managing the homelab infrastructure.
|
||||||
|
|
||||||
|
## Provisioning & Setup
|
||||||
|
|
||||||
|
### `create_lxc.yml`
|
||||||
|
**Creates and bootstraps a new LXC container on Proxmox.**
|
||||||
|
- **Input**: Prompts for Container Name and IP Address.
|
||||||
|
- **Actions**:
|
||||||
|
1. Connects to Proxmox API to create a new unprivileged LXC container (Ubuntu 24.04).
|
||||||
|
2. Starts the container and waits for connectivity.
|
||||||
|
3. Temporarily adds the host to the inventory.
|
||||||
|
4. Automatically triggers `lxc_setup_ubuntu.yml` to secure the new container.
|
||||||
|
|
||||||
|
### `lxc_setup_ubuntu.yml`
|
||||||
|
**Secures a fresh Ubuntu installation.**
|
||||||
|
- **Target**: Hosts in the `[new]` group (or fresh installs).
|
||||||
|
- **Actions**:
|
||||||
|
1. Creates the administrative user (`mbuz`).
|
||||||
|
2. Sets up SSH public key authentication.
|
||||||
|
3. Disables root login and password authentication for SSH.
|
||||||
|
4. Configures passwordless `sudo` for the admin user.
|
||||||
|
5. **Inventory Update**: Moves the host from the `[new]` group to the `[lxc]` group in `hosts.ini`.
|
||||||
|
|
||||||
|
### `lxc_setup_ubuntu_git.yml`
|
||||||
|
**Provisions application dependencies on managed hosts.**
|
||||||
|
- **Target**: Existing managed hosts (e.g., `[lxc]`).
|
||||||
|
- **Actions**:
|
||||||
|
1. Installs `git` and core utilities.
|
||||||
|
2. Clones the central Docker configuration repository from the local Gitea server.
|
||||||
|
3. Prepares the `/opt/docker` directory structure.
|
||||||
|
|
||||||
|
## Maintenance & Upgrades
|
||||||
|
|
||||||
|
### `apt_upgrade.yml`
|
||||||
|
**Performs system-wide updates.**
|
||||||
|
- **Target**: All Ubuntu hosts.
|
||||||
|
- **Actions**:
|
||||||
|
1. Updates `apt` cache.
|
||||||
|
2. Performs `dist-upgrade`.
|
||||||
|
3. Autoremoves unused packages.
|
||||||
|
4. Checks for and notifies if a reboot is required.
|
||||||
|
|
||||||
|
### `zabbix_agent_upgrade.yml`
|
||||||
|
**Updates Zabbix Agent.**
|
||||||
|
- **Target**: `zagents` group.
|
||||||
|
- **Actions**:
|
||||||
|
1. Ensures `zabbix-agent2` is installed and updated to the latest available version.
|
||||||
|
|
||||||
|
### `zabbix_proxy_install.yml`
|
||||||
|
**Installs Zabbix Proxy and Agent.**
|
||||||
|
- **Target**: Specific Zabbix Proxy host.
|
||||||
|
- **Actions**:
|
||||||
|
1. Downloads and installs the Zabbix release package.
|
||||||
|
2. Installs `zabbix-proxy-sqlite3` and `zabbix-agent2`.
|
||||||
|
3. Configures PSK encryption and connection settings using `secrets.yml`.
|
||||||
69
playbooks/create_lxc.yml
Normal file
69
playbooks/create_lxc.yml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
- name: Create and Configure New LXC Container
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: no
|
||||||
|
vars_files:
|
||||||
|
- "../secrets.yml"
|
||||||
|
vars_prompt:
|
||||||
|
- name: container_name
|
||||||
|
prompt: "Enter the new container name (e.g., my-service)"
|
||||||
|
private: no
|
||||||
|
- name: container_ip
|
||||||
|
prompt: "Enter the IP address (CIDR format preferred, or I will append /24) e.g., 10.0.0.123"
|
||||||
|
private: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Normalize IP address (append /24 if missing)
|
||||||
|
set_fact:
|
||||||
|
container_ip_cidr: "{{ container_ip if '/' in container_ip else container_ip + '/24' }}"
|
||||||
|
|
||||||
|
- name: Create LXC container on Proxmox
|
||||||
|
community.general.proxmox:
|
||||||
|
api_host: "{{ proxmox_host | default('10.0.0.1') }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ proxmox_node }}"
|
||||||
|
storage: "{{ proxmox_storage }}"
|
||||||
|
ostemplate: '{{ proxmox_storage }}:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst'
|
||||||
|
hostname: "{{ container_name }}"
|
||||||
|
password: "TempPassword123!" # Temporary password, will be disabled by lxc_setup
|
||||||
|
netif:
|
||||||
|
net0: "name=eth0,gw=10.0.0.1,ip={{ container_ip_cidr }},bridge=vmbr0"
|
||||||
|
cores: 2
|
||||||
|
memory: 1024
|
||||||
|
swap: 512
|
||||||
|
state: started
|
||||||
|
unprivileged: yes
|
||||||
|
features:
|
||||||
|
- nesting=1
|
||||||
|
register: proxmox_creation
|
||||||
|
|
||||||
|
- name: Wait for container to be reachable
|
||||||
|
wait_for:
|
||||||
|
host: "{{ container_ip_cidr | split('/') | first }}"
|
||||||
|
port: 22
|
||||||
|
search_regex: OpenSSH
|
||||||
|
delay: 10
|
||||||
|
timeout: 300
|
||||||
|
|
||||||
|
- name: Add new host to in-memory inventory (group 'new')
|
||||||
|
add_host:
|
||||||
|
name: "{{ container_name }}"
|
||||||
|
groups: new
|
||||||
|
ansible_host: "{{ container_ip_cidr | split('/') | first }}"
|
||||||
|
ansible_user: root
|
||||||
|
ansible_ssh_pass: "TempPassword123!"
|
||||||
|
# We need to ignore host key checking for the fresh container to avoid interactive prompt
|
||||||
|
ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||||
|
|
||||||
|
- name: Add new host to local hosts.ini file (persistency)
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ inventory_dir }}/hosts.ini"
|
||||||
|
block: |
|
||||||
|
{{ container_name }} ansible_host={{ container_ip_cidr | split('/') | first }} ansible_user=root
|
||||||
|
insertafter: "^\\[new\\]"
|
||||||
|
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR NEW HOST {{ container_name }}"
|
||||||
|
|
||||||
|
- name: Run Standard Setup on New Host
|
||||||
|
import_playbook: lxc_setup_ubuntu.yml
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Remove host from the [new] group
|
- name: Remove host from the [new] group
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /opt/ansible/inventory/hosts.ini
|
path: "{{ inventory_dir }}/hosts.ini"
|
||||||
regexp: "^{{ item }}\\s" # Match the start of the line with the hostname
|
regexp: "^{{ item }}\\s" # Match the start of the line with the hostname
|
||||||
state: absent
|
state: absent
|
||||||
loop: "{{ groups['new'] }}" # Loop over all hosts in the 'new' group
|
loop: "{{ groups['new'] }}" # Loop over all hosts in the 'new' group
|
||||||
|
|||||||
Reference in New Issue
Block a user