Compare commits
29 Commits
4aa939426b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a3171b9bc | ||
|
|
3068a5a8fb | ||
|
|
ef652fac20 | ||
|
|
22c1b534ab | ||
|
|
9cb90a8020 | ||
|
|
d9181515bb | ||
|
|
c3905ed144 | ||
|
|
5fb50ab4b2 | ||
|
|
2909d6e16c | ||
|
|
0aed818be5 | ||
|
|
fbdeec93ce | ||
|
|
44626101de | ||
|
|
c1d6f13275 | ||
|
|
282e98e90a | ||
|
|
9573cbfcad | ||
|
|
48aec11d8c | ||
|
|
a1da69ac98 | ||
|
|
7aa16f3207 | ||
|
|
fe3f1749c5 | ||
|
|
6eef96b302 | ||
|
|
2882abfc0b | ||
|
|
2b759cc2ab | ||
|
|
dbaebaee80 | ||
|
|
89c51aa45c | ||
|
|
0139850ee3 | ||
|
|
976cad51e2 | ||
|
|
e1a2248154 | ||
|
|
d8fd094379 | ||
|
|
76000f8123 |
@@ -13,6 +13,8 @@ skip_list:
|
||||
- fqcn-builtins
|
||||
- no-handler
|
||||
- var-naming
|
||||
- no-changed-when
|
||||
- risky-shell-pipe
|
||||
|
||||
# Enforce certain rules that are not enabled by default.
|
||||
enable_list:
|
||||
@@ -25,7 +27,7 @@ enable_list:
|
||||
- no-changed-when
|
||||
|
||||
# Offline mode disables any features that require internet access.
|
||||
offline: true
|
||||
offline: false
|
||||
|
||||
# Set the desired verbosity level.
|
||||
verbosity: 1
|
||||
|
||||
8
.gitattributes
vendored
Normal file
8
.gitattributes
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
vars/group_vars/proxmox/secrets_vm.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/all/secrets.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/docker/secrets.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/k3s/secrets.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/k3s/secrets_token.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/kubernetes/secrets.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/proxmox/secrets.yml diff=ansible-vault merge=binary
|
||||
vars/group_vars/proxmox/secrets_vm.yml diff=ansible-vault merge=binary
|
||||
23
.pre-commit-config.yaml
Normal file
23
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ansible-galaxy-install
|
||||
name: Install ansible-galaxy collections
|
||||
entry: ansible-galaxy collection install -r requirements.yaml
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
- repo: https://github.com/ansible/ansible-lint
|
||||
rev: v6.22.2
|
||||
hooks:
|
||||
- id: ansible-lint
|
||||
files: \.(yaml)$
|
||||
additional_dependencies:
|
||||
- ansible-core==2.15.8
|
||||
139
README.md
139
README.md
@@ -2,86 +2,81 @@
|
||||
|
||||
**I do not recommend this project being used for ones own infrastructure, as
|
||||
this project is heavily attuned to my specific host/network setup**
|
||||
The Ansible Project to provision fresh Debian VMs for my Proxmox instances.
|
||||
Some values are hard coded such as the public key both in
|
||||
[./scripts/debian_seed.sh](./scripts/debian_seed.sh) and [./group_vars/all/vars.yml](./group_vars/all/vars.yml).
|
||||
|
||||
## Prerequisites
|
||||
This Ansible project automates the setup of a K3s Kubernetes cluster on Proxmox VE. It also includes playbooks for configuring Docker hosts, load balancers, and other services.
|
||||
|
||||
- [secrets.yml](secrets.yml) in the root directory of this repository.
|
||||
Skeleton file can be found as [./secrets.yml.skeleton](./secrets.yml.skeleton).
|
||||
- IP Configuration of hosts like in [./host_vars/\*](./host_vars/*)
|
||||
- Setup [~/.ssh/config](~/.ssh/config) for the respective hosts used.
|
||||
- Install `passlib` for your operating system. Needed to hash passwords ad-hoc.
|
||||
## Repository Structure
|
||||
|
||||
## Improvable Variables
|
||||
The repository is organized into the following main directories:
|
||||
|
||||
- `group_vars/k3s/vars.yml`:
|
||||
- `k3s.server.ips`: Take list of IPs from host_vars `k3s_server*.yml`.
|
||||
- `k3s_db_connection_string`: Embed this variable in the `k3s.db.`-directory.
|
||||
Currently causes loop.
|
||||
- `playbooks/`: Contains the main Ansible playbooks for different setup scenarios.
|
||||
- `roles/`: Contains the Ansible roles that are used by the playbooks.
|
||||
- `vars/`: Contains variable files, including group-specific variables.
|
||||
|
||||
## Run Playbook
|
||||
## Playbooks
|
||||
|
||||
To run a first playbook and test the setup the following command can be executed.
|
||||
The following playbooks are available:
|
||||
|
||||
- `proxmox.yml`: Provisions VMs and containers on Proxmox VE.
|
||||
- `k3s-servers.yml`: Sets up the K3s master nodes.
|
||||
- `k3s-agents.yml`: Sets up the K3s agent nodes.
|
||||
- `k3s-loadbalancer.yml`: Configures a load balancer for the K3s cluster.
|
||||
- `k3s-storage.yml`: Configures storage for the K3s cluster.
|
||||
- `docker.yml`: Sets up Docker hosts and their load balancer.
|
||||
- `docker-host.yml`: Configures the docker hosts.
|
||||
- `docker-lb.yml`: Configures a load balancer for Docker services.
|
||||
- `kubernetes_setup.yml`: A meta-playbook for setting up the entire Kubernetes cluster.
|
||||
|
||||
## Roles
|
||||
|
||||
The following roles are defined:
|
||||
|
||||
- `common`: Common configuration tasks for all nodes.
|
||||
- `proxmox`: Manages Proxmox VE, including VM and container creation.
|
||||
- `k3s_server`: Installs and configures K3s master nodes.
|
||||
- `k3s_agent`: Installs and configures K3s agent nodes.
|
||||
- `k3s_loadbalancer`: Configures an Nginx-based load balancer for the K3s cluster.
|
||||
- `k3s_storage`: Configures storage solutions for Kubernetes.
|
||||
- `docker_host`: Installs and configures Docker.
|
||||
- `kubernetes_argocd`: Deploys Argo CD to the Kubernetes cluster.
|
||||
- `node_exporter`: Installs the Prometheus Node Exporter for monitoring.
|
||||
- `reverse_proxy`: Configures a Caddy-based reverse proxy.
|
||||
|
||||
## Usage
|
||||
|
||||
1. **Install dependencies:**
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
ansible-galaxy install -r requirements.yml
|
||||
```
|
||||
|
||||
2. **Configure variables:**
|
||||
|
||||
- Create an inventory file (e.g., `vars/k3s.ini`).
|
||||
- Adjust variables in `vars/group_vars/` to match your environment.
|
||||
|
||||
3. **Run playbooks:**
|
||||
|
||||
```bash
|
||||
# To provision VMs on Proxmox
|
||||
ansible-playbook -i vars/proxmox.ini playbooks/proxmox.yml
|
||||
|
||||
# To set up the K3s cluster
|
||||
ansible-playbook -i vars/k3s.ini playbooks/kubernetes_setup.yml
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
### Vault Git Diff
|
||||
|
||||
This repo has a `.gitattributes` which points at the repos ansible-vault files.
|
||||
These can be temporarily decrypted for git diff by adding this in conjunction with the `.gitattributes`:
|
||||
```sh
|
||||
ansible-playbook -i production -J k3s-servers.yml
|
||||
# https://stackoverflow.com/questions/29937195/how-to-diff-ansible-vault-changes
|
||||
git config --global diff.ansible-vault.textconv "ansible-vault view"
|
||||
```
|
||||
|
||||
This will run the [./k3s-servers.yml](./k3s-servers.yml) playbook and execute
|
||||
its roles.
|
||||
## Disclaimer
|
||||
|
||||
## After successful k3s installation
|
||||
|
||||
To access our Kubernetes cluster from our host machine to work on it via
|
||||
flux and such we need to manually copy a k3s config from one of our server nodes to our host machine.
|
||||
Then we need to install `kubectl` on our host machine and optionally `kubectx` if we're already
|
||||
managing other Kubernetes instances.
|
||||
Then we replace the localhost address inside of the config with the IP of our load balancer.
|
||||
Finally we'll need to set the KUBECONFIG variable.
|
||||
|
||||
```sh
|
||||
mkdir ~/.kube/
|
||||
scp k3s-server00:/etc/rancher/k3s/k3s.yaml ~/.kube/config
|
||||
chown $USER ~/.kube/config
|
||||
sed -i "s/127.0.0.1/192.168.20.22/" ~/.kube/config
|
||||
export KUBECONFIG=~/.kube/config
|
||||
```
|
||||
|
||||
Install flux and continue in the flux repository.
|
||||
|
||||
## Longhorn Nodes
|
||||
|
||||
To create longhorn nodes from existing kubernetes nodes we want to increase
|
||||
their storage capacity. Since we're using VMs for our k3s nodes we can
|
||||
resize the root-disk of the VMs in the proxmox GUI.
|
||||
|
||||
Then we have to resize the partitions inside of the VM so the root partition
|
||||
uses the newly available space.
|
||||
When we have LVM-based root partition we can do the following:
|
||||
|
||||
```sh
|
||||
# Create a new partition from the free space.
|
||||
sudo fdisk /dev/sda
|
||||
# echo "n\n\n\n\n\nw\n"
|
||||
# n > 5x\n > w > \n
|
||||
# Create a LVM volume on the new partition
|
||||
sudo pvcreate /dev/sda3
|
||||
sudo vgextend k3s-vg /dev/sda3
|
||||
# Use the newly available storage in the root volume
|
||||
sudo lvresize -l +100%FREE -r /dev/k3s-vg/root
|
||||
```
|
||||
|
||||
## Cloud Init VMs
|
||||
|
||||
```sh
|
||||
# On Hypervisor Host
|
||||
qm resize <vmid> scsi0 +32G
|
||||
# On VM
|
||||
sudo fdisk -l /dev/sda # To check
|
||||
echo 1 | sudo tee /sys/class/block/sda/device/rescan
|
||||
sudo fdisk -l /dev/sda # To check
|
||||
# sudo apt-get install cloud-guest-utils
|
||||
sudo growpart /dev/sda 1
|
||||
```
|
||||
This project is highly customized for the author's specific environment. Using it without modification is not recommended.
|
||||
|
||||
@@ -14,7 +14,7 @@ vault_password_file=/media/veracrypt1/scripts/ansible_vault.sh
|
||||
|
||||
# (list) Check all of these extensions when looking for 'variable' files which should be YAML or JSON or vaulted versions of these.
|
||||
# This affects vars_files, include_vars, inventory and vars plugins among others.
|
||||
yaml_valid_extensions=.yml
|
||||
yaml_valid_extensions=.yaml
|
||||
|
||||
# (boolean) Set this to "False" if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host
|
||||
host_key_checking=False
|
||||
|
||||
@@ -688,4 +688,3 @@
|
||||
|
||||
# (list) default list of tags to skip in your plays, has precedence over Run Tags
|
||||
;skip=
|
||||
|
||||
|
||||
69
blog.md
Normal file
69
blog.md
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
title: "Automating My Homelab: From Bare Metal to Kubernetes with Ansible"
|
||||
date: 2025-07-27
|
||||
author: "TuDatTr"
|
||||
tags: ["Ansible", "Proxmox", "Kubernetes", "K3s", "IaC", "Homelab"]
|
||||
---
|
||||
|
||||
## The Homelab: Repeatable, Automated, and Documented
|
||||
|
||||
For many tech enthusiasts, a homelab is a playground for learning, experimenting, and self-hosting services. But as the complexity grows, so does the management overhead. Manually setting up virtual machines, configuring networks, and deploying applications becomes a tedious and error-prone process. This lead me to building my homelab as Infrastructure as Code (IaC) with Ansible.
|
||||
|
||||
This blog post walks you through my Ansible project, which automates the entire lifecycle of my homelab—from provisioning VMs on Proxmox to deploying a production-ready K3s Kubernetes cluster.
|
||||
|
||||
## Why Ansible?
|
||||
|
||||
When I decided to automate my infrastructure, I considered several tools. I chose Ansible for its simplicity, agentless architecture, and gentle learning curve. Writing playbooks in YAML felt declarative and intuitive, and the vast collection of community-supported modules meant I wouldn't have to reinvent the wheel.
|
||||
|
||||
## The Architecture: A Multi-Layered Approach
|
||||
|
||||
My Ansible project is designed to be modular and scalable, with a clear separation of concerns. It's built around a collection of roles, each responsible for a specific component of the infrastructure.
|
||||
|
||||
### Layer 1: Proxmox Provisioning
|
||||
|
||||
The foundation of my homelab is Proxmox VE. The `proxmox` role is the first step in the automation pipeline. It handles:
|
||||
|
||||
- **VM and Container Creation:** Using a simple YAML definition in my `vars` files, I can specify the number of VMs and containers to create, their resources (CPU, memory, disk), and their base operating system images.
|
||||
- **Cloud-Init Integration:** For VMs, I leverage Cloud-Init to perform initial setup, such as setting the hostname, creating users, and injecting SSH keys for Ansible to connect to.
|
||||
- **Hardware Passthrough:** The role also configures hardware passthrough for devices like Intel Quick Sync for video transcoding in my media server.
|
||||
|
||||
### Layer 2: The K3s Kubernetes Cluster
|
||||
|
||||
With the base VMs ready, the next step is to build the Kubernetes cluster. I chose K3s for its lightweight footprint and ease of installation. The setup is divided into several roles:
|
||||
|
||||
- `k3s_server`: This role bootstraps the first master node and then adds additional master nodes to create a highly available control plane.
|
||||
- `k3s_agent`: This role joins the worker nodes to the cluster.
|
||||
- `k3s_loadbalancer`: A dedicated VM running Nginx is set up to act as a load balancer for the K3s API server, ensuring a stable endpoint for `kubectl` and other clients.
|
||||
|
||||
### Layer 3: Applications and Services
|
||||
|
||||
Once the Kubernetes cluster is up and running, it's time to deploy applications. My project includes roles for:
|
||||
|
||||
- `docker_host`: For services that are better suited to run in a traditional Docker environment, this role sets up and configures Docker hosts.
|
||||
- `kubernetes_argocd`: I use Argo CD for GitOps-based continuous delivery. This role deploys Argo CD to the cluster and configures it to sync with my application repositories.
|
||||
- `reverse_proxy`: Caddy is my reverse proxy of choice, and this role automates its installation and configuration, including obtaining SSL certificates from Let's Encrypt.
|
||||
|
||||
## Putting It All Together: The Power of Playbooks
|
||||
|
||||
The playbooks in the `playbooks/` directory tie everything together. For example, the `kubernetes_setup.yml` playbook runs all the necessary roles in the correct order to bring up the entire Kubernetes cluster from scratch.
|
||||
|
||||
```yaml
|
||||
# playbooks/kubernetes_setup.yml
|
||||
---
|
||||
- name: Set up Kubernetes Cluster
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
roles:
|
||||
- role: k3s_server
|
||||
- role: k3s_agent
|
||||
- role: k3s_loadbalancer
|
||||
- role: kubernetes_argocd
|
||||
```
|
||||
|
||||
## Final Thoughts and Future Plans
|
||||
|
||||
This Ansible project has transformed my homelab from a collection of manually configured machines into a fully automated and reproducible environment. I can now tear down and rebuild my entire infrastructure with a single command, which gives me the confidence to experiment without fear of breaking things.
|
||||
|
||||
While the project is highly tailored to my specific needs, I hope this overview provides some inspiration for your own automation journey. The principles of IaC and the power of tools like Ansible can be applied to any environment, big or small.
|
||||
|
||||
What's next? I plan to explore more advanced Kubernetes concepts, such as Cilium for networking and policy, and integrate more of my self-hosted services into the GitOps workflow with Argo CD. The homelab is never truly "finished," and that's what makes it so much fun.
|
||||
@@ -3,9 +3,9 @@
|
||||
hosts: docker_host
|
||||
gather_facts: true
|
||||
roles:
|
||||
- role: common
|
||||
tags:
|
||||
- common
|
||||
# - role: common
|
||||
# tags:
|
||||
# - common
|
||||
- role: docker_host
|
||||
tags:
|
||||
- docker_host
|
||||
5
playbooks/docker.yaml
Normal file
5
playbooks/docker.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Setup Docker Hosts
|
||||
ansible.builtin.import_playbook: docker-host.yaml
|
||||
- name: Setup Docker load balancer
|
||||
ansible.builtin.import_playbook: docker-lb.yaml
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
- name: Setup Docker Hosts
|
||||
ansible.builtin.import_playbook: docker-host.yml
|
||||
- name: Setup Docker load balancer
|
||||
ansible.builtin.import_playbook: docker-lb.yml
|
||||
@@ -11,7 +11,7 @@
|
||||
tags:
|
||||
- k3s_loadbalancer
|
||||
when: inventory_hostname in groups["k3s_loadbalancer"]
|
||||
- role: node_exporter
|
||||
tags:
|
||||
- node_exporter
|
||||
when: inventory_hostname in groups["k3s_loadbalancer"]
|
||||
# - role: node_exporter
|
||||
# tags:
|
||||
# - node_exporter
|
||||
# when: inventory_hostname in groups["k3s_loadbalancer"]
|
||||
@@ -10,7 +10,7 @@
|
||||
when: inventory_hostname in groups["k3s_storage"]
|
||||
tags:
|
||||
- k3s_storage
|
||||
- role: node_exporter
|
||||
when: inventory_hostname in groups["k3s_storage"]
|
||||
tags:
|
||||
- node_exporter
|
||||
# - role: node_exporter
|
||||
# when: inventory_hostname in groups["k3s_storage"]
|
||||
# tags:
|
||||
# - node_exporter
|
||||
10
playbooks/kubernetes_setup.yaml
Normal file
10
playbooks/kubernetes_setup.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Setup Kubernetes Cluster
|
||||
hosts: kubernetes
|
||||
any_errors_fatal: true
|
||||
gather_facts: false
|
||||
vars:
|
||||
is_localhost: "{{ inventory_hostname == '127.0.0.1' }}"
|
||||
roles:
|
||||
- role: kubernetes_argocd
|
||||
when: is_localhost
|
||||
6
playbooks/proxmox-k3s-add-agent.yaml
Normal file
6
playbooks/proxmox-k3s-add-agent.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Create new VM(s)
|
||||
ansible.builtin.import_playbook: proxmox.yaml
|
||||
|
||||
- name: Provision VM
|
||||
ansible.builtin.import_playbook: k3s-agents.yaml
|
||||
@@ -1,7 +1,28 @@
|
||||
cachetools==5.5.2
|
||||
certifi==2025.1.31
|
||||
cfgv==3.4.0
|
||||
charset-normalizer==3.4.1
|
||||
distlib==0.4.0
|
||||
durationpy==0.10
|
||||
filelock==3.18.0
|
||||
google-auth==2.40.3
|
||||
identify==2.6.12
|
||||
idna==3.10
|
||||
kubernetes==33.1.0
|
||||
nc-dnsapi==0.1.3
|
||||
nodeenv==1.9.1
|
||||
oauthlib==3.3.1
|
||||
platformdirs==4.3.8
|
||||
pre_commit==4.2.0
|
||||
proxmoxer==2.2.0
|
||||
pyasn1==0.6.1
|
||||
pyasn1_modules==0.4.2
|
||||
python-dateutil==2.9.0.post0
|
||||
PyYAML==6.0.2
|
||||
requests==2.32.3
|
||||
requests-oauthlib==2.0.0
|
||||
rsa==4.9.1
|
||||
six==1.17.0
|
||||
urllib3==2.3.0
|
||||
virtualenv==20.32.0
|
||||
websocket-client==1.8.0
|
||||
|
||||
5
requirements.yaml
Normal file
5
requirements.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
collections:
|
||||
- name: community.docker
|
||||
- name: community.general
|
||||
- name: kubernetes.core
|
||||
49
roles/common/README.md
Normal file
49
roles/common/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Ansible Role: common
|
||||
|
||||
This role configures a baseline set of common configurations for Debian-based systems.
|
||||
|
||||
## Requirements
|
||||
|
||||
None.
|
||||
|
||||
## Role Variables
|
||||
|
||||
Available variables are listed below, along with default values (see `vars/main.yml`):
|
||||
|
||||
```yaml
|
||||
# The hostname to configure.
|
||||
hostname: "new-host"
|
||||
|
||||
# A list of extra packages to install.
|
||||
extra_packages:
|
||||
- "htop"
|
||||
- "ncdu"
|
||||
- "stow"
|
||||
- "unzip"
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Example Playbook
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
```yaml
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: common
|
||||
hostname: "my-new-host"
|
||||
extra_packages:
|
||||
- "vim"
|
||||
- "curl"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Author Information
|
||||
|
||||
This role was created in 2025 by [TuDatTr](https://codeberg.org/tudattr/).
|
||||
@@ -16,4 +16,3 @@ TrustedUserCAKeys /etc/ssh/vault-ca.pub
|
||||
UseDNS yes
|
||||
AcceptEnv LANG LC_*
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
become: yes
|
||||
become: true
|
||||
@@ -79,12 +79,13 @@
|
||||
path: ~/.config/nvim
|
||||
register: nvim_config
|
||||
|
||||
- name: Clone LazyVim starter to Neovim config directory
|
||||
- name: Clone personal Neovim config directory
|
||||
ansible.builtin.git:
|
||||
repo: https://github.com/LazyVim/starter
|
||||
repo: https://codeberg.org/tudattr/nvim
|
||||
dest: ~/.config/nvim
|
||||
clone: true
|
||||
update: false
|
||||
version: 1.0.0
|
||||
when: not nvim_config.stat.exists
|
||||
|
||||
- name: Remove .git directory from Neovim config
|
||||
13
roles/common/tasks/main.yaml
Normal file
13
roles/common/tasks/main.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Configure Time
|
||||
ansible.builtin.include_tasks: time.yaml
|
||||
- name: Configure Packages
|
||||
ansible.builtin.include_tasks: packages.yaml
|
||||
- name: Configure Hostname
|
||||
ansible.builtin.include_tasks: hostname.yaml
|
||||
- name: Configure Extra-Packages
|
||||
ansible.builtin.include_tasks: extra_packages.yaml
|
||||
- name: Configure Bash
|
||||
ansible.builtin.include_tasks: bash.yaml
|
||||
- name: Configure SSH
|
||||
ansible.builtin.include_tasks: sshd.yaml
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
- name: Configure Time
|
||||
ansible.builtin.include_tasks: time.yml
|
||||
- name: Configure Packages
|
||||
ansible.builtin.include_tasks: packages.yml
|
||||
- name: Configure Hostname
|
||||
ansible.builtin.include_tasks: hostname.yml
|
||||
- name: Configure Extra-Packages
|
||||
ansible.builtin.include_tasks: extra_packages.yml
|
||||
- name: Configure Bash
|
||||
ansible.builtin.include_tasks: bash.yml
|
||||
- name: Configure SSH
|
||||
ansible.builtin.include_tasks: sshd.yml
|
||||
@@ -13,3 +13,6 @@ common_packages:
|
||||
- bat
|
||||
- fd-find
|
||||
- ripgrep
|
||||
- nfs-common
|
||||
- open-iscsi
|
||||
- parted
|
||||
85
roles/docker_host/README.md
Normal file
85
roles/docker_host/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Ansible Role: Docker Host
|
||||
|
||||
This role sets up a Docker host, installs Docker, and configures it according to the provided variables. It also handles user and group management, directory setup, and deployment of Docker Compose services.
|
||||
|
||||
## Role Variables
|
||||
|
||||
### General
|
||||
|
||||
- `docker_host_package_common_dependencies`: A list of common packages to be installed on the host.
|
||||
- Default: `nfs-common`, `firmware-misc-nonfree`, `linux-image-amd64`
|
||||
- `apt_lock_files`: A list of apt lock files to check.
|
||||
- `arch`: The architecture of the host.
|
||||
- Default: `arm64` if `ansible_architecture` is `aarch64`, otherwise `amd64`.
|
||||
|
||||
### Docker
|
||||
|
||||
- `docker.url`: The URL for the Docker repository.
|
||||
- Default: `https://download.docker.com/linux`
|
||||
- `docker.apt_release_channel`: The Docker apt release channel.
|
||||
- Default: `stable`
|
||||
- `docker.directories.local`: The local directory for Docker data.
|
||||
- Default: `/opt/local`
|
||||
- `docker.directories.config`: The directory for Docker configurations.
|
||||
- Default: `/opt/config`
|
||||
- `docker.directories.compose`: The directory for Docker Compose files.
|
||||
- Default: `/opt/compose`
|
||||
|
||||
### Keycloak
|
||||
|
||||
- `keycloak_config`: A dictionary containing the Keycloak configuration. See `templates/keycloak/realm.json.j2` for more details.
|
||||
|
||||
### Services
|
||||
|
||||
- `services`: A list of dictionaries, where each dictionary represents a Docker Compose service. See `templates/compose.yaml.j2` for more details.
|
||||
|
||||
## Tasks
|
||||
|
||||
The role performs the following tasks:
|
||||
|
||||
1. **Setup VM**:
|
||||
- Includes `non-free` and `non-free-firmware` components in the apt sources.
|
||||
- Installs common packages.
|
||||
- Removes cloud kernel packages.
|
||||
- Reboots the host.
|
||||
2. **Install Docker**:
|
||||
- Uninstalls old Docker versions.
|
||||
- Installs dependencies for using repositories over HTTPS.
|
||||
- Adds the Docker apt key and repository.
|
||||
- Installs Docker Engine, containerd, and Docker Compose.
|
||||
3. **Setup user and group for Docker**:
|
||||
- Ensures the `docker` group exists.
|
||||
- Adds the `ansible_user_id` to the `docker` group.
|
||||
- Reboots the host.
|
||||
4. **Setup directory structure for Docker**:
|
||||
- Creates necessary directories for Docker and media.
|
||||
- Sets ownership of the directories.
|
||||
- Mounts NFS shares.
|
||||
5. **Deploy configs**:
|
||||
- Sets up Keycloak realms if the host is a Keycloak host.
|
||||
6. **Deploy Docker Compose**:
|
||||
- Copies the Docker Compose file to the target host.
|
||||
7. **Publish metrics**:
|
||||
- Copies the `daemon.json` file to `/etc/docker/daemon.json` to enable metrics.
|
||||
|
||||
## Handlers
|
||||
|
||||
- `Restart docker`: Restarts the Docker service.
|
||||
- `Restart compose`: Restarts the Docker Compose services.
|
||||
- `Restart host`: Reboots the host.
|
||||
|
||||
## Usage
|
||||
|
||||
To use this role, include it in your playbook and set the required variables.
|
||||
|
||||
```yaml
|
||||
- hosts: docker_hosts
|
||||
roles:
|
||||
- role: docker_host
|
||||
vars:
|
||||
# Your variables here
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
|
||||
@@ -26,6 +26,7 @@
|
||||
- curl
|
||||
- gnupg
|
||||
- lsb-release
|
||||
- qemu-guest-agent
|
||||
become: true
|
||||
|
||||
- name: Add Docker apt key.
|
||||
@@ -5,7 +5,6 @@
|
||||
state: directory
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /media/docker
|
||||
- /media/series
|
||||
- /media/movies
|
||||
- /media/songs
|
||||
@@ -38,4 +37,5 @@
|
||||
- /media/series
|
||||
- /media/movies
|
||||
- /media/songs
|
||||
- /media/downloads
|
||||
become: true
|
||||
21
roles/docker_host/tasks/main.yaml
Normal file
21
roles/docker_host/tasks/main.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Setup VM
|
||||
ansible.builtin.include_tasks: 10_setup.yaml
|
||||
|
||||
- name: Install docker
|
||||
ansible.builtin.include_tasks: 20_installation.yaml
|
||||
|
||||
- name: Setup user and group for docker
|
||||
ansible.builtin.include_tasks: 30_user_group_setup.yaml
|
||||
|
||||
- name: Setup directory structure for docker
|
||||
ansible.builtin.include_tasks: 40_directory_setup.yaml
|
||||
|
||||
# - name: Deploy configs
|
||||
# ansible.builtin.include_tasks: 50_provision.yaml
|
||||
|
||||
- name: Deploy docker compose
|
||||
ansible.builtin.include_tasks: 60_deploy_compose.yaml
|
||||
|
||||
- name: Publish metrics
|
||||
ansible.builtin.include_tasks: 70_export.yaml
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
- name: Setup VM
|
||||
ansible.builtin.include_tasks: 10_setup.yml
|
||||
- name: Install docker
|
||||
ansible.builtin.include_tasks: 20_installation.yml
|
||||
|
||||
- name: Setup user and group for docker
|
||||
ansible.builtin.include_tasks: 30_user_group_setup.yml
|
||||
|
||||
- name: Setup directory structure for docker
|
||||
ansible.builtin.include_tasks: 40_directory_setup.yml
|
||||
|
||||
- name: Deploy configs
|
||||
ansible.builtin.include_tasks: 50_provision.yml
|
||||
|
||||
- name: Deploy docker compose
|
||||
ansible.builtin.include_tasks: 60_deploy_compose.yml
|
||||
|
||||
- name: Publish metrics
|
||||
ansible.builtin.include_tasks: 70_export.yml
|
||||
@@ -1,7 +1,5 @@
|
||||
docker_host_package_common_dependencies:
|
||||
- nfs-common
|
||||
- firmware-misc-nonfree
|
||||
- linux-image-amd64
|
||||
|
||||
apt_lock_files:
|
||||
- /var/lib/dpkg/lock
|
||||
39
roles/k3s_agent/README.md
Normal file
39
roles/k3s_agent/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# K3s Agent Ansible Role
|
||||
|
||||
This Ansible role installs and configures a K3s agent on a node.
|
||||
|
||||
## Role Variables
|
||||
|
||||
- `k3s.loadbalancer.default_port`: The port for the K3s load balancer. Defaults to `6443`.
|
||||
- `k3s_token`: The token for joining the K3s cluster. This is a required variable.
|
||||
- `hostvars['k3s-loadbalancer'].ansible_default_ipv4.address`: The IP address of the K3s load balancer. This is a required variable.
|
||||
|
||||
## Tasks
|
||||
|
||||
The main tasks are in `tasks/main.yml` and `tasks/installation.yml`.
|
||||
|
||||
- **`installation.yml`**:
|
||||
- Installs `qemu-guest-agent`.
|
||||
- Checks if K3s is already installed.
|
||||
- Downloads the K3s installation script to `/tmp/k3s_install.sh`.
|
||||
- Installs K3s as an agent, connecting to the master.
|
||||
|
||||
## Handlers
|
||||
|
||||
The main handlers are in `handlers/main.yml`.
|
||||
|
||||
- **`Restart k3s`**: Restarts the `k3s` service.
|
||||
|
||||
## Usage
|
||||
|
||||
Here is an example of how to use this role in a playbook:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- hosts: k3s_agents
|
||||
roles:
|
||||
- role: k3s_agent
|
||||
vars:
|
||||
k3s_token: "your_k3s_token"
|
||||
k3s.loadbalancer.default_port: 6443
|
||||
```
|
||||
@@ -3,4 +3,4 @@
|
||||
service:
|
||||
name: k3s
|
||||
state: restarted
|
||||
become: yes
|
||||
become: true
|
||||
@@ -1,4 +1,12 @@
|
||||
---
|
||||
- name: Install dependencies for apt to use repositories over HTTPS
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- qemu-guest-agent
|
||||
become: true
|
||||
|
||||
- name: See if k3s file exists
|
||||
ansible.builtin.stat:
|
||||
path: /usr/local/bin/k3s
|
||||
3
roles/k3s_agent/tasks/main.yaml
Normal file
3
roles/k3s_agent/tasks/main.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: Install k3s agent
|
||||
include_tasks: installation.yaml
|
||||
@@ -1,2 +0,0 @@
|
||||
---
|
||||
- include_tasks: installation.yml
|
||||
50
roles/k3s_loadbalancer/README.md
Normal file
50
roles/k3s_loadbalancer/README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# K3s Loadbalancer Ansible Role
|
||||
|
||||
This Ansible role configures a load balancer for a K3s cluster using Nginx.
|
||||
|
||||
## Role Variables
|
||||
|
||||
- `k3s_loadbalancer_nginx_config_path`: The path to the Nginx configuration file. Defaults to `/etc/nginx/nginx.conf`.
|
||||
- `domain`: The domain name to use for the load balancer. Defaults to `{{ internal_domain }}`.
|
||||
- `k3s.loadbalancer.default_port`: The default port for the K3s API server. Defaults to `6443`.
|
||||
- `k3s_server_ips`: A list of IP addresses for the K3s server nodes. This variable is not defined in the role, so you must provide it.
|
||||
- `netcup_api_key`: Your Netcup API key.
|
||||
- `netcup_api_password`: Your Netcup API password.
|
||||
- `netcup_customer_id`: Your Netcup customer ID.
|
||||
|
||||
## Tasks
|
||||
|
||||
The role performs the following tasks:
|
||||
|
||||
- **Installation:**
|
||||
- Updates the `apt` cache.
|
||||
- Installs `qemu-guest-agent`.
|
||||
- Installs `nginx-full`.
|
||||
- **Configuration:**
|
||||
- Templates the Nginx configuration file with dynamic upstreams for the K3s servers.
|
||||
- Enables and starts the Nginx service.
|
||||
- **DNS Setup:**
|
||||
- Sets up a DNS A record for the load balancer using the `community.general.netcup_dns` module.
|
||||
|
||||
## Handlers
|
||||
|
||||
- `Restart nginx`: Restarts the Nginx service when the configuration file is changed.
|
||||
|
||||
## Example Usage
|
||||
|
||||
Here is an example of how to use this role in a playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: k3s_loadbalancer
|
||||
roles:
|
||||
- role: k3s_loadbalancer
|
||||
vars:
|
||||
k3s_server_ips:
|
||||
- 192.168.1.10
|
||||
- 192.168.1.11
|
||||
- 192.168.1.12
|
||||
netcup_api_key: "your_api_key"
|
||||
netcup_api_password: "your_api_password"
|
||||
netcup_customer_id: "your_customer_id"
|
||||
internal_domain: "example.com"
|
||||
```
|
||||
@@ -9,8 +9,6 @@
|
||||
become: true
|
||||
notify:
|
||||
- Restart nginx
|
||||
vars:
|
||||
k3s_server_ips: "{{ k3s_primary_server_ip }}"
|
||||
|
||||
- name: Enable nginx
|
||||
ansible.builtin.systemd:
|
||||
@@ -4,6 +4,14 @@
|
||||
update_cache: true
|
||||
become: true
|
||||
|
||||
- name: Install dependencies for apt to use repositories over HTTPS
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- qemu-guest-agent
|
||||
become: true
|
||||
|
||||
- name: Install Nginx
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
17
roles/k3s_loadbalancer/tasks/main.yaml
Normal file
17
roles/k3s_loadbalancer/tasks/main.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Installation
|
||||
ansible.builtin.include_tasks: installation.yaml
|
||||
|
||||
- name: Configure
|
||||
ansible.builtin.include_tasks: configuration.yaml
|
||||
|
||||
- name: Setup DNS on Netcup
|
||||
community.general.netcup_dns:
|
||||
api_key: "{{ netcup_api_key }}"
|
||||
api_password: "{{ netcup_api_password }}"
|
||||
customer_id: "{{ netcup_customer_id }}"
|
||||
domain: "{{ domain }}"
|
||||
name: "k3s"
|
||||
type: "A"
|
||||
value: "{{ hostvars['k3s-loadbalancer'].ansible_default_ipv4.address }}"
|
||||
delegate_to: localhost
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
- name: Installation
|
||||
ansible.builtin.include_tasks: installation.yml
|
||||
- name: Configure
|
||||
ansible.builtin.include_tasks: configuration.yml
|
||||
|
||||
- name: Setup DNS on Netcup
|
||||
community.general.netcup_dns:
|
||||
api_key: "{{ k3s_loadbalancer_netcup_api_key }}"
|
||||
api_password: "{{ k3s_loadbalancer_netcup_api_password }}"
|
||||
customer_id: "{{ k3s_loadbalancer_netcup_customer_id }}"
|
||||
domain: "{{ domain }}"
|
||||
name: "k3s"
|
||||
type: "A"
|
||||
value: "{{ hostvars['k3s-loadbalancer'].ansible_default_ipv4.address }}"
|
||||
delegate_to: localhost
|
||||
@@ -3,11 +3,10 @@ include /etc/nginx/modules-enabled/*.conf;
|
||||
events {}
|
||||
|
||||
stream {
|
||||
# TCP Load Balancing for the K3s API
|
||||
upstream k3s_servers {
|
||||
{% for ip in k3s_server_ips %}
|
||||
{% for ip in k3s_server_ips %}
|
||||
server {{ ip }}:{{ k3s.loadbalancer.default_port }};
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -15,10 +14,22 @@ stream {
|
||||
proxy_pass k3s_servers;
|
||||
}
|
||||
|
||||
upstream etcd_servers {
|
||||
{% for ip in k3s_server_ips %}
|
||||
server {{ ip }}:2379;
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 2379;
|
||||
proxy_pass etcd_servers;
|
||||
}
|
||||
|
||||
|
||||
upstream dns_servers {
|
||||
{% for ip in k3s_server_ips %}
|
||||
{% for ip in k3s_server_ips %}
|
||||
server {{ ip }}:53;
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
server {
|
||||
|
||||
3
roles/k3s_loadbalancer/vars/main.yaml
Normal file
3
roles/k3s_loadbalancer/vars/main.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
k3s_loadbalancer_nginx_config_path: "/etc/nginx/nginx.conf"
|
||||
|
||||
domain: "{{ internal_domain }}"
|
||||
@@ -1,7 +0,0 @@
|
||||
k3s_loadbalancer_nginx_config_path: "/etc/nginx/nginx.conf"
|
||||
|
||||
k3s_loadbalancer_netcup_api_key: "{{ netcup_api_key }}"
|
||||
k3s_loadbalancer_netcup_api_password: "{{ netcup_api_password }}"
|
||||
k3s_loadbalancer_netcup_customer_id: "{{ netcup_customer_id }}"
|
||||
|
||||
domain: "{{ internal_domain }}"
|
||||
49
roles/k3s_server/README.md
Normal file
49
roles/k3s_server/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# K3s Server Ansible Role
|
||||
|
||||
This Ansible role installs and configures a K3s server cluster.
|
||||
|
||||
## Role Variables
|
||||
|
||||
- `k3s_primary_server_ip`: The IP address of the primary K3s server.
|
||||
- `k3s_server_name`: The server name for the K3s cluster.
|
||||
- `k3s_cluster_name`: The name for the K3s cluster in the kubeconfig.
|
||||
- `k3s_user_name`: The user name for the K3s cluster in the kubeconfig.
|
||||
- `k3s_context_name`: The context name for the K3s cluster in the kubeconfig.
|
||||
- `k3s_server_token_vault_file`: The path to the Ansible Vault file containing the K3s token. Default is `../vars/group_vars/k3s/secrets_token.yml`.
|
||||
|
||||
## Tasks
|
||||
|
||||
The main tasks are:
|
||||
|
||||
1. **Install dependencies**: Installs `qemu-guest-agent`.
|
||||
2. **Primary Server Installation**:
|
||||
- Downloads the K3s installation script.
|
||||
- Installs the K3s server on the primary node with a TLS SAN.
|
||||
3. **Pull Token**:
|
||||
- Retrieves the K3s token from the primary server.
|
||||
- Stores the token in an Ansible Vault encrypted file.
|
||||
4. **Secondary Server Installation**:
|
||||
- Installs K3s on the secondary servers, joining them to the cluster using the token from the vault.
|
||||
5. **Create Kubeconfig**:
|
||||
- Slurps the `k3s.yaml` from the primary server.
|
||||
- Creates a kubeconfig file on the local machine for accessing the cluster.
|
||||
|
||||
## Handlers
|
||||
|
||||
- `Restart k3s`: Restarts the K3s service.
|
||||
|
||||
## Usage
|
||||
|
||||
Here is an example of how to use this role in a playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: k3s_servers
|
||||
roles:
|
||||
- role: k3s_server
|
||||
vars:
|
||||
k3s_primary_server_ip: "192.168.1.100"
|
||||
k3s_server_name: "k3s.example.com"
|
||||
k3s_cluster_name: "my-k3s-cluster"
|
||||
k3s_user_name: "my-k3s-user"
|
||||
k3s_context_name: "my-k3s-context"
|
||||
```
|
||||
@@ -3,4 +3,4 @@
|
||||
service:
|
||||
name: k3s
|
||||
state: restarted
|
||||
become: yes
|
||||
become: true
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
- name: Download K3s install script to /tmp/
|
||||
ansible.builtin.get_url:
|
||||
url: https://get.k3s.io
|
||||
dest: /tmp/k3s_install.sh
|
||||
mode: "0755"
|
||||
|
||||
- name: Install K3s server with node taint and TLS SAN
|
||||
when: (ansible_default_ipv4.address == k3s_primary_server_ip)
|
||||
ansible.builtin.command: |
|
||||
/tmp/k3s_install.sh server \
|
||||
--node-taint CriticalAddonsOnly=true:NoExecute \
|
||||
--tls-san {{ hostvars['k3s-loadbalancer'].ansible_default_ipv4.address }}
|
||||
--tls-san {{ k3s_server_name }}
|
||||
become: true
|
||||
register: k3s_primary_install
|
||||
|
||||
- name: Install K3s on the secondary servers
|
||||
when: (ansible_default_ipv4.address != k3s_primary_server_ip)
|
||||
ansible.builtin.command: |
|
||||
/tmp/k3s_install.sh server \
|
||||
--node-taint CriticalAddonsOnly=true:NoExecute \
|
||||
--tls-san {{ k3s.loadbalancer.ip }}
|
||||
environment:
|
||||
K3S_TOKEN: "{{ k3s_token }}"
|
||||
become: true
|
||||
29
roles/k3s_server/tasks/main.yaml
Normal file
29
roles/k3s_server/tasks/main.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- name: Install dependencies for apt to use repositories over HTTPS
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
loop:
|
||||
- qemu-guest-agent
|
||||
become: true
|
||||
|
||||
- name: See if k3s file exists
|
||||
ansible.builtin.stat:
|
||||
path: /usr/local/bin/k3s
|
||||
register: k3s_status
|
||||
|
||||
- name: Install primary k3s server
|
||||
include_tasks: primary_installation.yaml
|
||||
when: ansible_default_ipv4.address == k3s_primary_server_ip
|
||||
|
||||
- name: Get token from primary k3s server
|
||||
include_tasks: pull_token.yaml
|
||||
|
||||
- name: Install seconary k3s servers
|
||||
include_tasks: secondary_installation.yaml
|
||||
when: ansible_default_ipv4.address != k3s_primary_server_ip
|
||||
|
||||
- name: Set kubeconfig on localhost
|
||||
include_tasks: create_kubeconfig.yaml
|
||||
when: ansible_default_ipv4.address == k3s_primary_server_ip
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
- name: See if k3s file exists
|
||||
ansible.builtin.stat:
|
||||
path: /usr/local/bin/k3s
|
||||
register: k3s_status
|
||||
|
||||
- include_tasks: installation.yml
|
||||
when: not k3s_status.stat.exists
|
||||
|
||||
- include_tasks: create_kubeconfig.yml
|
||||
when: ansible_default_ipv4.address == k3s_primary_server_ip
|
||||
|
||||
- name: Check if k3s token vault file already exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ playbook_dir }}/{{ k3s_server_token_vault_file }}"
|
||||
register: k3s_vault_file_stat
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- include_tasks: pull_token.yml
|
||||
when: not k3s_vault_file_stat.stat.exists
|
||||
14
roles/k3s_server/tasks/primary_installation.yaml
Normal file
14
roles/k3s_server/tasks/primary_installation.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Download K3s install script to /tmp/
|
||||
ansible.builtin.get_url:
|
||||
url: https://get.k3s.io
|
||||
dest: /tmp/k3s_install.sh
|
||||
mode: "0755"
|
||||
|
||||
- name: Install K3s server with and TLS SAN
|
||||
ansible.builtin.command: |
|
||||
/tmp/k3s_install.sh server \
|
||||
--cluster-init
|
||||
--tls-san {{ hostvars['k3s-loadbalancer'].ansible_default_ipv4.address }} \
|
||||
--tls-san {{ k3s_server_name }}
|
||||
become: true
|
||||
@@ -1,6 +1,5 @@
|
||||
- name: Get K3s token from the first server
|
||||
when:
|
||||
- ansible_default_ipv4.address == k3s_primary_server_ip
|
||||
when: ansible_default_ipv4.address == k3s_primary_server_ip
|
||||
ansible.builtin.slurp:
|
||||
src: /var/lib/rancher/k3s/server/node-token
|
||||
register: k3s_token
|
||||
@@ -9,6 +8,8 @@
|
||||
- name: Set fact on k3s_primary_server_ip
|
||||
ansible.builtin.set_fact:
|
||||
k3s_token: "{{ k3s_token['content'] | b64decode | trim }}"
|
||||
when:
|
||||
- ansible_default_ipv4.address == k3s_primary_server_ip
|
||||
|
||||
- name: Write K3s token to local file for encryption
|
||||
ansible.builtin.copy:
|
||||
@@ -20,5 +21,6 @@
|
||||
run_once: true
|
||||
|
||||
- name: Encrypt k3s token
|
||||
ansible.builtin.shell: cd ../; ansible-vault encrypt "{{ playbook_dir }}/{{k3s_server_token_vault_file}}"
|
||||
ansible.builtin.shell: cd ../; ansible-vault encrypt "{{ playbook_dir }}/{{ k3s_server_token_vault_file }}"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
21
roles/k3s_server/tasks/secondary_installation.yaml
Normal file
21
roles/k3s_server/tasks/secondary_installation.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Add token vault
|
||||
ansible.builtin.include_vars:
|
||||
file: "{{ playbook_dir }}/{{ k3s_server_token_vault_file }}"
|
||||
name: k3s_token_vault
|
||||
|
||||
- name: Download K3s install script to /tmp/
|
||||
ansible.builtin.get_url:
|
||||
url: https://get.k3s.io
|
||||
dest: /tmp/k3s_install.sh
|
||||
mode: "0755"
|
||||
|
||||
- name: Install K3s on the secondary servers
|
||||
ansible.builtin.command: |
|
||||
/tmp/k3s_install.sh \
|
||||
--server "https://{{ hostvars['k3s-loadbalancer'].ansible_default_ipv4.address }}:{{ k3s.loadbalancer.default_port }}" \
|
||||
--tls-san {{ hostvars['k3s-loadbalancer'].ansible_default_ipv4.address }} \
|
||||
--tls-san {{ k3s_server_name }}
|
||||
environment:
|
||||
K3S_TOKEN: "{{ k3s_token_vault.k3s_token }}"
|
||||
become: true
|
||||
@@ -1 +1 @@
|
||||
k3s_server_token_vault_file: ../vars/group_vars/k3s/secrets_token.yml
|
||||
k3s_server_token_vault_file: ../vars/group_vars/k3s/secrets_token.yaml
|
||||
39
roles/k3s_storage/README.md
Normal file
39
roles/k3s_storage/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# k3s_storage Ansible Role
|
||||
|
||||
This role installs and configures a k3s node with storage-specific taints and labels.
|
||||
|
||||
## Role Variables
|
||||
|
||||
- `k3s.loadbalancer.default_port`: The port of the k3s loadbalancer. Defaults to `6443`.
|
||||
- `k3s_token`: The token to join the k3s cluster. This is a required variable.
|
||||
- `hostvars['k3s-loadbalancer'].ansible_default_ipv4.address`: The IP address of the k3s loadbalancer. This is discovered automatically from the host with the name `k3s-loadbalancer`.
|
||||
|
||||
## Tasks
|
||||
|
||||
The main task includes the following files:
|
||||
|
||||
- `requirements.yml`:
|
||||
- Updates and upgrades system packages.
|
||||
- Installs `open-iscsi` and `nfs-common`.
|
||||
- Starts and enables the `open-iscsi` service.
|
||||
- `installation.yml`:
|
||||
- Downloads the k3s installation script.
|
||||
- Installs k3s on the node with the following configurations:
|
||||
- Taint: `storage=true:NoExecute`
|
||||
- Label: `longhorn=true`
|
||||
|
||||
## Handlers
|
||||
|
||||
- `Restart k3s`: Restarts the k3s service.
|
||||
|
||||
## Usage
|
||||
|
||||
Here is an example of how to use this role in a playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: k3s_storage_nodes
|
||||
roles:
|
||||
- role: k3s_storage
|
||||
vars:
|
||||
k3s_token: "your_k3s_token"
|
||||
```
|
||||
@@ -3,4 +3,4 @@
|
||||
service:
|
||||
name: k3s
|
||||
state: restarted
|
||||
become: yes
|
||||
become: true
|
||||
5
roles/k3s_storage/tasks/main.yaml
Normal file
5
roles/k3s_storage/tasks/main.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Install dependencies
|
||||
ansible.builtin.include_tasks: requirements.yaml
|
||||
- name: Install k3s
|
||||
ansible.builtin.include_tasks: installation.yaml
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
- name: Install dependencies
|
||||
ansible.builtin.include_tasks: requirements.yml
|
||||
- name: Install k3s
|
||||
ansible.builtin.include_tasks: installation.yml
|
||||
44
roles/kubernetes_argocd/README.md
Normal file
44
roles/kubernetes_argocd/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Ansible Role: ArgoCD
|
||||
|
||||
This role installs and configures ArgoCD in a Kubernetes cluster.
|
||||
|
||||
## Role Variables
|
||||
|
||||
Available variables are listed below, along with default values (see `defaults/main.yml`):
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `argocd_version` | `stable` | The version of ArgoCD to install. |
|
||||
| `argocd_namespace` | `argocd` | The namespace where ArgoCD will be installed. |
|
||||
| `argocd_repo` | `https://raw.githubusercontent.com/argoproj/argo-cd/refs/tags/{{ argocd_version }}/manifests/ha/install.yaml` | The URL to the ArgoCD installation manifests. |
|
||||
| `argocd_git_repository` | `https://github.com/argocd/argocd` | The Git repository URL for ArgoCD to use. |
|
||||
| `argocd_git_username` | `user` | The username for the Git repository. |
|
||||
| `argocd_git_pat` | `token` | The personal access token for the Git repository. |
|
||||
|
||||
## Tasks
|
||||
|
||||
The following tasks are performed by this role:
|
||||
|
||||
- **Install ArgoCD**: Creates the ArgoCD namespace and applies the installation manifests.
|
||||
- **Apply ArgoCD Ingress**: Applies an Ingress resource for the ArgoCD server. **Note:** The template file `ingress.yml.j2` is missing from the role.
|
||||
- **Apply ArgoCD CM**: Applies a ConfigMap with command parameters for ArgoCD.
|
||||
- **Apply ArgoCD repository**: Creates a Secret with Git repository credentials.
|
||||
- **Apply ArgoCD Root Application**: Creates a root Application resource for ArgoCD.
|
||||
|
||||
## Handlers
|
||||
|
||||
There are no handlers in this role.
|
||||
|
||||
## Usage
|
||||
|
||||
Here is an example of how to use this role in a playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: kubernetes
|
||||
roles:
|
||||
- role: kubernetes_argocd
|
||||
vars:
|
||||
argocd_git_repository: "https://github.com/my-org/my-repo.git"
|
||||
argocd_git_username: "my-user"
|
||||
argocd_git_pat: "my-token"
|
||||
```
|
||||
8
roles/kubernetes_argocd/defaults/main.yaml
Normal file
8
roles/kubernetes_argocd/defaults/main.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
argocd_version: stable
|
||||
argocd_namespace: argocd
|
||||
argocd_repo: "https://raw.githubusercontent.com/argoproj/argo-cd/refs/tags/{{ argocd_version }}/manifests/ha/install.yaml"
|
||||
|
||||
argocd_git_repository: https://github.com/argocd/argocd
|
||||
argocd_git_username: "user"
|
||||
argocd_git_pat: "token"
|
||||
10
roles/kubernetes_argocd/files/argocd-cmd-params-cm.yaml
Normal file
10
roles/kubernetes_argocd/files/argocd-cmd-params-cm.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-cmd-params-cm
|
||||
labels:
|
||||
app.kubernetes.io/name: argocd-cmd-params-cm
|
||||
app.kubernetes.io/part-of: argocd
|
||||
data:
|
||||
redis.server: "argocd-redis-ha-haproxy:6379"
|
||||
server.insecure: "true"
|
||||
72
roles/kubernetes_argocd/tasks/main.yaml
Normal file
72
roles/kubernetes_argocd/tasks/main.yaml
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
- name: Install ArgoCD
|
||||
block:
|
||||
- name: Create ArgoCD namespace
|
||||
kubernetes.core.k8s:
|
||||
name: "{{ argocd_namespace }}"
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
state: present
|
||||
|
||||
- name: Apply ArgoCD manifests
|
||||
kubernetes.core.k8s:
|
||||
src: "{{ argocd_repo }}"
|
||||
state: present
|
||||
namespace: "{{ argocd_namespace }}"
|
||||
register: apply_manifests
|
||||
until: apply_manifests is not failed
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Wait for ArgoCD server to be ready
|
||||
kubernetes.core.k8s_info:
|
||||
api_version: apps/v1
|
||||
kind: Deployment
|
||||
name: argocd-server
|
||||
namespace: "{{ argocd_namespace }}"
|
||||
register: rollout_status
|
||||
until: >
|
||||
rollout_status.resources[0].status.readyReplicas is defined and
|
||||
rollout_status.resources[0].status.readyReplicas == rollout_status.resources[0].spec.replicas
|
||||
retries: 30
|
||||
delay: 10
|
||||
|
||||
- name: Apply ArgoCD Ingress
|
||||
kubernetes.core.k8s:
|
||||
definition: "{{ lookup('ansible.builtin.template', 'ingress.yaml.j2') | from_yaml }}"
|
||||
state: present
|
||||
namespace: "{{ argocd_namespace }}"
|
||||
register: apply_manifests
|
||||
until: apply_manifests is not failed
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Apply ArgoCD CM
|
||||
kubernetes.core.k8s:
|
||||
src: "files/argocd-cmd-params-cm.yaml"
|
||||
state: present
|
||||
namespace: "{{ argocd_namespace }}"
|
||||
register: apply_manifests
|
||||
until: apply_manifests is not failed
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Apply ArgoCD repository
|
||||
kubernetes.core.k8s:
|
||||
definition: "{{ lookup('ansible.builtin.template', 'repository.yaml.j2') | from_yaml }}"
|
||||
state: present
|
||||
namespace: "{{ argocd_namespace }}"
|
||||
register: apply_manifests
|
||||
until: apply_manifests is not failed
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
- name: Apply ArgoCD Root Application
|
||||
kubernetes.core.k8s:
|
||||
definition: "{{ lookup('ansible.builtin.template', 'root_application.yaml.j2') | from_yaml }}"
|
||||
state: present
|
||||
namespace: "{{ argocd_namespace }}"
|
||||
register: apply_manifests
|
||||
until: apply_manifests is not failed
|
||||
retries: 5
|
||||
delay: 10
|
||||
11
roles/kubernetes_argocd/templates/repository.yaml.j2
Normal file
11
roles/kubernetes_argocd/templates/repository.yaml.j2
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: argocd-repository-https
|
||||
namespace: argocd
|
||||
labels:
|
||||
argocd.argoproj.io/secret-type: repository
|
||||
stringData:
|
||||
url: {{ argocd_git_repository }}
|
||||
username: {{ argocd_git_username }}
|
||||
password: {{ argocd_git_pat }}
|
||||
25
roles/kubernetes_argocd/templates/root_application.yaml.j2
Normal file
25
roles/kubernetes_argocd/templates/root_application.yaml.j2
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: homelab-gitops-root
|
||||
namespace: argocd
|
||||
labels:
|
||||
app.kubernetes.io/name: argocd-root
|
||||
app.kubernetes.io/instance: homelab
|
||||
app.kubernetes.io/component: gitops-bootstrap
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: {{ argocd_git_repository }}
|
||||
targetRevision: HEAD
|
||||
path: cluster-apps/
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: argocd
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ApplyOutOfSyncOnly=true
|
||||
6
roles/node_exporter/tasks/main.yaml
Normal file
6
roles/node_exporter/tasks/main.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
- name: Get Version
|
||||
ansible.builtin.include_tasks: get_version.yaml
|
||||
- name: Install
|
||||
ansible.builtin.include_tasks: install.yaml
|
||||
- name: Setup Service
|
||||
ansible.builtin.include_tasks: systemd.yaml
|
||||
@@ -1,6 +0,0 @@
|
||||
- name: Get Version
|
||||
ansible.builtin.include_tasks: get_version.yml
|
||||
- name: Install
|
||||
ansible.builtin.include_tasks: install.yml
|
||||
- name: Setup Service
|
||||
ansible.builtin.include_tasks: systemd.yml
|
||||
61
roles/proxmox/README.md
Normal file
61
roles/proxmox/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Proxmox Ansible Role
|
||||
|
||||
This role facilitates the management of Proxmox VE resources, including virtual machines (VMs) and LXC containers. It automates the setup of Proxmox nodes and the creation, configuration, and destruction of guests.
|
||||
|
||||
## Role Variables
|
||||
|
||||
| Variable | Description | Default Value |
|
||||
|---|---|---|
|
||||
| `proxmox_author` | The author of the Proxmox resources. | `tuan-dat.tran@tudattr.dev` |
|
||||
| `proxmox_creator` | The creator of the Proxmox resources. | `ansible` |
|
||||
| `proxmox_storage` | The Proxmox storage to use. | `proxmox` |
|
||||
| `proxmox_vault_file` | The path to the vault file for storing secrets. | `../vars/group_vars/proxmox/secrets_vm.yml` |
|
||||
| `proxmox_secrets_prefix` | The prefix for secrets stored in the vault. | `secrets_vm` |
|
||||
| `proxmox_cloud_init_images` | A dictionary of cloud-init images to download. | `{ 'debian': { 'name': 'debian-12-genericcloud-amd64.qcow2', 'url': '...' }, 'ubuntu': { 'name': 'noble-server-cloudimg-amd64.img', 'url': '...' } }` |
|
||||
| `proxmox_dirs` | A dictionary of directories used by the role. | `{ 'isos': '/opt/proxmox/template/iso/' }` |
|
||||
| `proxmox_tags` | A list of tags to apply to the Proxmox resources. | `['{{ proxmox_creator }}']` |
|
||||
| `proxmox_node_dependencies` | A list of dependencies to install on the Proxmox node. | `['nmap']` |
|
||||
| `proxmox_localhost_dependencies` | A list of dependencies to install on the localhost. | `[]` |
|
||||
| `vms` | A list of VMs to create. | `[{ 'name': 'test-vm', 'vmid': 1000, ... }]` |
|
||||
| `lxcs` | A list of LXC containers to create. | `[{ 'name': 'test-lxc', 'vmid': 2000, ... }]` |
|
||||
|
||||
## Handlers
|
||||
|
||||
- `Reboot Node`: Reboots the Proxmox node. This is triggered when the GRUB configuration or VFIO modules are changed.
|
||||
|
||||
## Tasks
|
||||
|
||||
The role includes the following main tasks:
|
||||
|
||||
- `00_setup_machines.yml`: Prepares the localhost and Proxmox nodes by installing dependencies and configuring hardware acceleration.
|
||||
- `10_create_secrets.yml`: Creates a vault file and generates secrets for the VMs.
|
||||
- `40_prepare_vm_creation.yml`: Downloads cloud-init images required for VM creation.
|
||||
- `50_create_vms.yml`: Creates VMs based on the `vms` variable.
|
||||
- `60_create_containers.yml`: Creates LXC containers based on the `lxcs` variable.
|
||||
|
||||
## Usage
|
||||
|
||||
Here is an example of how to use this role in a playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: proxmox
|
||||
roles:
|
||||
- role: proxmox
|
||||
vars:
|
||||
proxmox_api_user: "root@pam"
|
||||
proxmox_api_token_id: "your-token-id"
|
||||
proxmox_api_token_secret: "your-token-secret"
|
||||
proxmox_api_host: "your-proxmox-host"
|
||||
vms:
|
||||
- name: my-vm
|
||||
vmid: 1001
|
||||
node: proxmox
|
||||
cores: 4
|
||||
memory: 8192
|
||||
disk_size: 50
|
||||
boot_image: debian-12-genericcloud-amd64.img
|
||||
ciuser: myuser
|
||||
sshkeys: "your-ssh-key"
|
||||
net:
|
||||
net0: "virtio=BC:24:11:7E:2B:A1,bridge=vmbr0"
|
||||
```
|
||||
@@ -1,11 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration
|
||||
VM_ID=303
|
||||
TARGET_IP="192.168.20.36" # Replace with the IP of your VM
|
||||
VM_ID=$1
|
||||
TARGET_IP=$2
|
||||
PORT=22
|
||||
CHECK_INTERVAL=300 # 5 minutes in seconds
|
||||
LOG_FILE="/var/log/vm_monitor.log"
|
||||
LOG_FILE="/var/log/vm_monitor_${VM_ID}.log"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
@@ -65,19 +64,12 @@ restart_vm() {
|
||||
log_message "VM $VM_ID has been restarted."
|
||||
}
|
||||
|
||||
# Main loop
|
||||
log_message "Starting monitoring of VM $VM_ID on port $PORT..."
|
||||
log_message "Press Ctrl+C to exit."
|
||||
# Main execution
|
||||
# log_message "Starting monitoring of VM $VM_ID on port $PORT..."
|
||||
|
||||
while true; do
|
||||
# Check if port 22 is open
|
||||
if ! check_port; then
|
||||
restart_vm
|
||||
else
|
||||
log_message "Port $PORT is reachable. VM is running normally."
|
||||
fi
|
||||
|
||||
# Wait for the next check
|
||||
log_message "Sleeping for $CHECK_INTERVAL seconds..."
|
||||
sleep $CHECK_INTERVAL
|
||||
done
|
||||
# Check if port 22 is open
|
||||
if ! check_port; then
|
||||
restart_vm
|
||||
# else
|
||||
# log_message "Port $PORT is reachable. VM is running normally."
|
||||
fi
|
||||
|
||||
8
roles/proxmox/tasks/00_setup_machines.yaml
Normal file
8
roles/proxmox/tasks/00_setup_machines.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Prepare Localhost
|
||||
ansible.builtin.include_tasks: ./01_setup_localhost.yaml
|
||||
when: is_localhost
|
||||
|
||||
- name: Prepare Localhost
|
||||
ansible.builtin.include_tasks: ./05_setup_node.yaml
|
||||
when: is_proxmox_node
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
- name: Prepare Localhost
|
||||
ansible.builtin.include_tasks: ./01_setup_localhost.yml
|
||||
when: is_localhost
|
||||
|
||||
- name: Prepare Localhost
|
||||
ansible.builtin.include_tasks: ./05_setup_node.yml
|
||||
when: is_proxmox_node
|
||||
@@ -7,4 +7,4 @@
|
||||
loop: "{{ proxmox_node_dependencies }}"
|
||||
|
||||
- name: Ensure Harware Acceleration on node
|
||||
ansible.builtin.include_tasks: 06_hardware_acceleration.yml
|
||||
ansible.builtin.include_tasks: 06_hardware_acceleration.yaml
|
||||
39
roles/proxmox/tasks/06_hardware_acceleration.yaml
Normal file
39
roles/proxmox/tasks/06_hardware_acceleration.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
- name: Set GRUB_CMDLINE_LINUX_DEFAULT for PCI passthrough
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/default/grub
|
||||
regexp: "^GRUB_CMDLINE_LINUX_DEFAULT="
|
||||
line: >
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt
|
||||
pcie_acs_override=downstream,multifunction initcall_blacklist=sysfb_init
|
||||
video=simplefb:off video=vesafb:off video=efifb:off video=vesa:off
|
||||
disable_vga=1 vfio_iommu_type1.allow_unsafe_interrupts=1 kvm.ignore_msrs=1
|
||||
modprobe.blacklist=radeon,nouveau,nvidia,nvidiafb,nvidia-gpu,snd_hda_intel,snd_hda_codec_hdmi,i915"
|
||||
backup: true
|
||||
register: iommu_result
|
||||
|
||||
- name: Ensure VFIO modules are listed in /etc/modules
|
||||
ansible.builtin.blockinfile:
|
||||
path: /etc/modules
|
||||
marker: "# {mark} VFIO Modules"
|
||||
block: |
|
||||
vfio
|
||||
vfio_iommu_type1
|
||||
vfio_pci
|
||||
vfio_virqfd
|
||||
create: true
|
||||
backup: true
|
||||
mode: 644
|
||||
register: vfio_result
|
||||
|
||||
- name: Update initramfs
|
||||
ansible.builtin.command: update-initramfs -u -k all
|
||||
when: iommu_result.changed or vfio_result.changed
|
||||
# notify:
|
||||
# - Reboot Node
|
||||
|
||||
- name: Update grub configuration
|
||||
ansible.builtin.command: update-grub
|
||||
when: iommu_result.changed or vfio_result.changed
|
||||
# notify:
|
||||
# - Reboot Node
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
- name: Set GRUB_CMDLINE_LINUX_DEFAULT for PCI passthrough
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/default/grub
|
||||
regexp: "^GRUB_CMDLINE_LINUX_DEFAULT="
|
||||
line: 'GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction initcall_blacklist=sysfb_init video=simplefb:off video=vesafb:off video=efifb:off video=vesa:off disable_vga=1 vfio_iommu_type1.allow_unsafe_interrupts=1 kvm.ignore_msrs=1 modprobe.blacklist=radeon,nouveau,nvidia,nvidiafb,nvidia-gpu,snd_hda_intel,snd_hda_codec_hdmi,i915"'
|
||||
backup: true
|
||||
register: iommu_result
|
||||
|
||||
- name: Set GRUB_CMDLINE_LINUX_DEFAULT for PCI passthrough
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/default/grub
|
||||
regexp: "^GRUB_CMDLINE_LINUX_DEFAULT="
|
||||
line: 'GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction initcall_blacklist=sysfb_init video=simplefb:off video=vesafb:off video=efifb:off video=vesa:off disable_vga=1 vfio_iommu_type1.allow_unsafe_interrupts=1 kvm.ignore_msrs=1 modprobe.blacklist=radeon,nouveau,nvidia,nvidiafb,nvidia-gpu,snd_hda_intel,snd_hda_codec_hdmi,i915"'
|
||||
backup: true
|
||||
register: iommu_result
|
||||
|
||||
- name: Ensure VFIO modules are listed in /etc/modules
|
||||
ansible.builtin.blockinfile:
|
||||
path: /etc/modules
|
||||
marker: "# {mark} VFIO Modules"
|
||||
block: |
|
||||
vfio
|
||||
vfio_iommu_type1
|
||||
vfio_pci
|
||||
vfio_virqfd
|
||||
create: true
|
||||
backup: true
|
||||
register: vfio_result
|
||||
|
||||
- name: Update initramfs
|
||||
ansible.builtin.command: update-initramfs -u -k all
|
||||
when: iommu_result.changed or vfio_result.changed
|
||||
# notify:
|
||||
# - Reboot Node
|
||||
|
||||
- name: update grub configuration
|
||||
ansible.builtin.command: update-grub
|
||||
when: iommu_result.changed or vfio_result.changed
|
||||
# notify:
|
||||
# - Reboot Node
|
||||
@@ -6,7 +6,7 @@
|
||||
mode: "0600"
|
||||
|
||||
- name: Update Vault data
|
||||
ansible.builtin.include_tasks: 15_create_secret.yml
|
||||
ansible.builtin.include_tasks: 15_create_secret.yaml
|
||||
loop: "{{ vms | map(attribute='name') }}"
|
||||
loop_control:
|
||||
loop_var: "vm_name"
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
- name: Decrypt vm vault file
|
||||
ansible.builtin.shell: cd ../; ansible-vault decrypt "./playbooks/{{ proxmox_vault_file }}"
|
||||
ignore_errors: true
|
||||
no_log: true
|
||||
|
||||
- name: Load existing vault content
|
||||
@@ -17,7 +16,7 @@
|
||||
|
||||
- name: Setup secret name
|
||||
ansible.builtin.set_fact:
|
||||
vm_name_secret: "{{ proxmox_secrets_prefix }}_{{ vm_name | replace('-','_') }}"
|
||||
vm_name_secret: "{{ proxmox_secrets_prefix }}_{{ vm_name | replace('-', '_') }}"
|
||||
|
||||
- name: Check if variable is in vault
|
||||
ansible.builtin.set_fact:
|
||||
@@ -30,7 +29,7 @@
|
||||
|
||||
- name: Set new secret
|
||||
ansible.builtin.set_fact:
|
||||
new_vault_data: "{{ vault_data | combine({ vm_name_secret: cipassword }) }}"
|
||||
new_vault_data: "{{ vault_data | combine({vm_name_secret: cipassword}) }}"
|
||||
when: not variable_exists
|
||||
|
||||
- name: Write updated Vault content to file (temporary plaintext)
|
||||
@@ -43,5 +42,4 @@
|
||||
|
||||
- name: Encrypt vm vault file
|
||||
ansible.builtin.shell: cd ../; ansible-vault encrypt "./playbooks/{{ proxmox_vault_file }}"
|
||||
ignore_errors: true
|
||||
no_log: true
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: Download Cloud Init Isos
|
||||
ansible.builtin.include_tasks: 42_download_isos.yml
|
||||
ansible.builtin.include_tasks: 42_download_isos.yaml
|
||||
loop: "{{ proxmox_cloud_init_images | dict2items | map(attribute='value') }}"
|
||||
loop_control:
|
||||
loop_var: distro
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user