• alex3305
  • Registratie: Januari 2004
  • Laatst online: 17:51
Ik citeer je even andersom om eerst mijn opzet hierin wat meer toe te lichten :).
blackd schreef op vrijdag 13 maart 2026 @ 22:05:
Ik heb één main playbook die weer andere playbooks include, de enige manier om daar selectief mee om te gaan die ik had gevonden is met tags. Maar dat vereist discipline.
Ik gebruik ook tags, maar ik heb aparte playbooks en meta-playbooks.

Neem ik bijvoorbeeld AdGuard home, dan heb ik dus het playbook playbooks/apps/adguard_home.yml.
YAML:
1
2
3
4
5
6
- name: Deploy AdGuard Home
  hosts: dns

  roles:
    - role: adguard_home
      tags: [app, dns, infra, adguard, adguard_home]
De 'dns' hosts zijn dus mijn primaire en secundaire nodes zoals ik in mijn eerdere post aangaf. Deze playbook gebruik ik ook bij het 'meta-playbook' playbooks/apps/infra.yml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
- name: Deploy AdGuard Home
  ansible.builtin.import_playbook: adguard_home.yml

- name: Deploy ddclient
  ansible.builtin.import_playbook: ddclient.yml

- name: Deploy Beszel
  ansible.builtin.import_playbook: beszel.yml

- name: Deploy Gatus
  ansible.builtin.import_playbook: gatus.yml
En dit 'meta-playbook' neem ik toevallig ook weer mee in een ander 'meta-playbook' playbooks/apps/all.yml:
YAML:
1
2
3
4
5
6
7
- name: Deploy Infra
  ansible.builtin.import_playbook: infra.yml

- name: Deploy Traefik
  ansible.builtin.import_playbook: traefik.yml

# de rest van het playbook is hier niet relevant...
Om tot slot dit 'meta-playbook' nog eenmaal mee te nemen in een ander playbook: playbooks/all.yml om de meta-ception te maximaliseren :+
YAML:
1
2
3
4
5
6
7
8
- name: Setup Hosts
  ansible.builtin.import_playbook: hosts/all.yml

- name: Setup Docker
  ansible.builtin.import_playbook: docker.yml

- name: Install apps
  ansible.builtin.import_playbook: apps/all.yml
Daarmee heeft elk playbook een eigen functie:
  • playbooks/apps/adguard_home.yml gebruik ik wanneer ik alleen AdGuard Home deploy
  • playbooks/apps/infra.yml gebruik ik bij het deployen van de basis infra
  • playbooks/apps/all.yml gebruik ik bij het deployen van alle apps (eventueel met een host list) bijvoorbeeld wanneer ik een 'bulk' aan aanpassingen heb gedaan zoals CPU of mem toewijzingen
  • playbooks/all.yml gebruik ik bij een verse install
AdGuard Home is daarin een beetje flauw, maar mijn Home Assistant playbook include op deze manier ook vele andere playbooks (en rollen) voordat Home Assistant daadwerkelijk deployed wordt. Een selectie uit dat playbook:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
- name: Deploy Mosquitto
  ansible.builtin.import_playbook: mosquitto.yml

- name: Deploy Zigbee2MQTT
  ansible.builtin.import_playbook: zigbee2mqtt.yml

- name: Deploy Home Assistant
  hosts: home_assistant

  roles:
    - role: home_assistant
      tags: [app, infra, home-assistant, home_assistant]
Het zou dan ook zomaar kunnen zijn dat de Zigbee2MQTT playbook in dit geval ook Moquitto deployed. Zou kunnen, want dat heb ik momenteel nog niet O-). Dit werkt niet helemaal zoals ik zou verwachten met import_playbook omdat dan toch de role twee keer wordt uitgevoerd. Mja, 'verwacht' dus, want uiteraard is een playbook altijd afzonderlijk.

Doordat Ansible idempotent is zou ik uiteraard ook altijd all.yml of apps/all.yml kunnen gebruiken. Dit doe ik voornamelijk vanwege het af kunnen kaderen (kom ik zo op) en performance bij het ontwikkelen. Ik wil niet altijd alles of grote gedeeltes deployen. Ik besef me ook dat dit een kwestie van smaak is.
Hoe doe je dit?
Met bovenstaande dus in het achterhoofd heb ik mijn Forgejo workflow een path-mapping toegewezen. Om dus met AdGuard Home verder te gaan, .forgejo/workflows/adguard_home.yaml:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
name: Deploy AdGuard Home

# yamllint disable-line rule:truthy
on:
  push:
    branches:
      - main
    paths:
      - roles/adguard_home/**
  pull_request:
    types:
      - opened
      - reopened
      - synchronize
    paths:
      - roles/adguard_home/**
  workflow_dispatch:
    inputs:
      check_mode:
        description: "Check mode (dry-run)"
        default: false
        required: false
        type: boolean

concurrency:
  group: ${{ github.repository }}

jobs:
  deploy:
    name: Deploy AdGuard Home
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: ⤵️ Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - name: 🏗️ Setup Python
        id: setup-python
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
        with:
          cache: 'pip'
          cache-dependency-path: 'requirements.txt'

      - name: 👷 Install Python dependencies
        if: steps.setup-python.outputs.cache-hit != 'true'
        shell: bash
        run: pip install -r requirements.txt

      - name: 📦 Setup Ansible Galaxy Cache
        id: ansible-galaxy-cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
        with:
          path: |
            .ansible
            ~/.ansible
          key: ${{ runner.os }}-ansible-${{ hashFiles('**/requirements.yml') }}
          restore-keys: |
            ${{ runner.os }}-ansible-

      - name: 🌌 Install Ansible Galaxy dependencies
        if: steps.ansible-galaxy-cache.outputs.cache-hit != 'true'
        shell: bash
        run: ansible-galaxy install -r requirements.yml

      - name: 🚧 Setup known hosts
        id: setup-known-hosts
        shell: bash
        run: |
          if [ -z "${KNOWN_HOSTS}" ]; then
            echo "No known hosts provided, skipping setup."
            exit 0
          fi

          KNOWN_HOSTS_FILE="/etc/ssh/known_hosts"

          mkdir -p /etc/ssh/
          echo ${KNOWN_HOSTS} > ${KNOWN_HOSTS_FILE}
          echo "known-hosts-file=$KNOWN_HOSTS_FILE" >> $GITHUB_OUTPUT
          echo "SSH known hosts setup at: $KNOWN_HOSTS_FILE"
        env:
          KNOWN_HOSTS: ${{ vars.KNOWN_HOSTS }}

      - name: 🔑 Setup Vault password
        id: setup-vault-pass
        shell: bash
        run: |
          if [ -z "${VAULT_PASS}" ]; then
            echo "No vault password provided, skipping setup."
            exit 0
          fi

          echo "::add-mask::${VAULT_PASS}"

          if [ -z "$VAULT_PASS_DIRECTORY" ]; then
            VAULT_PASS_FILE="${{ github.workspace }}/.vault_pass"
          else
            mkdir -p "$VAULT_PASS_DIRECTORY"
            VAULT_PASS_FILE="$VAULT_PASS_DIRECTORY/.vault_pass"
          fi

          echo "$VAULT_PASS" > $VAULT_PASS_FILE
          echo "vault-pass-file=$VAULT_PASS_FILE" >> $GITHUB_OUTPUT
          echo "Vault password file setup at: $VAULT_PASS_FILE"
        env:
          VAULT_PASS: ${{ inputs.vault-pass }}
          VAULT_PASS_DIRECTORY: ${{ inputs.vault-pass-directory }}

      - name: 🚀 Run Ansible Playbook
        uses: dawidd6/action-ansible-playbook@v9
        with:
          playbook: playbooks/apps/adguard_home.yml
          requirements: requirements.yml
          key: ${{ secrets.DEPLOY_KEY }}
          vault_password: ${{ secrets.ANSIBLE_VAULT_KEY }}
          check_mode: >-
            ${{ inputs.check_mode == true ||
                github.event_name == 'pull_request' }}
Bij een PR wordt er dus altijd een check_mode uitgevoerd. Je zou uiteraard ook nog een Molecule test kunnen doen. Wanneer het PR uiteindelijk geaccepteerd wordt door Renovate wordt de deploy gedaan.

Ik gebruik voor het deployen een eigen fork van deze GitHub action. Die kerel had namelijk check_mode vernaggeld. Dit is alweer een tijdje geleden, dus de action zou wellicht weer kunnen werken.

De hele Ansible setup heb ik in een workflow zitten zodat ik geen oneindige herhaling van code heb. Tegenwoordig is het ook mogelijk om hiervoor workflow_call te gebruiken.

Tot slot heb ik in Renovate een tijdslot gezet voor auto-merges van Docker applicaties.
JSON:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "packageRules": [
      "description": "Update Docker dependencies",
      "matchFileNames": [
        "roles/common/**",
        "roles/docker/**",
        "roles/dockge/**",
        "**/compose.yml",
        "**/compose.yaml",
        "**/compose.yml.j2",
        "**/compose.yaml.j2"
      ],
      "automergeSchedule": ["* 10-19 * * 1-6"]
    }
}
Vandaar dat ik dit de roles dus eigenlijk in een aparte repo zou willen. Dan is het een en ander van nature namelijk afgekaderd in plaats van dat ik dit nog moet configureren. De merges zouden dan ook continue kunnen plaatsvinden met een afgekaderde / tijdstlot merge naar mijn infra-repo

Nu heb ik namelijk regelmatig 3 - 5 Renovate PR's openstaan, terwijl ik voor digests zelfs al alleen branches gebruik 8)7 :X. Dat houdt elkaar ook nog eens op, want elke keer moeten PR's gesynct worden én wordt er dus opnieuw een Ansible-playbook met check mode uitgevoerd om te testen of het geheel nog werkt.

  • blackd
  • Registratie: Februari 2001
  • Niet online
@alex3305 interessante aanpak, zo had ik er nog niet over nagedacht. Feitelijk maak je voor alle laagste niveau apps een playbook en installeer je daar ook je dependencies.

Ik neem aan dat je deze opzet ook kent?
Als je de dependencies op role niveau definieert, zouden ze maar 1x uitgevoerd moeten worden.

En mag ik concluderen uit je post dat je hiermee eigenlijk voor elke app een eigen workflow hebt?
Klinkt als een mooie feature voor mijn role template :*) .

Ik heb nu maar 1 workflow die altijd het grote playbook uitvoert. Dat duurt 15 min, dat was ik zat, vandaar dat ik naar een nightly release ben overgestapt.

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 17:51
blackd schreef op zaterdag 14 maart 2026 @ 17:02:
@alex3305 interessante aanpak, zo had ik er nog niet over nagedacht. Feitelijk maak je voor alle laagste niveau apps een playbook en installeer je daar ook je dependencies.
Ja, heel kort door de bocht wel ja :).
Ik neem aan dat je deze opzet ook kent?
Als je de dependencies op role niveau definieert, zouden ze maar 1x uitgevoerd moeten worden.
Zeker. Sterker nog, die pagina had ik open toen ik mijn post schreef :9. Maar een role dependency is wederom per playbook, omdat ik meerdere playbooks uitvoer werkt dat dus niet zoals ik hoop dat dat werkt. Ik moet daarbij wel opmerken dat ik het niet heb getest :$. Wel om meerdere roles uit te voeren in twee playbooks en die worden dan dus ook twee keer uitgevoerd. Verder las ik wat online discussies en documentaties waarbij aangegeven wordt dat role deduplication alleen per play plaatsvindt.

Daarnaast vind ik dat bijvoorbeeld Mosquitto of Zigbee2MQTT geen echte dependency is van Home Assistant. En misschien is dat niet helemaal waar voor een tool zoals Zigbee2MQTT, maar wel voor Mosquitto. De MQTT broker gebruik ik immers ook op andere plekken. En ook krijg je dan een beetje 'vreemde' afhankelijkheden. Is DNS (AdGuard Home) bijvoorbeeld ergens afhankelijk van? Of monitoring en logging? Maar ja, als ik ze niet heb dan werkt het ook niet. Of in een extremer geval is Traefik met Crowdsec bij mij afhankelijk van het Vaultwarden (logging) pad. Is dan Vaultwarden een afhankelijkheid van Traefik? Eigenlijk wel... Maar dat voelt niet zo goed :/.

Collecties zouden hier de uitkomst bieden, maar daarbij zijn afhankelijkheden op andere rollen of collecties alleen mogelijk als deze in de centrale Ansible Galaxy repository staan. En dat wil ik niet :|.

Ik zit hier dus een beetje tussen wal en schip :-(.
En mag ik concluderen uit je post dat je hiermee eigenlijk voor elke app een eigen workflow hebt?
Klinkt als een mooie feature voor mijn role template :*) .
Kort door de bocht wel. Er zijn uiteraard uitzonderingen. Home Assistant is zo'n uitzondering waarbij die wel alle afhankelijkheden include, maar geen op zichzelf staand playbook heeft.
Ik heb nu maar 1 workflow die altijd het grote playbook uitvoert. Dat duurt 15 min, dat was ik zat, vandaar dat ik naar een nightly release ben overgestapt.
Ik haal het volgens mij niet in 15 minuten :P. Misschien is dat wel de noodzaak voor het opsplitsen geweest B-) oOo

Nee, dat was mijn vorige werk. Daar deden we volledige cloud inrichtingen met Ansible. Daar zaten we ook ruim over de 100 rollen heen. Dan is een volledige play - ook per host - niet meer praktisch. Ik heb het dan ook over een Ansible setup van ruim 12 jaar oud.

Dit patroon zie je overigens ook al bij de grotere setups van bijv. Red Hat zelf. Dus heel vreemd is het niet.

  • blackd
  • Registratie: Februari 2001
  • Niet online
alex3305 schreef op zaterdag 14 maart 2026 @ 17:51:
Zeker. Sterker nog, die pagina had ik open toen ik mijn post schreef :9. Maar een role dependency is wederom per playbook, omdat ik meerdere playbooks uitvoer werkt dat dus niet zoals ik hoop dat dat werkt. Ik moet daarbij wel opmerken dat ik het niet heb getest :$. Wel om meerdere roles uit te voeren in twee playbooks en die worden dan dus ook twee keer uitgevoerd. Verder las ik wat online discussies en documentaties waarbij aangegeven wordt dat role deduplication alleen per play plaatsvindt.
Ik heb wel op die manier dependencies opgegeven, zo heb ik een dockerproxy role toegevoegd aan mijn setup en alles wat iets met het docker socket nodig heeft, heeft als dependency de dockerproxy role.
Dat werkt inderdaad binnen een playbook prima, want dat is hoe ik het nu heb ingericht.
Op mijn TrueNAS machine heb ik een jailmaker jail, waar ik alle docker compose projecten naar deploy.
Daarvoor heb ik één playbook truenas_apps.yml waarin alle docker compose projecten als roles staan, ieder met een eigen tag.
Daarnaast vind ik dat bijvoorbeeld Mosquitto of Zigbee2MQTT geen echte dependency is van Home Assistant. En misschien is dat niet helemaal waar voor een tool zoals Zigbee2MQTT, maar wel voor Mosquitto. De MQTT broker gebruik ik immers ook op andere plekken. En ook krijg je dan een beetje 'vreemde' afhankelijkheden. Is DNS (AdGuard Home) bijvoorbeeld ergens afhankelijk van? Of monitoring en logging? Maar ja, als ik ze niet heb dan werkt het ook niet. Of in een extremer geval is Traefik met Crowdsec bij mij afhankelijk van het Vaultwarden (logging) pad. Is dan Vaultwarden een afhankelijkheid van Traefik? Eigenlijk wel... Maar dat voelt niet zo goed :/.
Dat HomeAssistant een dependency heeft op Zigbee2MQTT vind ik wel wat voor te zeggen, ook dat Zigbee2MQTT een broker nodig heeft, vind ik een goede dependency. Maar het maakt ook wel uit wanneer je de dependency nodig hebt, al bij het opstarten of pas bij het configureren van de applicaties.

Een DNS server heb je nodig, dat klopt. Maar dat kun je ook op een andere manier afdwingen, nl: volgorde in je playbooks, zoals je dat bij Docker ook gedaan hebt.

Ik heb een vergelijkbaar playbook voor docker met een groep in mijn inventory en daar kan ik opgeven op welke hosts ik docker geïnstalleerd wil hebben.

Maar hoe pas jij jouw patroon toe bij apps die je op meerdere machines deployed?

Want ik kan me voorstellen dat als je Traefik op meerdere hosts deployed, dat je workflow file triggert op roles/traefik/* maar als je dan meerdere playbooks (aanname) moet aanroepen heb je eigenlijk de link tussen host en app op twee plekken liggen: in je playbooks én je workflow.
Of heb je één playbook per app en dan in die playbooks geconfigureerd op welke host (of groep) je de zaken deployed?

9000Wp o/w SolarEdge SE6K - Panasonic 5kW bi-bloc - gasloos sinds 17-7-2023

Pagina: 1 ... 17 18 Laatste