Fist commit

Signed-off-by: Nikolai Rodionov <allanger@badhouseplants.net>
This commit is contained in:
2025-10-26 21:54:20 +01:00
commit ddfed61d8e
12 changed files with 1349 additions and 0 deletions

20
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,20 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0 # Use the ref you want to point at
hooks:
- id: trailing-whitespace
- repo: https://github.com/google/yamlfmt
rev: v0.13.0
hooks:
- id: yamlfmt
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
hooks:
- id: codespell
- repo: local
hooks:
- id: ansible-lint
name: Run the ansible linter
entry: make lint
language: system
pass_filenames: false

5
.sops.yaml Normal file
View File

@@ -0,0 +1,5 @@
creation_rules:
- path_regex: .*
key_groups:
- age:
- age1lzythn62c4yug8w2wskckpgyjyja6rreyvgmwl9hj4mjvm0tvq6sl68d4z

17
LICENSE Normal file
View File

@@ -0,0 +1,17 @@
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the
above copyright notice and the following two paragraphs appear in
all copies of this software.
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

12
Makefile Normal file
View File

@@ -0,0 +1,12 @@
install:
poetry install --no-root
poetry run ansible-galaxy install -r ./requirements.yml --force
lint:
poetry run ansible-lint playbook.yml
check:
poetry run ansible-playbook playbook.yml --check
run:
./scripts/run.sh

32
README.md Normal file
View File

@@ -0,0 +1,32 @@
# Hetzner Ansilbe Playbook
Repo for managing the Hetzner infrastructure
## Dev
This project is using poetry for managing ansible and dependencies.
```shell
$ make install
$ make lint
$ make install
```
## Removing stuff
Since the state of the config is the ansible code itself, you can't just remove something from the code and expect that it's going to be removed from Hetzner.
Each entity has a variable `state`, to remove anything, you need to set state to `absent` and run the playbook. And only after that you can remove it from the code.
Also, please, create a git commit, where on object with the `absent` state is tracked.
## Outputs
After running the role you'll see three variables being logged in the last step:
- Server public IP -> It should be used for `ssh` connection to the server
- Load balancer public IP -> It should be used by k8s as the load balancer IP
- Volume device name -> It's the name of device that should be mounted to Longhorn
## Notes
### Resize the volume
Don't forget to resize the filesystem, it should be done manually
- https://docs.hetzner.com/cloud/volumes/faq/

32
oslo.yaml Normal file
View File

@@ -0,0 +1,32 @@
k3s_cluster:
children:
server:
hosts:
37.27.11.18:
ansible_user: overlord
vars:
ansible_port: 22
k3s_version: v1.34.1+k3s1
api_endpoint: "37.27.11.18"
token: "${TOKEN}"
extra_server_args: |-
--write-kubeconfig-mode=644 \
--tls-san="37.27.202.157" \
--kubelet-arg "allowed-unsafe-sysctls=net.ipv4.ip_forward" \
--disable-cloud-controller \
--disable-helm-controller \
--disable metrics-server \
--disable local-storage \
--disable traefik \
--flannel-iface eth1 \
--flannel-backend none \
--disable coredns \
--disable servicelb \
--cluster-cidr=192.168.0.0/16 \
--disable-network-policy \
--cluster-init
extra_agent_args: |-
--kubelet-arg "allowed-unsafe-sysctls=net.ipv4.ip_forward" \
--flannel-iface eth1
extra_service_envs:
- 'NO_PROXY=10.0.0.0/16,192.168.0.0/16'

1181
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

19
pyproject.toml Normal file
View File

@@ -0,0 +1,19 @@
[project]
name = "k3s-ansible-playbooks"
version = "0.1.0"
description = "Bootstrap k3s cluster"
authors = [
{name = "Nikolai Rodionov",email = "allanger@badhouseplants.net"}
]
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"hcloud (>=2.5.4,<3.0.0)",
"ansible (>=12.0.0,<12.1.0)",
"ansible-lint (>=25.8.2,<26.0.0)",
]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

3
renovate.json Normal file
View File

@@ -0,0 +1,3 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

4
requirements.yml Normal file
View File

@@ -0,0 +1,4 @@
collections:
- name: https://github.com/k3s-io/k3s-ansible.git
type: git
version: main

8
scripts/run.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
export TOKEN=$(sops -d "tokens/${INVENTORY}.yaml" | yq .TOKEN)
INVENTORY_FILE=$(mktemp --dry-run).yaml
envsubst < "${INVENTORY}.yaml" > "${INVENTORY_FILE}"
unset TOKEN
ansible-playbook k3s.orchestration.site -i "${INVENTORY_FILE}"
rm $INVENTORY_FILE

16
tokens/oslo.yaml Normal file
View File

@@ -0,0 +1,16 @@
TOKEN: ENC[AES256_GCM,data:j5fTSYZyWv2MRjfs5TMpppzwVwKLIvLHMcmkcwuox0dzjRTic30cW761ZLGF9s94Y7JJqD5w9g3AT7fTKOREww==,iv:Gg+csfvz2fdfRsR3XaqtD3RcqcNJbqIeKS/z4WlubYA=,tag:RqC6U7u0Ap22iWduo4kwbA==,type:str]
sops:
age:
- recipient: age1lzythn62c4yug8w2wskckpgyjyja6rreyvgmwl9hj4mjvm0tvq6sl68d4z
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAySGl4YWFjNURaVjRRUDRM
VkQ4eVVoWFpGZkNMdkprelIwOU5NTnVZUWlBCnhRWWtsM2NNbFNNMFJXUjl3REVY
bXJLd1FtdkQyLzlpa2RXMURuU2htYUUKLS0tIDlJbzZtTDhrWlJmL0dlYTE5MERi
Q085VitrTy8rTCs4NWtMc1JOOUFyRDAKs/Rt6U5EaEA8iZ5fXJ9baVLojRv9rNwu
LpWE+t7LdzV5L0fmXn4MW101K/7OV/Qxh2qm+naVtjEcqPTeQ1QOHQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-10-26T20:34:00Z"
mac: ENC[AES256_GCM,data:f8/nrKTHlQll5TdcZ85C5o4EipAYYEga7yhhaw4t3kX1d0KB+QOwkdjv3rYppbQipOjB9S4fQbJ+bezmU6DN4dF7FRk4slHRZex+d0gdTSP0PqglvcYjNHge7xYvh8CCpwPRhtUnDBSL/QwLxNfQ44X6WoCGx7WQ4QifDtyFtt8=,iv:lahPMNjz5551RnMPiRB2cAZoWeGEMZEH8qGc725rDJ8=,tag:JNUYcJGIu9Q8NHjsK2tc3w==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0