From c0103496a1857629742c0a6f967e897c2d04e06d Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sun, 5 Jan 2025 00:23:23 -0800 Subject: [PATCH] refactor: upgrade ansible, remove clean_desired flag, add separate clean playbook --- Makefile | 12 ++++-- clean.yml | 3 ++ group_vars/alpina/vars.yml | 6 +++ inventories/prod/group_vars/all.yml | 1 - inventories/prod/group_vars/alpina/vars.yml | 2 + inventories/staging/group_vars/all.yml | 1 - .../staging/group_vars/alpina/vars.yml | 2 + poetry.lock | 36 +++++++++--------- pyproject.toml | 4 +- .../{docker-compose.yml.j2 => compose.yml.j2} | 2 + .../{docker-compose.yml.j2 => compose.yml.j2} | 0 .../{docker-compose.yml.j2 => compose.yml.j2} | 0 .../{docker-compose.yml.j2 => compose.yml.j2} | 0 .../{docker-compose.yml.j2 => compose.yml.j2} | 0 .../{docker-compose.yml.j2 => compose.yml.j2} | 3 +- .../{docker-compose.yml.j2 => compose.yml.j2} | 0 .../{docker-compose.yml.j2 => compose.yml.j2} | 3 +- .../{docker-compose.yml.j2 => compose.yml.j2} | 0 roles/clean/tasks/main.yml | 22 +++++++++++ roles/docker_host/tasks/main.yml | 38 +------------------ services.yml | 1 - site.yml | 12 +----- 22 files changed, 73 insertions(+), 75 deletions(-) create mode 100644 clean.yml delete mode 100644 inventories/prod/group_vars/all.yml delete mode 100644 inventories/staging/group_vars/all.yml rename roles/alpina/templates/apps/arrstack/{docker-compose.yml.j2 => compose.yml.j2} (97%) rename roles/alpina/templates/apps/gitea/{docker-compose.yml.j2 => compose.yml.j2} (100%) rename roles/alpina/templates/apps/jellyfin/{docker-compose.yml.j2 => compose.yml.j2} (100%) rename roles/alpina/templates/apps/nextcloud/{docker-compose.yml.j2 => compose.yml.j2} (100%) rename roles/alpina/templates/apps/vpgen/{docker-compose.yml.j2 => compose.yml.j2} (100%) rename roles/alpina/templates/services/authentik/{docker-compose.yml.j2 => compose.yml.j2} (97%) rename roles/alpina/templates/services/minio/{docker-compose.yml.j2 => compose.yml.j2} (100%) rename roles/alpina/templates/services/monitoring/{docker-compose.yml.j2 => compose.yml.j2} (98%) rename roles/alpina/templates/services/traefik/{docker-compose.yml.j2 => compose.yml.j2} (100%) create mode 100644 roles/clean/tasks/main.yml diff --git a/Makefile b/Makefile index a49f126..f12131e 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,23 @@ .POSIX: .PHONY: * .EXPORT_ALL_VARIABLES: +MAKEFLAGS += -r # no use of built-in rules env ?= staging vault_id ?= alpina@contrib/rbw-client.sh -clean_desired ?= false +playbook_cmd := poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} -all: site +all: site services setup: poetry install --quiet site: setup - poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} --extra-vars "clean_desired_arg=${clean_desired}" site.yml + $(playbook_cmd) site.yml services: setup - poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} services.yml + $(playbook_cmd) services.yml + +clean: setup + $(playbook_cmd) clean.yml diff --git a/clean.yml b/clean.yml new file mode 100644 index 0000000..fac3c6e --- /dev/null +++ b/clean.yml @@ -0,0 +1,3 @@ +- hosts: alpina + roles: + - clean diff --git a/group_vars/alpina/vars.yml b/group_vars/alpina/vars.yml index 3994179..04e9153 100644 --- a/group_vars/alpina/vars.yml +++ b/group_vars/alpina/vars.yml @@ -5,6 +5,12 @@ alpina_svc_path: ~/alpina base_volume_path: /mnt/dock media_volume_path: /mnt/media +docker_ipv6_subnet: "{{ \ + ansible_default_ipv6.address \ + | ansible.utils.ipsubnet(64) \ + | ansible.utils.ipsubnet(72, docker_ipv6_index) \ + }}" + # Authentik authentik_db_password: "{{ vault_authentik_db_password }}" authentik_secret_key: "{{ vault_authentik_secret_key }}" diff --git a/inventories/prod/group_vars/all.yml b/inventories/prod/group_vars/all.yml deleted file mode 100644 index ceeb024..0000000 --- a/inventories/prod/group_vars/all.yml +++ /dev/null @@ -1 +0,0 @@ -domain: cazzzer.com diff --git a/inventories/prod/group_vars/alpina/vars.yml b/inventories/prod/group_vars/alpina/vars.yml index ad63395..de66566 100644 --- a/inventories/prod/group_vars/alpina/vars.yml +++ b/inventories/prod/group_vars/alpina/vars.yml @@ -1,6 +1,8 @@ # Environment specific variables (prod) --- +domain: cazzzer.com + docker_ipv6_index: 255 # Arrstack VPN diff --git a/inventories/staging/group_vars/all.yml b/inventories/staging/group_vars/all.yml deleted file mode 100644 index b64c48e..0000000 --- a/inventories/staging/group_vars/all.yml +++ /dev/null @@ -1 +0,0 @@ -domain: lab.cazzzer.com diff --git a/inventories/staging/group_vars/alpina/vars.yml b/inventories/staging/group_vars/alpina/vars.yml index 271d0c8..7a7548c 100644 --- a/inventories/staging/group_vars/alpina/vars.yml +++ b/inventories/staging/group_vars/alpina/vars.yml @@ -1,6 +1,8 @@ # Environment specific variables (staging) --- +domain: lab.cazzzer.com + docker_ipv6_index: 254 # Arrstack VPN diff --git a/poetry.lock b/poetry.lock index 46b9a24..509c9ba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,28 +1,28 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "ansible" -version = "10.7.0" +version = "11.1.0" description = "Radically simple IT automation" optional = false -python-versions = ">=3.10" +python-versions = ">=3.11" files = [ - {file = "ansible-10.7.0-py3-none-any.whl", hash = "sha256:0089f08e047ceb70edd011be009f5c6273add613fbe491e9697c0556c989d8ea"}, - {file = "ansible-10.7.0.tar.gz", hash = "sha256:59d29e3de1080e740dfa974517d455217601b16d16880314d9be26145c68dc22"}, + {file = "ansible-11.1.0-py3-none-any.whl", hash = "sha256:bbaf7073993f019fc0293fc8b76c7b215081831957c28eb020f12c270a16e8f0"}, + {file = "ansible-11.1.0.tar.gz", hash = "sha256:d01b425990d960d2a33fc378e1b73dbca1c0e28bc22f4056ab6b3c8e9ae74fba"}, ] [package.dependencies] -ansible-core = ">=2.17.7,<2.18.0" +ansible-core = ">=2.18.1,<2.19.0" [[package]] name = "ansible-core" -version = "2.17.7" +version = "2.18.1" description = "Radically simple IT automation" optional = false -python-versions = ">=3.10" +python-versions = ">=3.11" files = [ - {file = "ansible_core-2.17.7-py3-none-any.whl", hash = "sha256:64d4f0a006687a5621aa80dca54fd0c5ae75145b7aac8c1b8d7f07a1399c4705"}, - {file = "ansible_core-2.17.7.tar.gz", hash = "sha256:3aaab735d6c4e2d6239bc326800dc0ecda2a1490caa8455b41084ec0bc54dacf"}, + {file = "ansible_core-2.18.1-py3-none-any.whl", hash = "sha256:4a312e416e09c7271188d6b8e2b1062fc6834fefd6a1814d0e02fb8aadb3e1ba"}, + {file = "ansible_core-2.18.1.tar.gz", hash = "sha256:14cac1f92bbdae881cb0616eddeb17925e8cb507e486087975e724533d9de74f"}, ] [package.dependencies] @@ -418,25 +418,25 @@ test = ["commentjson", "packaging", "pytest"] [[package]] name = "setuptools" -version = "75.6.0" +version = "75.7.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, - {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, + {file = "setuptools-75.7.0-py3-none-any.whl", hash = "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183"}, + {file = "setuptools-75.7.0.tar.gz", hash = "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] [metadata] lock-version = "2.0" -python-versions = "^3.10" -content-hash = "334448cb0c7d192f0e10987a995ecefca5e136733cce4dd15dcc2238f1c371c8" +python-versions = "^3.11" +content-hash = "7c5b28e1b7fc5cf1c55fedf89a01f26e9246b9d1baa1441d51a8693697b6767a" diff --git a/pyproject.toml b/pyproject.toml index fa561b9..ad10acd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,8 @@ authors = ["Iurii Tatishchev "] readme = "README.md" [tool.poetry.dependencies] -python = "^3.10" -ansible = "^10.1.0" +python = "^3.11" +ansible = "^11.1.0" ansible-vault = "^2.1.0" netaddr = "^1.3.0" diff --git a/roles/alpina/templates/apps/arrstack/docker-compose.yml.j2 b/roles/alpina/templates/apps/arrstack/compose.yml.j2 similarity index 97% rename from roles/alpina/templates/apps/arrstack/docker-compose.yml.j2 rename to roles/alpina/templates/apps/arrstack/compose.yml.j2 index 2384982..e0e78d0 100644 --- a/roles/alpina/templates/apps/arrstack/docker-compose.yml.j2 +++ b/roles/alpina/templates/apps/arrstack/compose.yml.j2 @@ -9,6 +9,8 @@ services: container_name: gluetun cap_add: - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun sysctls: - net.ipv6.conf.all.disable_ipv6=0 env_file: diff --git a/roles/alpina/templates/apps/gitea/docker-compose.yml.j2 b/roles/alpina/templates/apps/gitea/compose.yml.j2 similarity index 100% rename from roles/alpina/templates/apps/gitea/docker-compose.yml.j2 rename to roles/alpina/templates/apps/gitea/compose.yml.j2 diff --git a/roles/alpina/templates/apps/jellyfin/docker-compose.yml.j2 b/roles/alpina/templates/apps/jellyfin/compose.yml.j2 similarity index 100% rename from roles/alpina/templates/apps/jellyfin/docker-compose.yml.j2 rename to roles/alpina/templates/apps/jellyfin/compose.yml.j2 diff --git a/roles/alpina/templates/apps/nextcloud/docker-compose.yml.j2 b/roles/alpina/templates/apps/nextcloud/compose.yml.j2 similarity index 100% rename from roles/alpina/templates/apps/nextcloud/docker-compose.yml.j2 rename to roles/alpina/templates/apps/nextcloud/compose.yml.j2 diff --git a/roles/alpina/templates/apps/vpgen/docker-compose.yml.j2 b/roles/alpina/templates/apps/vpgen/compose.yml.j2 similarity index 100% rename from roles/alpina/templates/apps/vpgen/docker-compose.yml.j2 rename to roles/alpina/templates/apps/vpgen/compose.yml.j2 diff --git a/roles/alpina/templates/services/authentik/docker-compose.yml.j2 b/roles/alpina/templates/services/authentik/compose.yml.j2 similarity index 97% rename from roles/alpina/templates/services/authentik/docker-compose.yml.j2 rename to roles/alpina/templates/services/authentik/compose.yml.j2 index a642fd7..21e2c4e 100644 --- a/roles/alpina/templates/services/authentik/docker-compose.yml.j2 +++ b/roles/alpina/templates/services/authentik/compose.yml.j2 @@ -15,7 +15,8 @@ services: restart: unless-stopped # Port forward is needed because traefik can't resolve the container name from the host network ports: - - "9000:9000" + - "127.0.0.1:9000:9000" + - "[::1]:9000:9000" command: server env_file: - .env.authentik diff --git a/roles/alpina/templates/services/minio/docker-compose.yml.j2 b/roles/alpina/templates/services/minio/compose.yml.j2 similarity index 100% rename from roles/alpina/templates/services/minio/docker-compose.yml.j2 rename to roles/alpina/templates/services/minio/compose.yml.j2 diff --git a/roles/alpina/templates/services/monitoring/docker-compose.yml.j2 b/roles/alpina/templates/services/monitoring/compose.yml.j2 similarity index 98% rename from roles/alpina/templates/services/monitoring/docker-compose.yml.j2 rename to roles/alpina/templates/services/monitoring/compose.yml.j2 index 5fe3def..8d4b180 100644 --- a/roles/alpina/templates/services/monitoring/docker-compose.yml.j2 +++ b/roles/alpina/templates/services/monitoring/compose.yml.j2 @@ -31,7 +31,8 @@ services: - -config.file=/etc/loki/loki-config.yaml # Port forward is needed because not possible to resolve the container name from the host network ports: - - 3100:3100 + - "127.0.0.1:3100:3100" + - "[::1]:3100:3100" volumes: - {{ base_volume_path }}/monitoring/loki:/loki - ./loki_config:/etc/loki:ro diff --git a/roles/alpina/templates/services/traefik/docker-compose.yml.j2 b/roles/alpina/templates/services/traefik/compose.yml.j2 similarity index 100% rename from roles/alpina/templates/services/traefik/docker-compose.yml.j2 rename to roles/alpina/templates/services/traefik/compose.yml.j2 diff --git a/roles/clean/tasks/main.yml b/roles/clean/tasks/main.yml new file mode 100644 index 0000000..21b59ba --- /dev/null +++ b/roles/clean/tasks/main.yml @@ -0,0 +1,22 @@ +- name: Get list of running Docker containers + docker_host_info: + containers: yes + register: docker_container_list + +- name: Stop all running Docker containers + docker_container: + name: "{{ item }}" + state: stopped + loop: "{{ docker_container_list.containers | map(attribute='Id') | list }}" + async: 300 + poll: 0 + +- name: Prune all Docker containers and networks + docker_prune: + containers: yes + networks: yes + +- name: Clean alpina directory + file: + path: "{{ alpina_svc_path }}" + state: absent diff --git a/roles/docker_host/tasks/main.yml b/roles/docker_host/tasks/main.yml index f0cfcf8..8bc3042 100644 --- a/roles/docker_host/tasks/main.yml +++ b/roles/docker_host/tasks/main.yml @@ -1,12 +1,5 @@ -- name: Get IPv6 subnet for Docker - set_fact: - docker_ipv6_subnet: "{{ \ - ansible_default_ipv6.address \ - | ansible.utils.ipsubnet(64) \ - | ansible.utils.ipsubnet(72, docker_ipv6_index) \ - }}" - -- debug: +- name: IPv6 subnet for Docker + debug: var: docker_ipv6_subnet - name: Configure Docker daemon @@ -35,33 +28,6 @@ state: disabled register: docker0_firewalld -- name: Get list of running Docker containers - docker_host_info: - containers: yes - register: docker_container_list - when: clean_desired is true - -- name: Stop all running Docker containers - docker_container: - name: "{{ item }}" - state: stopped - loop: "{{ docker_container_list.containers | map(attribute='Id') | list }}" - async: 300 - poll: 0 - when: clean_desired is true and docker_container_list.containers | length > 0 - -- name: Prune all Docker containers and networks - docker_prune: - containers: yes - networks: yes - when: clean_desired is true - -- name: Clean alpina directory - file: - path: "{{ alpina_svc_path }}" - state: absent - when: clean_desired is true - - name: Restart Docker daemon become: yes service: diff --git a/services.yml b/services.yml index 4e9ff71..b4ff534 100644 --- a/services.yml +++ b/services.yml @@ -1,6 +1,5 @@ - hosts: alpina roles: - - docker_host - alpina post_tasks: - name: Docker prune objects diff --git a/site.yml b/site.yml index 99098dd..3c69875 100644 --- a/site.yml +++ b/site.yml @@ -1,12 +1,4 @@ -- hosts: all +- hosts: alpina roles: - common - pre_tasks: - - name: Set fact for clean desired of docker objects and compose files - set_fact: - # clean_desired_arg is an extra variable passed to the playbook - clean_desired: "{{ clean_desired_arg | bool }}" - - -- name: Install services - import_playbook: services.yml + - docker_host