├── .ansible-lint ├── .editorconfig ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── bug_report.md.license │ ├── feature_request.md │ └── feature_request.md.license ├── dependabot.yml ├── labeler.yml └── workflows │ ├── gitlab.yml │ ├── gitlab_runner.yml │ ├── haproxy.yml │ ├── import-galaxy-test.yml │ ├── keepalived.yml │ ├── labeler.yml │ ├── lint.yml │ ├── netplan.yml │ ├── prepare-action │ └── action.yml │ ├── redis.yml │ ├── release.yml │ ├── reuse-compliance.yml │ ├── ssh_keys.yml │ ├── unattended_upgrades.yml │ └── zammad.yml ├── .github_changelog_generator ├── .gitignore ├── .python-version ├── .python-version.license ├── .yamllint.yml ├── CHANGELOG.md ├── CHANGELOG.md.license ├── CITATION.cff ├── CONTRIBUTING.md ├── LICENSE.md ├── LICENSES ├── Apache-2.0.txt ├── GPL-2.0-or-later.txt └── MIT.txt ├── README.md ├── UNATTENDED_UPGRADES_CHANGELOG.md ├── galaxy.yml ├── meta └── runtime.yml ├── molecule ├── gitlab │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml ├── gitlab_runner │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ ├── requirements.yml │ ├── test_key │ ├── test_key.license │ ├── test_key.pub │ ├── test_key.pub.license │ └── verify.yml ├── haproxy │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ ├── test.pem │ ├── test.pem.license │ └── verify.yml ├── keepalived │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml ├── netplan │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml ├── redis │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml ├── ssh_keys │ ├── converge.yml │ ├── molecule.yml │ ├── requirements.yml │ └── verify.yml ├── unattended_upgrades │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml └── zammad │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ ├── requirements.yml │ └── verify.yml ├── pyproject.toml ├── requirements.yml ├── roles ├── gitlab │ ├── .ansible-lint │ ├── CHANGELOG.md │ ├── GITLAB_BASE_HISTORY.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ ├── configure.yml │ │ ├── feature-flag.yml │ │ ├── install.yml │ │ ├── main.yml │ │ └── reconfigure.yml │ ├── templates │ │ └── gitlab.rb.j2 │ └── vars │ │ ├── AlmaLinux.yml │ │ ├── CentOS.yml │ │ ├── Debian.yml │ │ └── Ubuntu.yml ├── gitlab_runner │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── requirements.yml │ ├── tasks │ │ ├── configuration.yml │ │ ├── docker-machine-init.yml │ │ ├── install.autoscaler-plugin.yml │ │ ├── install.debianlike.yml │ │ ├── install.docker-machine.yml │ │ └── main.yml │ ├── templates │ │ ├── butane-config.bu.j2 │ │ ├── clouds.yaml.j2 │ │ ├── config.toml.j2 │ │ ├── pin-gitlab-runner.pref.j2 │ │ └── runner_config.j2 │ └── vars │ │ └── debian.yml ├── haproxy │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── haproxy.cfg.j2 ├── keepalived │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── keepalived.conf.j2 │ │ └── keepalived.service.j2 ├── netplan │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── config.yaml.j2 ├── redis │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── redis-sentinel.service.j2 │ │ ├── redis-server.service.j2 │ │ ├── redis.conf.j2 │ │ └── sentinel.conf.j2 ├── ssh_keys │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── meta │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── unattended_upgrades │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ ├── main.yml │ │ ├── reboot.yml │ │ ├── systemd_timers.yml │ │ ├── systemd_timers_remove.yml │ │ └── unattended-upgrades.yml │ ├── templates │ │ ├── apt_daily_override.conf.j2 │ │ ├── apt_daily_upgrade_override.conf.j2 │ │ └── unattended-upgrades.j2 │ └── vars │ │ ├── Debian-buster.yml │ │ ├── Debian.yml │ │ ├── Ubuntu.yml │ │ └── main.yml └── zammad │ ├── CHANGELOG.md │ ├── README.md │ ├── defaults │ └── main.yml │ ├── handlers │ └── main.yml │ ├── meta │ └── main.yml │ ├── tasks │ ├── install.yml │ ├── main.yml │ ├── nginx-config.yml │ └── ssl.yml │ └── templates │ └── nginx-zammad.conf.j2 ├── uv.lock └── uv.lock.license /.ansible-lint: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | exclude_paths: 7 | - ".cache/" 8 | - ".ansible/" 9 | skip_list: 10 | - 'var-naming[no-role-prefix]' 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | root = true 8 | 9 | [*] 10 | indent_style = space 11 | indent_size = 2 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | * @hifis-net/hifis-software-technology 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description 11 | A clear and concise description of what the bug is. 12 | 13 | ## To reproduce 14 | Paste an example playbook that can be used to reproduce the problem and/or describe steps to reproduce the behavior. 15 | 16 | ## Current behavior 17 | Please describe the results you received. 18 | 19 | ## Expected behavior 20 | Please describe what you expected to happen. 21 | 22 | ## OS / Environment 23 | Provide all relevant information below, e.g. target OS versions, etc. 24 | 25 | ## Ansible version 26 | Paste verbatim output from "ansible --version". 27 | 28 | ## Collection version 29 | Paste the version of the collection. 30 | 31 | ## Additional context 32 | Please feel free to add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 2 | 3 | SPDX-License-Identifier: Apache-2.0 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description 11 | Is your feature request related to a problem? Please describe, e.g. I'm always frustrated when [...] 12 | 13 | ## Solution 14 | Please describe what you want to happen. 15 | 16 | ## Alternative 17 | Please describe any alternative solutions or features you've considered. 18 | 19 | ## Additional context 20 | Add any other context about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 2 | 3 | SPDX-License-Identifier: Apache-2.0 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | version: 2 8 | enable-beta-ecosystems: true 9 | updates: 10 | 11 | - package-ecosystem: "github-actions" 12 | directory: "/" 13 | schedule: 14 | # Check for updates to GitHub Actions every weekday 15 | interval: "daily" 16 | - package-ecosystem: "github-actions" 17 | directory: "/.github/workflows/prepare-action" 18 | schedule: 19 | # Check for updates to GitHub Actions every weekday 20 | interval: "daily" 21 | 22 | - package-ecosystem: "uv" 23 | directory: "/" 24 | schedule: 25 | # Check for updates to pip packages every weekday 26 | interval: "daily" 27 | ignore: 28 | - dependency-name: "python" 29 | update-types: ["version-update:semver-major"] 30 | ... 31 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_runner: 8 | - changed-files: 9 | - any-glob-to-any-file: 10 | - "roles/gitlab_runner/**" 11 | - "molecule/gitlab_runner/**" 12 | - ".github/workflows/gitlab_runner.yml" 13 | gitlab: 14 | - changed-files: 15 | - any-glob-to-any-file: 16 | - "roles/gitlab/**" 17 | - "molecule/gitlab/**" 18 | - ".github/workflows/gitlab.yml" 19 | haproxy: 20 | - changed-files: 21 | - any-glob-to-any-file: 22 | - "roles/haproxy/**" 23 | - "molecule/haproxy/**" 24 | - ".github/workflows/haproxy.yml" 25 | keepalived: 26 | - changed-files: 27 | - any-glob-to-any-file: 28 | - "roles/keepalived/**" 29 | - "molecule/keepalived/**" 30 | - ".github/workflows/keepalived.yml" 31 | netplan: 32 | - changed-files: 33 | - any-glob-to-any-file: 34 | - "roles/netplan/**" 35 | - "molecule/netplan/**" 36 | - ".github/workflows/netplan.yml" 37 | redis: 38 | - changed-files: 39 | - any-glob-to-any-file: 40 | - "roles/redis/**" 41 | - "molecule/redis/**" 42 | - ".github/workflows/redis.yml" 43 | ssh_keys: 44 | - changed-files: 45 | - any-glob-to-any-file: 46 | - "roles/ssh_keys/**" 47 | - "molecule/ssh_keys/**" 48 | - ".github/workflows/ssh_keys.yml" 49 | unattended_upgrades: 50 | - changed-files: 51 | - any-glob-to-any-file: 52 | - "roles/unattended_upgrades/**" 53 | - "molecule/unattended_upgrades/**" 54 | - ".github/workflows/unattended_upgrades.yml" 55 | zammad: 56 | - changed-files: 57 | - any-glob-to-any-file: 58 | - "roles/zammad/**" 59 | - "molecule/zammad/**" 60 | - ".github/workflows/zammad.yml" 61 | -------------------------------------------------------------------------------- /.github/workflows/gitlab.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.gitlab" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/gitlab.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/gitlab/**' 15 | - 'molecule/gitlab/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/gitlab.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/gitlab/**' 27 | - 'molecule/gitlab/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: "0 0 * * *" 32 | env: 33 | PY_COLORS: 1 34 | ANSIBLE_FORCE_COLOR: 1 35 | 36 | jobs: 37 | 38 | test: 39 | name: "Run Molecule tests." 40 | runs-on: "ubuntu-24.04" 41 | env: 42 | PY_COLORS: 1 43 | ANSIBLE_FORCE_COLOR: 1 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | image: 48 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 49 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 50 | - "ghcr.io/hifis-net/debian-systemd:11" 51 | 52 | steps: 53 | - name: "Check out the codebase." 54 | uses: "actions/checkout@v4" 55 | with: 56 | path: "./ansible_collections/hifis/toolkit" 57 | 58 | - name: "Prepare the job environment." 59 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 60 | 61 | # https://github.com/ansible/molecule/issues/3806 62 | - name: "Help molecule to find the dependencies" 63 | run: | 64 | mkdir -p /home/runner/.ansible 65 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 66 | /home/runner/.ansible/roles 67 | 68 | - name: "Run Molecule tests." 69 | run: "uv run molecule test -s gitlab" 70 | env: 71 | MOLECULE_IMAGE: "${{ matrix.image }}" 72 | working-directory: "./ansible_collections/hifis/toolkit" 73 | -------------------------------------------------------------------------------- /.github/workflows/gitlab_runner.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.gitlab_runner" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/gitlab_runner.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/gitlab_runner/**' 15 | - 'molecule/gitlab_runner/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/gitlab_runner.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/gitlab_runner/**' 27 | - 'molecule/gitlab_runner/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: "0 0 * * *" 32 | env: 33 | PY_COLORS: 1 34 | ANSIBLE_FORCE_COLOR: 1 35 | 36 | jobs: 37 | 38 | test: 39 | name: "Run Molecule tests." 40 | runs-on: "ubuntu-24.04" 41 | env: 42 | PY_COLORS: 1 43 | ANSIBLE_FORCE_COLOR: 1 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | image: 48 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 49 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 50 | - "ghcr.io/hifis-net/debian-systemd:11" 51 | - "ghcr.io/hifis-net/debian-systemd:12" 52 | 53 | steps: 54 | - name: "Check out the codebase." 55 | uses: "actions/checkout@v4" 56 | with: 57 | path: "./ansible_collections/hifis/toolkit" 58 | 59 | - name: "Prepare the job environment." 60 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 61 | 62 | # https://github.com/ansible/molecule/issues/3806 63 | - name: "Help molecule to find the dependencies" 64 | run: | 65 | mkdir -p /home/runner/.ansible 66 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 67 | /home/runner/.ansible/roles 68 | 69 | - name: "Run Molecule tests." 70 | run: "uv run molecule test -s gitlab_runner" 71 | env: 72 | MOLECULE_IMAGE: "${{ matrix.image }}" 73 | AUTHENTICATION_TOKEN: "${{ secrets.authentication_token }}" 74 | working-directory: "./ansible_collections/hifis/toolkit" 75 | -------------------------------------------------------------------------------- /.github/workflows/haproxy.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.haproxy" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/haproxy.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/haproxy/**' 15 | - 'molecule/haproxy/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/haproxy.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/haproxy/**' 27 | - 'molecule/haproxy/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: "0 0 * * *" 32 | 33 | jobs: 34 | 35 | test: 36 | name: "Run Molecule tests." 37 | runs-on: "ubuntu-24.04" 38 | env: 39 | PY_COLORS: 1 40 | ANSIBLE_FORCE_COLOR: 1 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | image: 45 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 46 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 47 | - "ghcr.io/hifis-net/debian-systemd:11" 48 | - "ghcr.io/hifis-net/debian-systemd:12" 49 | 50 | steps: 51 | - name: "Check out the codebase." 52 | uses: "actions/checkout@v4" 53 | with: 54 | path: "./ansible_collections/hifis/toolkit" 55 | 56 | - name: "Prepare the job environment." 57 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 58 | 59 | # https://github.com/ansible/molecule/issues/3806 60 | - name: "Help molecule to find the dependencies" 61 | run: | 62 | mkdir -p /home/runner/.ansible 63 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 64 | /home/runner/.ansible/roles 65 | 66 | - name: "Run Molecule tests." 67 | # Haproxy tries to configure the nofile limit which is not allowed from within podman. 68 | # This approach increased the limit beforehand. 69 | run: "XDG_RUNTIME_DIR=/run/user/$UID uv run sudo prlimit --pid $$ --nofile=500000:500000 && uv run molecule test -s haproxy" 70 | env: 71 | MOLECULE_IMAGE: "${{ matrix.image }}" 72 | working-directory: "./ansible_collections/hifis/toolkit" 73 | -------------------------------------------------------------------------------- /.github/workflows/import-galaxy-test.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "Test importing collection" 8 | 9 | on: 10 | pull_request: 11 | push: 12 | branches: 13 | - "main" 14 | 15 | jobs: 16 | import-galaxy: 17 | permissions: 18 | contents: "read" 19 | name: "Import collection with Galaxy importer" 20 | uses: "ansible-community/github-action-test-galaxy-import/.github/workflows/test-galaxy-import.yml@main" 21 | -------------------------------------------------------------------------------- /.github/workflows/keepalived.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.keepalived" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/keepalived.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/keepalived/**' 15 | - 'molecule/keepalived/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/keepalived.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/keepalived/**' 27 | - 'molecule/keepalived/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: '0 0 * * *' 32 | 33 | jobs: 34 | 35 | test: 36 | name: "Run Molecule tests." 37 | runs-on: "ubuntu-24.04" 38 | env: 39 | PY_COLORS: 1 40 | ANSIBLE_FORCE_COLOR: 1 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | image: 45 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 46 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 47 | 48 | steps: 49 | - name: "Check out the codebase." 50 | uses: "actions/checkout@v4" 51 | with: 52 | path: "./ansible_collections/hifis/toolkit" 53 | 54 | - name: "Prepare the job environment." 55 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 56 | 57 | - name: "Run Molecule tests." 58 | run: "uv run molecule test -s keepalived" 59 | env: 60 | MOLECULE_IMAGE: "${{ matrix.image }}" 61 | working-directory: "./ansible_collections/hifis/toolkit" 62 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "Pull Request Labeler" 8 | 9 | on: 10 | pull_request_target: 11 | types: 12 | - "labeled" 13 | - "unlabeled" 14 | - "opened" 15 | - "edited" 16 | - "synchronize" 17 | 18 | jobs: 19 | labeler: 20 | runs-on: "ubuntu-24.04" 21 | permissions: 22 | contents: "read" 23 | pull-requests: "write" 24 | steps: 25 | - name: "Check out the codebase." 26 | uses: "actions/checkout@v4" 27 | 28 | - uses: "actions/labeler@v5.0.0" 29 | with: 30 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 31 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "Ansible Lint" 8 | 9 | on: 10 | push: 11 | pull_request: 12 | 13 | env: 14 | PY_COLORS: 1 15 | ANSIBLE_FORCE_COLOR: 1 16 | 17 | jobs: 18 | 19 | ansible-lint: 20 | name: "Ansible Lint" 21 | runs-on: "ubuntu-24.04" 22 | steps: 23 | - name: "Check out the codebase." 24 | uses: "actions/checkout@v4" 25 | 26 | - name: "Lint code." 27 | uses: "ansible/ansible-lint@v25.5.0" 28 | -------------------------------------------------------------------------------- /.github/workflows/netplan.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.netplan" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/netplan.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/netplan/**' 15 | - 'molecule/netplan/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/netplan.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/netplan/**' 27 | - 'molecule/netplan/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: "0 0 * * *" 32 | 33 | jobs: 34 | 35 | test: 36 | name: "Run Molecule tests." 37 | runs-on: "ubuntu-24.04" 38 | env: 39 | PY_COLORS: 1 40 | ANSIBLE_FORCE_COLOR: 1 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | image: 45 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 46 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 47 | 48 | steps: 49 | - name: "Check out the codebase." 50 | uses: "actions/checkout@v4" 51 | with: 52 | path: "./ansible_collections/hifis/toolkit" 53 | 54 | - name: "Prepare the job environment." 55 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 56 | 57 | # https://github.com/ansible/molecule/issues/3806 58 | - name: "Help molecule to find the dependencies" 59 | run: | 60 | mkdir -p /home/runner/.ansible 61 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 62 | /home/runner/.ansible/roles 63 | 64 | - name: "Create Podman network required for testing" 65 | run: "podman network create --subnet 10.123.0.0/24 netplan_network" 66 | 67 | - name: "Run Molecule tests." 68 | run: "uv run molecule test -s netplan" 69 | env: 70 | MOLECULE_IMAGE: "${{ matrix.image }}" 71 | working-directory: "./ansible_collections/hifis/toolkit" 72 | -------------------------------------------------------------------------------- /.github/workflows/prepare-action/action.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "Install dependencies and prepare the environment." 8 | description: "Install the necessary dependencies for jobs." 9 | runs: 10 | using: "composite" 11 | steps: 12 | - name: "Configure UV_PYTHON variable" 13 | run: 'echo "UV_PYTHON=$(cat .python-version)" >> $GITHUB_ENV' 14 | shell: "bash" 15 | working-directory: "./ansible_collections/hifis/toolkit/" 16 | 17 | - name: "Set up Python 3.x" 18 | uses: "actions/setup-python@v5" 19 | with: 20 | python-version-file: "./ansible_collections/hifis/toolkit/.python-version" 21 | 22 | - name: "Install uv" 23 | uses: "astral-sh/setup-uv@v6" 24 | with: 25 | enable-cache: true 26 | cache-dependency-glob: "./ansible_collections/hifis/toolkit/uv.lock" 27 | 28 | - name: "Install dependencies via uv." 29 | run: "uv sync --frozen" 30 | shell: "bash" 31 | working-directory: "./ansible_collections/hifis/toolkit" 32 | -------------------------------------------------------------------------------- /.github/workflows/redis.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.redis" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/redis.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/redis/**' 15 | - 'molecule/redis/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/redis.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/redis/**' 27 | - 'molecule/redis/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: "0 0 * * *" 32 | env: 33 | PY_COLORS: 1 34 | ANSIBLE_FORCE_COLOR: 1 35 | 36 | jobs: 37 | 38 | test: 39 | name: "Run Molecule tests." 40 | runs-on: "ubuntu-24.04" 41 | env: 42 | PY_COLORS: 1 43 | ANSIBLE_FORCE_COLOR: 1 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | image: 48 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 49 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 50 | 51 | steps: 52 | - name: "Check out the codebase." 53 | uses: "actions/checkout@v4" 54 | with: 55 | path: "./ansible_collections/hifis/toolkit" 56 | 57 | - name: "Prepare the job environment." 58 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 59 | 60 | # https://github.com/ansible/molecule/issues/3806 61 | - name: "Help molecule to find the dependencies" 62 | run: | 63 | mkdir -p /home/runner/.ansible 64 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 65 | /home/runner/.ansible/roles 66 | 67 | - name: "Run Molecule tests." 68 | run: "uv run molecule test -s redis" 69 | env: 70 | MOLECULE_IMAGE: "${{ matrix.image }}" 71 | working-directory: "./ansible_collections/hifis/toolkit" 72 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "Release new version on Ansible Galaxy" 8 | 9 | on: 10 | release: 11 | types: 12 | - "released" 13 | 14 | jobs: 15 | 16 | release: 17 | name: "Release new version on Ansible Galaxy" 18 | runs-on: "ubuntu-24.04" 19 | steps: 20 | - name: "checkout" 21 | uses: "actions/checkout@v4" 22 | 23 | - name: "Deploy the collection" 24 | uses: "artis3n/ansible_galaxy_collection@v2.11.0" 25 | with: 26 | api_key: "${{ secrets.galaxy_api_key }}" 27 | -------------------------------------------------------------------------------- /.github/workflows/reuse-compliance.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "Check compliance with the REUSE specification" 8 | 9 | on: 10 | push: 11 | pull_request: 12 | 13 | jobs: 14 | reuse-lint: 15 | name: "REUSE compliance check" 16 | runs-on: "ubuntu-24.04" 17 | steps: 18 | - name: "Check out the codebase." 19 | uses: "actions/checkout@v4" 20 | 21 | - name: "REUSE lint" 22 | uses: "fsfe/reuse-action@v5.0.0" 23 | -------------------------------------------------------------------------------- /.github/workflows/ssh_keys.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.ssh_keys" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/ssh_keys.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/ssh_keys/**' 15 | - 'molecule/ssh_keys/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/ssh_keys.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/ssh_keys/**' 27 | - 'molecule/ssh_keys/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: '0 0 * * *' 32 | 33 | jobs: 34 | 35 | test: 36 | name: "Run Molecule tests." 37 | runs-on: "ubuntu-24.04" 38 | env: 39 | PY_COLORS: 1 40 | ANSIBLE_FORCE_COLOR: 1 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | image: 45 | - "ghcr.io/hifis-net/almalinux-systemd:8" 46 | - "ghcr.io/hifis-net/almalinux-systemd:9" 47 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 48 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 49 | - "ghcr.io/hifis-net/debian-systemd:11" 50 | - "ghcr.io/hifis-net/debian-systemd:12" 51 | 52 | steps: 53 | - name: "Check out the codebase." 54 | uses: "actions/checkout@v4" 55 | with: 56 | path: "./ansible_collections/hifis/toolkit" 57 | 58 | - name: "Prepare the job environment." 59 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 60 | 61 | # https://github.com/ansible/molecule/issues/3806 62 | - name: "Help molecule to find the dependencies" 63 | run: | 64 | mkdir -p /home/runner/.ansible 65 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 66 | /home/runner/.ansible/roles 67 | 68 | - name: "Run Molecule tests." 69 | run: "uv run molecule test -s ssh_keys" 70 | env: 71 | MOLECULE_IMAGE: "${{ matrix.image }}" 72 | working-directory: "./ansible_collections/hifis/toolkit" 73 | -------------------------------------------------------------------------------- /.github/workflows/unattended_upgrades.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.unattended_upgrades" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/unattended_upgrades.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/unattended_upgrades/**' 15 | - 'molecule/unattended_upgrades/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/unattended_upgrades.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/unattended_upgrades/**' 27 | - 'molecule/unattended_upgrades/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: '0 0 * * *' 32 | 33 | jobs: 34 | 35 | test: 36 | name: "Run Molecule tests." 37 | runs-on: "ubuntu-24.04" 38 | env: 39 | PY_COLORS: 1 40 | ANSIBLE_FORCE_COLOR: 1 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | image: 45 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 46 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 47 | - "ghcr.io/hifis-net/debian-systemd:12" 48 | - "ghcr.io/hifis-net/debian-systemd:11" 49 | 50 | steps: 51 | - name: "Check out the codebase." 52 | uses: "actions/checkout@v4" 53 | with: 54 | path: "./ansible_collections/hifis/toolkit" 55 | 56 | - name: "Prepare the job environment." 57 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 58 | 59 | - name: "Run Molecule tests." 60 | run: "uv run molecule test -s unattended_upgrades" 61 | env: 62 | MOLECULE_IMAGE: "${{ matrix.image }}" 63 | working-directory: "./ansible_collections/hifis/toolkit" 64 | -------------------------------------------------------------------------------- /.github/workflows/zammad.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | name: "hifis.toolkit.zammad" 8 | 9 | on: 10 | pull_request: 11 | paths: 12 | - '.github/workflows/zammad.yml' 13 | - '.github/workflows/prepare-action/action.yml' 14 | - 'roles/zammad/**' 15 | - 'molecule/zammad/**' 16 | - 'pyproject.toml' 17 | - 'uv.lock' 18 | push: 19 | branches: 20 | - "main" 21 | tags: 22 | - "v*.*.*" 23 | paths: 24 | - '.github/workflows/zammad.yml' 25 | - '.github/workflows/prepare-action/action.yml' 26 | - 'roles/zammad/**' 27 | - 'molecule/zammad/**' 28 | - 'pyproject.toml' 29 | - 'uv.lock' 30 | schedule: 31 | - cron: '0 0 * * *' 32 | 33 | jobs: 34 | 35 | test: 36 | name: "Run Molecule tests." 37 | runs-on: "ubuntu-24.04" 38 | env: 39 | PY_COLORS: 1 40 | ANSIBLE_FORCE_COLOR: 1 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | image: 45 | - "ghcr.io/hifis-net/ubuntu-systemd:22.04" 46 | - "ghcr.io/hifis-net/ubuntu-systemd:24.04" 47 | 48 | steps: 49 | - name: "Check out the codebase." 50 | uses: "actions/checkout@v4" 51 | with: 52 | path: "./ansible_collections/hifis/toolkit" 53 | 54 | - name: "Prepare the job environment." 55 | uses: "./ansible_collections/hifis/toolkit/.github/workflows/prepare-action" 56 | 57 | # https://github.com/ansible/molecule/issues/3806 58 | - name: "Help molecule to find the dependencies" 59 | run: | 60 | mkdir -p /home/runner/.ansible 61 | ln -s /home/runner/work/ansible-collection-toolkit/ansible-collection-toolkit/ansible_collections/hifis/toolkit/roles \ 62 | /home/runner/.ansible/roles 63 | 64 | - name: "Run Molecule tests." 65 | run: "XDG_RUNTIME_DIR=/run/user/$UID uv run molecule test -s zammad" 66 | env: 67 | MOLECULE_IMAGE: "${{ matrix.image }}" 68 | working-directory: "./ansible_collections/hifis/toolkit" 69 | -------------------------------------------------------------------------------- /.github_changelog_generator: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | user=hifis-net 7 | project=ansible-collection-toolkit 8 | since-tag=v3.3.0 9 | issue-line-labels=gitlab,gitlab_runner,haproxy,keepalived,netplan,redis,ssh_keys,unattended_upgrades,zammad 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | .vagrant/ 8 | *~ 9 | *.log 10 | .idea/ 11 | .venv/ 12 | .vscode/ 13 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.13 2 | -------------------------------------------------------------------------------- /.python-version.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | -------------------------------------------------------------------------------- /.yamllint.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | # Based on ansible-lint config 8 | extends: "default" 9 | 10 | ignore: | 11 | .cache/ 12 | 13 | rules: 14 | braces: 15 | max-spaces-inside: 1 16 | level: "error" 17 | brackets: 18 | max-spaces-inside: 1 19 | level: "error" 20 | colons: 21 | max-spaces-after: -1 22 | level: "error" 23 | commas: 24 | max-spaces-after: -1 25 | level: "error" 26 | comments: 27 | min-spaces-from-content: 1 28 | comments-indentation: "disable" 29 | document-start: "disable" 30 | empty-lines: 31 | max: 3 32 | level: "error" 33 | hyphens: 34 | level: "error" 35 | indentation: "enable" 36 | key-duplicates: "enable" 37 | line-length: "disable" 38 | new-line-at-end-of-file: "enable" 39 | new-lines: 40 | type: "unix" 41 | octal-values: 42 | forbid-implicit-octal: true 43 | forbid-explicit-octal: true 44 | quoted-strings: 45 | quote-type: "any" 46 | required: true 47 | extra-required: [ ] 48 | extra-allowed: [ ] 49 | trailing-spaces: "enable" 50 | truthy: "enable" 51 | -------------------------------------------------------------------------------- /CHANGELOG.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | cff-version: '1.2.0' 7 | title: 'hifis.toolkit Ansible collection' 8 | message: >- 9 | "If you use this Ansible collection, please cite 10 | it as below." 11 | abstract: >- 12 | Ansible collection that provides production-ready Ansible roles used for providing 13 | services used in research and by research software engineers, but not exclusively. 14 | type: 'software' 15 | authors: 16 | - given-names: 'Norman' 17 | family-names: 'Ziegner' 18 | email: 'n.ziegner@hzdr.de' 19 | affiliation: >- 20 | Helmholtz-Zentrum Dresden - Rossendorf e. V. 21 | (HZDR) 22 | orcid: 'https://orcid.org/0000-0001-7579-216X' 23 | - given-names: 'Tobias' 24 | family-names: 'Huste' 25 | email: 't.huste@hzdr.de' 26 | affiliation: >- 27 | Helmholtz-Zentrum Dresden - Rossendorf e. V. 28 | (HZDR) 29 | orcid: 'https://orcid.org/0000-0002-5590-7473' 30 | - given-names: 'Christian' 31 | family-names: 'Hüser' 32 | email: 'c.hueser@hzdr.de' 33 | affiliation: >- 34 | Helmholtz-Zentrum Dresden - Rossendorf e. V. 35 | (HZDR) 36 | orcid: 'https://orcid.org/0000-0002-5028-6663' 37 | repository-code: 'https://github.com/hifis-net/ansible-collection-toolkit' 38 | repository-artifact: 'https://galaxy.ansible.com/ui/repo/published/hifis/toolkit/' 39 | version: v6.0.0' 40 | date-released: '2025-06-04' 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License Hint 2 | 3 | Copyright © 2022 Helmholtz Centre for Environmental Research (UFZ) 4 | Copyright © 2022 Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 5 | 6 | This work is licensed under the Apache-2.0 license. 7 | The individual Ansible roles in the roles directory may be licensed differently. 8 | 9 | Please see the individual files for more accurate information. 10 | 11 | > **Hint:** We provided the copyright and license information in accordance to the [REUSE Specification 3.0](https://reuse.software/spec/). 12 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Helmholtz Centre for Environmental Research (UFZ) 4 | Copyright (c) 2020 Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # Ansible Collection - hifis.toolkit 9 | 10 | [![Latest release](https://img.shields.io/github/v/release/hifis-net/ansible-collection-toolkit)](https://github.com/hifis-net/ansible-collection-toolkit/releases) 11 | [![hifis.gitlab_runner](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/gitlab_runner.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/gitlab_runner.yml) 12 | [![hifis.gitlab](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/gitlab.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/gitlab.yml) 13 | [![hifis.haproxy](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/haproxy.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/haproxy.yml) 14 | [![hifis.keepalived](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/keepalived.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/keepalived.yml) 15 | [![hifis.netplan](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/netplan.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/netplan.yml) 16 | [![hifis.redis](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/redis.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/redis.yml) 17 | [![hifis.ssh_keys](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/ssh_keys.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/ssh_keys.yml) 18 | [![hifis.unattended_upgrades](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/unattended_upgrades.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/unattended_upgrades.yml) 19 | [![hifis.zammad](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/zammad.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/zammad.yml) 20 | [![DOI](https://zenodo.org/badge/495697576.svg)](https://zenodo.org/doi/10.5281/zenodo.11147483) 21 | 22 | This collection provides production-ready Ansible roles used for providing services used in research and by research 23 | software engineers, but not exclusively. The following use cases are supported: 24 | 25 | * **DevOps platform:** 26 | * [GitLab](roles/gitlab) 27 | * deploy [GitLab-Runner](roles/gitlab_runner) with a focus, but not limited, on Openstack autoscaling 28 | * [Redis](roles/redis) 29 | * **Help desk:** 30 | * [Zammad](roles/zammad) 31 | * **High Availability (HA) / Load Balancing:** 32 | * [HAProxy](roles/haproxy) 33 | * [Keepalived](roles/keepalived) 34 | * **OS-related:** 35 | * [unattended-upgrades](roles/unattended_upgrades) 36 | * [netplan](roles/netplan) 37 | * distribute authorized [SSH keys](roles/ssh_keys) to users 38 | 39 | ## Looking for the unattended_upgrades role? 40 | 41 | You can now find it under [roles/unattended_upgrades](roles/unattended_upgrades). 42 | 43 | We moved our existing Ansible roles into a single collection to deduplicate code and have a common test suite for all roles. 44 | We decided to reuse the unattended_upgrades repository as a collection repo as it is our most popular role. 45 | 46 | ## Minimum required Ansible-version 47 | 48 | * Ansible >= 2.17 49 | 50 | ## Installation 51 | 52 | Install the collection via ansible-galaxy: 53 | 54 | ```shell 55 | ansible-galaxy collection install hifis.toolkit 56 | ``` 57 | 58 | ## Contributing 59 | 60 | See [CONTRIBUTING.md](CONTRIBUTING.md). 61 | 62 | ## License 63 | 64 | Apache-2.0 65 | 66 | ## Author 67 | 68 | This collection is maintained by [HIFIS Software Services](https://hifis.net/). 69 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | namespace: 'hifis' 7 | name: 'toolkit' 8 | version: '6.0.0' 9 | readme: 'README.md' 10 | authors: 11 | - 'HIFIS Software Services ' 12 | description: 'This collection provides production-ready Ansible roles used for providing services used in research and by research software engineers, but not exclusively.' 13 | license: 14 | - 'Apache-2.0' 15 | - 'GPL-2.0-or-later' 16 | - 'MIT' 17 | tags: 18 | - 'hifis' 19 | - 'ubuntu' 20 | - 'debian' 21 | - 'linux' 22 | - 'system' 23 | dependencies: {} 24 | repository: 'https://github.com/hifis-net/ansible-collection-toolkit' 25 | homepage: 'https://hifis.net/services/software-overview.html' 26 | issues: 'https://github.com/hifis-net/ansible-collection-toolkit/issues' 27 | build_ignore: 28 | - '.editorconfig' 29 | - '.github' 30 | - '.github_changelog_generator' 31 | - '.gitattributes' 32 | - '.gitignore' 33 | - '.yamllint' 34 | - 'pyproject.toml' 35 | - 'uv.lock' 36 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | requires_ansible: '>=2.17.0' 8 | -------------------------------------------------------------------------------- /molecule/gitlab/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | tasks: 10 | - name: "Include gitlab role" 11 | ansible.builtin.include_role: 12 | name: "hifis.toolkit.gitlab" 13 | 14 | ... 15 | -------------------------------------------------------------------------------- /molecule/gitlab/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | driver: 10 | name: "podman" 11 | platforms: 12 | - name: "instancegitlab" 13 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 14 | pre_build_image: true 15 | privileged: true 16 | systemd: "always" 17 | tty: true 18 | override_command: false 19 | provisioner: 20 | name: "ansible" 21 | config_options: 22 | defaults: 23 | result_format: "yaml" 24 | playbooks: 25 | prepare: "prepare.yml" 26 | check: "converge.yml" 27 | converge: "converge.yml" 28 | verify: "verify.yml" 29 | inventory: 30 | host_vars: 31 | instancegitlab: 32 | gitlab_edition: "gitlab-ce" 33 | gitlab_ip_range: "0.0.0.0/0" 34 | gitlab_additional_configurations: 35 | - package: 36 | - key: "modify_kernel_parameters" 37 | type: "plain" 38 | value: "false" 39 | - gitlab_kas: 40 | - key: "env" 41 | type: "plain" 42 | value: "{ 'OWN_PRIVATE_API_URL' => 'grpc://127.0.0.1:8155' }" 43 | gitlab_feature_flags: 44 | # See https://docs.gitlab.com/ee/user/feature_flags.html 45 | - name: "vscode_web_ide" 46 | enabled: true 47 | - name: "chatops" 48 | enabled: true 49 | - name: "webauthn" 50 | enabled: false 51 | verifier: 52 | name: "ansible" 53 | scenario: 54 | name: "gitlab" 55 | test_sequence: 56 | - "destroy" 57 | - "dependency" 58 | - "syntax" 59 | - "create" 60 | - "prepare" 61 | - "check" 62 | - "converge" 63 | - "idempotence" 64 | - "check" 65 | - "side_effect" 66 | - "verify" 67 | - "destroy" 68 | 69 | ... 70 | -------------------------------------------------------------------------------- /molecule/gitlab/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Prepare" 8 | hosts: "all" 9 | tasks: 10 | - name: "Install depenencies for OS family RedHat" 11 | when: 12 | - "ansible_facts.os_family == 'RedHat'" 13 | - "ansible_facts.distribution_major_version | int >= 7" 14 | block: 15 | - name: "Install missing dependencies" 16 | ansible.builtin.dnf: 17 | name: 18 | - "sudo" 19 | - "iproute" 20 | - "libarchive" 21 | state: "present" 22 | update_cache: true 23 | 24 | - name: "Install depenencies for OS family Debian" 25 | when: "ansible_facts.os_family == 'Debian'" 26 | block: 27 | - name: "Install missing dependencies" 28 | ansible.builtin.apt: 29 | name: 30 | - "sudo" # for `become` privilege escalation 31 | - "iproute2" # for gathering network facts 32 | - "python3-debian" 33 | - "ca-certificates" 34 | state: "present" 35 | update_cache: true 36 | 37 | # Provisioning freezes and GitLab "waits for redis server socket" on task "GitLab reconfigure" if file ".dockerenv" exists! 38 | - name: "Remove file so GitLab Omnibus does not wait for redis server socket on task GitLab reconfigure." 39 | ansible.builtin.file: 40 | path: "/.dockerenv" 41 | state: "absent" 42 | 43 | ... 44 | -------------------------------------------------------------------------------- /molecule/gitlab/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Verify" 8 | hosts: "all" 9 | tasks: 10 | - name: "Gather package facts" 11 | ansible.builtin.package_facts: 12 | manager: "auto" 13 | 14 | - name: "Assert that GitLab Omnibus package is installed" 15 | ansible.builtin.assert: 16 | that: 17 | - "gitlab_edition in ansible_facts.packages" 18 | when: 19 | - "gitlab_edition is defined" 20 | 21 | - name: "Set expected package version of GitLab" 22 | ansible.builtin.set_fact: 23 | gitlab_expected_package_version: "{{ gitlab_version }}-{{ gitlab_release }}" 24 | when: 25 | - "gitlab_edition is defined" 26 | - "gitlab_version is defined" 27 | - "gitlab_release is defined" 28 | 29 | - name: "Assert that installed GitLab version is equal to the desired one" 30 | ansible.builtin.assert: 31 | that: 32 | - "ansible_facts.packages[gitlab_edition][0].version == gitlab_expected_package_version" 33 | when: 34 | - "gitlab_edition is defined" 35 | - "gitlab_version is defined" 36 | - "gitlab_release is defined" 37 | 38 | - name: "Check GitLab Health endpoint" 39 | ansible.builtin.uri: 40 | url: "http://localhost/-/health" 41 | register: "health_check" 42 | failed_when: "'OK' not in health_check.msg or health_check.status != 200" 43 | 44 | - name: "Check GitLab Readiness endpoint" 45 | ansible.builtin.uri: 46 | url: "http://localhost/-/readiness?all=1" 47 | register: "readiness_check" 48 | failed_when: "readiness_check.status == 503" 49 | 50 | - name: "Check GitLab Liveness endpoint" 51 | ansible.builtin.uri: 52 | url: "http://localhost/-/liveness" 53 | register: "liveness_check" 54 | failed_when: "liveness_check.status == 503" 55 | 56 | - name: "Check the output of gitlab status" 57 | ansible.builtin.command: "gitlab-ctl status" 58 | register: "gitlab_ctl_status" 59 | changed_when: "gitlab_ctl_status.rc != 0" 60 | failed_when: "gitlab_ctl_status.rc != 0" 61 | 62 | - name: "Check GitLab configuration via Rake task" 63 | ansible.builtin.command: "gitlab-rake gitlab:check" 64 | register: "gitlab_rake_check" 65 | changed_when: "gitlab_rake_check.rc != 0" 66 | failed_when: "gitlab_rake_check.rc != 0" 67 | 68 | ... 69 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | tasks: 10 | - name: "Include gitlab_runner role" 11 | ansible.builtin.include_role: 12 | name: "hifis.toolkit.gitlab_runner" 13 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Prepare" 8 | hosts: "all" 9 | tasks: 10 | - name: "Install necessary packages" 11 | when: "ansible_os_family == 'Debian'" 12 | block: 13 | - name: "Install missing dependencies" 14 | ansible.builtin.apt: 15 | name: 16 | - "sudo" # for `become` privilege escalation 17 | - "iproute2" # for gathering network facts 18 | - "ca-certificates" # for Gitlab-Runner download 19 | - "gpg" 20 | - "python3-debian" 21 | state: "present" 22 | update_cache: true 23 | - name: "Set up iptables" 24 | when: "ansible_distribution == 'Debian'" 25 | block: 26 | - name: "Install missing dependencies" 27 | ansible.builtin.apt: 28 | name: 29 | - "iptables" 30 | state: "present" 31 | update_cache: true 32 | - name: "Use legacy iptables" 33 | community.general.alternatives: 34 | name: "iptables" 35 | path: "/usr/sbin/iptables-legacy" 36 | - name: "Use legacy ip6tables" 37 | community.general.alternatives: 38 | name: "ip6tables" 39 | path: "/usr/sbin/ip6tables-legacy" 40 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/requirements.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | roles: 8 | - name: "geerlingguy.docker" 9 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/test_key: -------------------------------------------------------------------------------- 1 | -----BEGIN OPENSSH PRIVATE KEY----- 2 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 3 | QyNTUxOQAAACAZxWIoT1CX3FFjc3+Em53Hy5ht8AbF8QHWQb25c3H2hQAAAJCiuPqvorj6 4 | rwAAAAtzc2gtZWQyNTUxOQAAACAZxWIoT1CX3FFjc3+Em53Hy5ht8AbF8QHWQb25c3H2hQ 5 | AAAEBQMNsWaiJGO+9HM245p+bcdI6mucBBHnD+880/zEOOERnFYihPUJfcUWNzf4SbncfL 6 | mG3wBsXxAdZBvblzcfaFAAAACXVzZXJAaG9zdAECAwQ= 7 | -----END OPENSSH PRIVATE KEY----- 8 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/test_key.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/test_key.pub: -------------------------------------------------------------------------------- 1 | ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBnFYihPUJfcUWNzf4SbncfLmG3wBsXxAdZBvblzcfaF 2 | -------------------------------------------------------------------------------- /molecule/gitlab_runner/test_key.pub.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | -------------------------------------------------------------------------------- /molecule/haproxy/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | tasks: 10 | - name: "Include haproxy_role" 11 | ansible.builtin.include_role: 12 | name: "hifis.toolkit.haproxy" 13 | vars: 14 | haproxy_frontend_ip: "192.168.33.100" 15 | haproxy_backends: 16 | - backend_name: "backend_server_1" 17 | backend_ip: "192.168.33.10" 18 | 19 | ... 20 | -------------------------------------------------------------------------------- /molecule/haproxy/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | driver: 10 | name: "podman" 11 | platforms: 12 | - name: "haproxy_v3.2" 13 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 14 | pre_build_image: true 15 | privileged: true 16 | override_command: false 17 | systemd: true 18 | tty: true 19 | - name: "haproxy_v3.0" 20 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 21 | pre_build_image: true 22 | privileged: true 23 | override_command: false 24 | systemd: true 25 | tty: true 26 | - name: "haproxy_v2.8" 27 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 28 | pre_build_image: true 29 | privileged: true 30 | override_command: false 31 | systemd: true 32 | tty: true 33 | - name: "haproxy_v2.6" 34 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 35 | pre_build_image: true 36 | privileged: true 37 | override_command: false 38 | systemd: true 39 | tty: true 40 | - name: "haproxy_v2.4" 41 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 42 | pre_build_image: true 43 | privileged: true 44 | override_command: false 45 | systemd: true 46 | tty: true 47 | provisioner: 48 | name: "ansible" 49 | inventory: 50 | hosts: 51 | all: 52 | vars: 53 | haproxy_ssl_dhparam_size: 512 54 | host_vars: 55 | haproxy_v3.2: 56 | haproxy_create_self_signed_cert: true 57 | haproxy_ppa_version: "ppa:vbernat/haproxy-3.2" 58 | haproxy_version: "3.2.*" 59 | haproxy_v3.0: 60 | haproxy_create_self_signed_cert: true 61 | haproxy_ppa_version: "ppa:vbernat/haproxy-3.0" 62 | haproxy_version: "3.0.*" 63 | haproxy_v2.8: 64 | haproxy_create_self_signed_cert: true 65 | haproxy_ppa_version: "ppa:vbernat/haproxy-2.8" 66 | haproxy_version: "2.8.*" 67 | haproxy_v2.6: 68 | haproxy_create_self_signed_cert: false 69 | haproxy_ssl_cert_chain_src_file_path: "{{ (lookup('env', 'MOLECULE_SCENARIO_DIRECTORY'), 'test.pem') | path_join }}" 70 | haproxy_ppa_version: "ppa:vbernat/haproxy-2.6" 71 | haproxy_version: "2.6.*" 72 | haproxy_v2.4: 73 | haproxy_create_self_signed_cert: true 74 | haproxy_ppa_version: "ppa:vbernat/haproxy-2.4" 75 | haproxy_version: "2.4.*" 76 | playbooks: 77 | prepare: "prepare.yml" 78 | check: "converge.yml" 79 | converge: "converge.yml" 80 | verify: "verify.yml" 81 | verifier: 82 | name: "ansible" 83 | scenario: 84 | name: "haproxy" 85 | test_sequence: 86 | - "destroy" 87 | - "dependency" 88 | - "syntax" 89 | - "create" 90 | - "prepare" 91 | - "check" 92 | - "converge" 93 | - "idempotence" 94 | - "check" 95 | - "side_effect" 96 | - "verify" 97 | - "destroy" 98 | 99 | ... 100 | -------------------------------------------------------------------------------- /molecule/haproxy/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Prepare" 8 | hosts: "all" 9 | tasks: 10 | - name: "Install dependencies" 11 | ansible.builtin.apt: 12 | name: 13 | - "sudo" # for `become` privilege escalation 14 | - "iproute2" # for gathering network facts 15 | - "gnupg2" # for use with "apt-key export" 16 | - "software-properties-common" # for use with "apt-repository" 17 | - "python3-debian" 18 | - "python3-cryptography" # for use with openssl modules 19 | - "python3-openssl" # for use to create p12 files 20 | update_cache: true 21 | state: "present" 22 | 23 | ... 24 | -------------------------------------------------------------------------------- /molecule/haproxy/test.pem.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | -------------------------------------------------------------------------------- /molecule/haproxy/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Verify HAProxy" 8 | hosts: "all" 9 | tasks: 10 | - name: "Stop play for unsupported HAProxy / Debian combinations" 11 | ansible.builtin.meta: "end_host" 12 | when: >- 13 | ansible_facts.distribution_release | lower == 'bookworm' and haproxy_version | regex_search('\\d+\\.\\d+') is version('2.4', '==') or 14 | ansible_facts.distribution_release | lower == 'bullseye' and haproxy_version | regex_search('\\d+\\.\\d+') is version('3.2', '>=') or 15 | ansible_facts.distribution_release | lower == 'buster' and haproxy_version | regex_search('\\d+\\.\\d+') is version('2.8', '>=') 16 | 17 | - name: "Stop play for unsupported HAProxy / Ubuntu combinations" 18 | ansible.builtin.meta: "end_host" 19 | when: >- 20 | ansible_facts.distribution_release | lower == 'noble' and haproxy_version | regex_search('\\d+\\.\\d+') is version('2.9', '<') or 21 | ansible_facts.distribution_release | lower != 'noble' and haproxy_version | regex_search('\\d+\\.\\d+') is version('3.2', '>=') 22 | 23 | - name: "Populate service facts." 24 | ansible.builtin.service_facts: 25 | register: "services_state" 26 | 27 | - name: "Check that HAProxy is running on instance." 28 | ansible.builtin.assert: 29 | that: 30 | - "services_state.ansible_facts.services['haproxy.service'].state is search('running')" 31 | fail_msg: "HAProxy need to be running on instance." 32 | success_msg: "HAProxy is running on instance." 33 | 34 | ... 35 | -------------------------------------------------------------------------------- /molecule/keepalived/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Converge" 9 | hosts: "all" 10 | tasks: 11 | - name: "Include keepalived role" 12 | ansible.builtin.include_role: 13 | name: "hifis.toolkit.keepalived" 14 | 15 | ... 16 | -------------------------------------------------------------------------------- /molecule/keepalived/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | dependency: 9 | name: "galaxy" 10 | driver: 11 | name: "podman" 12 | platforms: 13 | - name: "instancekeepalived" 14 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 15 | pre_build_image: true 16 | privileged: true 17 | systemd: "always" 18 | tty: true 19 | override_command: false 20 | provisioner: 21 | name: "ansible" 22 | config_options: 23 | defaults: 24 | result_format: "yaml" 25 | playbooks: 26 | prepare: "prepare.yml" 27 | check: "converge.yml" 28 | converge: "converge.yml" 29 | verify: "verify.yml" 30 | inventory: 31 | hosts: 32 | all: 33 | vars: 34 | keepalived_unicast_peers: 35 | - "172.17.0.3" 36 | - "172.17.0.4" 37 | keepalived_virtual_ip_address: "172.17.0.20" 38 | keepalived_notification_emails: 39 | - "root@localhost" 40 | - "sysadmin@firewall.loc" 41 | verifier: 42 | name: "ansible" 43 | scenario: 44 | name: "keepalived" 45 | test_sequence: 46 | - "destroy" 47 | - "dependency" 48 | - "syntax" 49 | - "create" 50 | - "prepare" 51 | - "check" 52 | - "converge" 53 | - "idempotence" 54 | - "check" 55 | - "side_effect" 56 | - "verify" 57 | - "destroy" 58 | 59 | ... 60 | -------------------------------------------------------------------------------- /molecule/keepalived/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Prepare" 9 | hosts: "all" 10 | tasks: 11 | - name: "Install dependencies" 12 | ansible.builtin.apt: 13 | name: 14 | - "sudo" # for `become` privilege escalation 15 | - "iproute2" # for gathering network facts 16 | - "psmisc" # provides `killall` command 17 | state: "present" 18 | update_cache: true 19 | 20 | ... 21 | -------------------------------------------------------------------------------- /molecule/keepalived/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Verify Keepalived" 9 | hosts: "all" 10 | tasks: 11 | - name: "Populate service facts." 12 | ansible.builtin.service_facts: 13 | register: "services_state" 14 | 15 | - name: "Check that Keepalived is running on instance." 16 | ansible.builtin.assert: 17 | that: 18 | - "services_state.ansible_facts.services['keepalived.service'].state is search('running')" 19 | fail_msg: "Keepalived need to be running on instance." 20 | success_msg: "Keepalived is running on instance." 21 | 22 | ... 23 | -------------------------------------------------------------------------------- /molecule/netplan/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | vars: 10 | netplan_ethernets: 11 | - interface_name: "eth0" 12 | dhcp4: "no" 13 | routes: 14 | - to: "default" 15 | via: "10.123.0.1" 16 | - to: "172.16.0.0/24" 17 | via: "10.123.0.100" 18 | addresses: 19 | - "10.123.0.10/24" 20 | nameservers: 21 | addresses: 22 | - "8.8.8.8" 23 | - "9.9.9.9" 24 | search: 25 | - "domain.local" 26 | - "domain.name" 27 | tasks: 28 | - name: "Include netplan_role" 29 | ansible.builtin.include_role: 30 | name: "hifis.toolkit.netplan" 31 | 32 | ... 33 | -------------------------------------------------------------------------------- /molecule/netplan/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | driver: 10 | name: "podman" 11 | platforms: 12 | - name: "instancenetplan" 13 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 14 | pre_build_image: true 15 | override_command: false 16 | privileged: true 17 | systemd: true 18 | tty: true 19 | extra_opts: 20 | - "--network=netplan_network" 21 | provisioner: 22 | name: "ansible" 23 | options: 24 | D: true 25 | playbooks: 26 | prepare: "prepare.yml" 27 | converge: "converge.yml" 28 | verify: "verify.yml" 29 | verifier: 30 | name: "ansible" 31 | 32 | ... 33 | -------------------------------------------------------------------------------- /molecule/netplan/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Prepare" 8 | hosts: "all" 9 | tasks: 10 | - name: "Install dependencies" 11 | ansible.builtin.apt: 12 | name: 13 | - "sudo" # for `become` privilege escalation 14 | - "iproute2" # for gathering network facts 15 | - "udev" # needed for netplan 16 | update_cache: true 17 | state: "present" 18 | 19 | - name: "Ensure systemd-udevd is started on Ubuntu 24.04" 20 | ansible.builtin.service: 21 | name: "systemd-udevd" 22 | state: "started" 23 | when: "ansible_facts.distribution_release | lower == 'noble'" 24 | ... 25 | -------------------------------------------------------------------------------- /molecule/netplan/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Verify" 8 | hosts: "all" 9 | gather_facts: true 10 | vars: 11 | netplan_ethernets: 12 | - interface_name: "eth0" 13 | dhcp4: "no" 14 | gateway4: "10.123.0.1" 15 | addresses: 16 | - "10.123.0.10/24" 17 | nameservers: 18 | addresses: 19 | - "8.8.8.8" 20 | - "9.9.9.9" 21 | search: 22 | - "domain.local" 23 | - "domain.name" 24 | tasks: 25 | - name: "Check network settings if no DHCP is set." 26 | when: "netplan_ethernets is defined and netplan_ethernets | length > 0 and netplan_ethernets[0]['dhcp4'] == 'no'" 27 | block: 28 | - name: "Store actual and target network settings." 29 | ansible.builtin.set_fact: 30 | actual_interface_name: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['interface'] }}" 31 | target_interface_name: "{{ netplan_ethernets[0]['interface_name'] }}" 32 | actual_ip_addresses: "{{ hostvars[inventory_hostname]['ansible_all_ipv4_addresses'] | ansible.utils.ipaddr('address') }}" 33 | target_ip_address: "{{ netplan_ethernets[0]['addresses'][0] | ansible.utils.ipaddr('address') }}" 34 | actual_subnet: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['netmask'] }}" 35 | target_subnet: "{{ netplan_ethernets[0]['addresses'][0] | ansible.utils.ipaddr('netmask') }}" 36 | 37 | - name: "Check that network settings are correct." 38 | ansible.builtin.assert: 39 | that: 40 | - "actual_ip_addresses | ansible.utils.ipaddr('bool')" 41 | - "target_ip_address | ansible.utils.ipaddr('bool')" 42 | - "actual_interface_name == target_interface_name" 43 | - "target_ip_address in actual_ip_addresses" 44 | - "actual_subnet == target_subnet" 45 | 46 | ... 47 | -------------------------------------------------------------------------------- /molecule/redis/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | tasks: 10 | - name: "Include redis_role" 11 | ansible.builtin.include_role: 12 | name: "hifis.toolkit.redis" 13 | 14 | ... 15 | -------------------------------------------------------------------------------- /molecule/redis/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | driver: 10 | name: "podman" 11 | platforms: 12 | - name: "instance_redis" 13 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 14 | pre_build_image: true 15 | privileged: true 16 | systemd: "always" 17 | tty: true 18 | override_command: false 19 | provisioner: 20 | name: "ansible" 21 | config_options: 22 | defaults: 23 | result_format: "yaml" 24 | playbooks: 25 | prepare: "prepare.yml" 26 | converge: "converge.yml" 27 | inventory: 28 | hosts: 29 | all: 30 | vars: 31 | redis_sentinel_password: "123456" 32 | verifier: 33 | name: "ansible" 34 | scenario: 35 | name: "redis" 36 | test_sequence: 37 | - "destroy" 38 | - "syntax" 39 | - "create" 40 | - "prepare" 41 | - "check" 42 | - "converge" 43 | - "idempotence" 44 | - "check" 45 | - "verify" 46 | - "destroy" 47 | 48 | ... 49 | -------------------------------------------------------------------------------- /molecule/redis/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Prepare" 8 | hosts: "all" 9 | tasks: 10 | - name: "Install dependencies" 11 | ansible.builtin.apt: 12 | name: 13 | - "ca-certificates" # for Redis download 14 | - "iproute2" # for gathering network facts 15 | - "net-tools" # for gathering listening ports 16 | - "python3-redis" # required by community.general.redis 17 | - "sudo" # for `become` privilege escalation 18 | update_cache: true 19 | state: "present" 20 | 21 | ... 22 | -------------------------------------------------------------------------------- /molecule/redis/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Verify" 8 | hosts: "all" 9 | vars: 10 | redis_server_service_name: "redis-server" 11 | redis_sentinel_service_name: "redis-sentinel" 12 | redis_server_port: 6379 13 | redis_sentinel_port: 26379 14 | redis_ports: 15 | - "{{ redis_server_port }}" 16 | - "{{ redis_sentinel_port }}" 17 | redis_password: "changeme" 18 | tasks: 19 | - name: "Populate service facts" 20 | ansible.builtin.service_facts: 21 | register: "services_state" 22 | 23 | - name: "Check that Redis is running on instance" 24 | ansible.builtin.assert: 25 | that: 26 | - "services_state.ansible_facts.services[redis_server_service_name + '.service'].state is search('running')" 27 | - "services_state.ansible_facts.services[redis_sentinel_service_name + '.service'].state is search('running')" 28 | 29 | - name: "Gather facts on listening ports." 30 | community.general.listen_ports_facts: 31 | 32 | - name: "Check if Redis is listening on TCP ports" 33 | vars: 34 | tcp_listen: "{{ ansible_facts.tcp_listen | selectattr('port', 'in', redis_ports) | list }}" 35 | ansible.builtin.assert: 36 | that: 37 | - "item.name == redis_server_service_name" 38 | loop: "{{ tcp_listen }}" 39 | 40 | - name: "Ensure Redis is in master mode" 41 | community.general.redis: 42 | command: "slave" 43 | slave_mode: "master" 44 | login_password: "{{ redis_password }}" 45 | 46 | - name: "Configure Redis maxmemory" 47 | community.general.redis: 48 | command: "config" 49 | name: "maxmemory" 50 | value: "0" 51 | login_password: "{{ redis_password }}" 52 | 53 | ... 54 | -------------------------------------------------------------------------------- /molecule/ssh_keys/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | vars: 10 | ssh_user_list: 11 | - name: "dummyuser" 12 | authorized_keys: 13 | - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJi3wBlOT+oR8Rd+YQsV8tUoQOd3NSUuyzJYQp8finD6 john@example.com" 14 | create_user_account: true 15 | - name: "root" 16 | authorized_keys: 17 | - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJi3wBlOT+oR8Rd+YQsV8tUoQOd3NSUuyzJYQp8finD6 john@example.com" 18 | - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDXkvy8jMmw45grnmYK+Ylk/mcc7IyG9taNseNiVrGjR8KRHVJpzEntW1g6SAomIGIpBLvviiyhal4E1v1bhpv2JopbiM3JDOck6gwc4AfpanjuZFPuq6stq5pF7bb2C+zliw16zTFL7bp09tD7nNs30GlchB5DU2sSn1zq4iC+eQ== john@example.com" # noqa 204 19 | tasks: 20 | - name: "Include ssh_keys role" 21 | ansible.builtin.include_role: 22 | name: "hifis.toolkit.ssh_keys" 23 | -------------------------------------------------------------------------------- /molecule/ssh_keys/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | options: 10 | requirements-file: "molecule/ssh_keys/requirements.yml" 11 | driver: 12 | name: "podman" 13 | platforms: 14 | - name: "instance" 15 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 16 | pre_build_image: true 17 | privileged: true 18 | override_command: false 19 | systemd: true 20 | tty: true 21 | provisioner: 22 | name: "ansible" 23 | verifier: 24 | name: "ansible" 25 | scenario: 26 | name: "ssh_keys" 27 | test_sequence: 28 | - "destroy" 29 | - "dependency" 30 | - "syntax" 31 | - "create" 32 | - "prepare" 33 | - "check" 34 | - "converge" 35 | - "idempotence" 36 | - "check" 37 | - "side_effect" 38 | - "verify" 39 | - "destroy" 40 | -------------------------------------------------------------------------------- /molecule/ssh_keys/requirements.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | collections: 9 | - name: "ansible.posix" 10 | -------------------------------------------------------------------------------- /molecule/ssh_keys/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Verify" 8 | hosts: "all" 9 | tasks: 10 | - name: "Ensure ssh dummy user is present" 11 | ansible.builtin.user: 12 | name: "dummyuser" 13 | state: "present" 14 | register: "dummyuser" 15 | failed_when: "dummyuser.changed" 16 | 17 | - name: "Ensure ssh key for newly created user is present" 18 | ansible.builtin.lineinfile: 19 | path: "/home/dummyuser/.ssh/authorized_keys" 20 | regexp: '^{{ ssh_public_key }}(.*)$' 21 | line: '{{ ssh_public_key }}\1' 22 | state: "present" 23 | backrefs: true 24 | check_mode: true 25 | register: "line_in_file" 26 | failed_when: "(line_in_file.changed) or (line_in_file.failed)" 27 | vars: 28 | ssh_public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJi3wBlOT+oR8Rd+YQsV8tUoQOd3NSUuyzJYQp8finD6 john@example.com" 29 | 30 | - name: "Ensure ssh key for existing user is present" 31 | ansible.builtin.lineinfile: 32 | path: "/root/.ssh/authorized_keys" 33 | regexp: '^{{ item }}(.*)$' 34 | line: '{{ item }}\1' 35 | state: "present" 36 | backrefs: true 37 | check_mode: true 38 | register: "line_in_file" 39 | failed_when: "(line_in_file.changed) or (line_in_file.failed)" 40 | loop: 41 | - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJi3wBlOT+oR8Rd+YQsV8tUoQOd3NSUuyzJYQp8finD6 john@example.com" 42 | - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDXkvy8jMmw45grnmYK+Ylk/mcc7IyG9taNseNiVrGjR8KRHVJpzEntW1g6SAomIGIpBLvviiyhal4E1v1bhpv2JopbiM3JDOck6gwc4AfpanjuZFPuq6stq5pF7bb2C+zliw16zTFL7bp09tD7nNs30GlchB5DU2sSn1zq4iC+eQ== john@example.com" # noqa 204 43 | -------------------------------------------------------------------------------- /molecule/unattended_upgrades/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | # Play to create and provision instance. 8 | - name: "Converge" 9 | hosts: "all" 10 | tasks: 11 | - name: "Include unattended_upgrades role" 12 | ansible.builtin.include_role: 13 | name: "hifis.toolkit.unattended_upgrades" 14 | 15 | ... 16 | -------------------------------------------------------------------------------- /molecule/unattended_upgrades/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | driver: 10 | name: "podman" 11 | platforms: 12 | - name: "instance1" 13 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 14 | pre_build_image: true 15 | privileged: true 16 | override_command: false 17 | systemd: true 18 | tty: true 19 | - name: "instance2" 20 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 21 | pre_build_image: true 22 | privileged: true 23 | override_command: false 24 | systemd: true 25 | tty: true 26 | provisioner: 27 | name: "ansible" 28 | options: 29 | diff: true 30 | inventory: 31 | hosts: 32 | all: 33 | vars: 34 | ubuntu_defaults: 35 | - 'Unattended-Upgrade::Allowed-Origins:: "${distro_id}:${distro_codename}";' 36 | - 'Unattended-Upgrade::Allowed-Origins:: "${distro_id}:${distro_codename}-security";' 37 | - 'Unattended-Upgrade::Allowed-Origins:: "${distro_id}ESMApps:${distro_codename}-apps-security";' 38 | - 'Unattended-Upgrade::Allowed-Origins:: "${distro_id}ESM:${distro_codename}-infra-security";' 39 | debian_defaults: 40 | - 'Unattended-Upgrade::Origins-Pattern:: "origin=Debian,codename=${distro_codename},label=Debian";' 41 | host_vars: 42 | instance1: 43 | unattended_systemd_timer_override: false 44 | unattended_autofix_interrupted_dpkg: false 45 | unattended_minimal_steps: true 46 | unattended_install_on_shutdown: true 47 | unattended_automatic_reboot: true 48 | unattended_update_days: '{"Sat"}' 49 | unattended_remove_unused_kernel_packages: true 50 | unattended_only_on_ac_power: true 51 | unattended_mail_sender: "jane@example.org" 52 | instance2: 53 | unattended_systemd_timer_override: true 54 | unattended_apt_daily_oncalendar: "*-*-* 11:08" 55 | unattended_apt_daily_randomizeddelaysec: "0s" 56 | unattended_apt_daily_upgrade_oncalendar: "*-*-* 11:31" 57 | unattended_apt_daily_upgrade_randomizeddelaysec: "0s" 58 | playbooks: 59 | prepare: "prepare.yml" 60 | check: "converge.yml" 61 | converge: "converge.yml" 62 | verify: "verify.yml" 63 | verifier: 64 | name: "ansible" 65 | scenario: 66 | test_sequence: 67 | - "destroy" 68 | - "dependency" 69 | - "syntax" 70 | - "create" 71 | - "prepare" 72 | - "check" 73 | - "converge" 74 | - "idempotence" 75 | - "check" 76 | - "side_effect" 77 | - "verify" 78 | - "destroy" 79 | 80 | ... 81 | -------------------------------------------------------------------------------- /molecule/unattended_upgrades/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | # Play to install dependencies. 8 | - name: "Prepare" 9 | hosts: "all" 10 | tasks: 11 | - name: "Install dependencies" 12 | ansible.builtin.apt: 13 | update_cache: "yes" 14 | force_apt_get: "yes" 15 | 16 | ... 17 | -------------------------------------------------------------------------------- /molecule/unattended_upgrades/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Verify unattended upgrades installation" 8 | hosts: "all" 9 | tasks: 10 | - name: "Get apt-config variables" 11 | ansible.builtin.command: "apt-config dump" 12 | register: "aptconfig" 13 | changed_when: false 14 | 15 | - name: "Check for registered variables" 16 | when: "not unattended_systemd_timer_override" 17 | ansible.builtin.assert: 18 | that: "item in aptconfig.stdout" 19 | with_items: 20 | - 'APT::Periodic::Unattended-Upgrade "1"' 21 | - 'Unattended-Upgrade::Origins-Pattern "";' 22 | - 'Unattended-Upgrade::AutoFixInterruptedDpkg "false"' 23 | - 'Unattended-Upgrade::MinimalSteps "true"' 24 | - 'Unattended-Upgrade::InstallOnShutdown "true"' 25 | - 'Unattended-Upgrade::Automatic-Reboot "true"' 26 | # NOTE: this uses the array syntax, which requires one 27 | # top-level record, then one item per line 28 | - 'Unattended-Upgrade::Update-Days "";' 29 | - 'Unattended-Upgrade::Update-Days:: "Sat";' 30 | - 'Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";' 31 | - 'Unattended-Upgrade::OnlyOnACPower "true";' 32 | - 'Unattended-Upgrade::Sender "jane@example.org"' 33 | 34 | - name: "Ubuntu specific verification" 35 | when: "ansible_facts.distribution == 'Ubuntu'" 36 | block: 37 | - name: "Check for registered variables on Ubuntu" 38 | ansible.builtin.assert: 39 | that: "item in aptconfig.stdout" 40 | with_items: 41 | - 'Unattended-Upgrade::Origins-Pattern:: "origin=Ubuntu,archive=${distro_codename}-security,label=Ubuntu";' 42 | 43 | - name: "Check absence of Ubuntu defaults" 44 | ansible.builtin.assert: 45 | that: "item not in aptconfig.stdout" 46 | with_items: "{{ ubuntu_defaults }}" 47 | 48 | - name: "Debian specific verification" 49 | when: "ansible_facts.distribution == 'Debian'" 50 | block: 51 | - name: "Check for registered variables on Debian" 52 | ansible.builtin.assert: 53 | that: "item in aptconfig.stdout" 54 | with_items: 55 | - 'Unattended-Upgrade::Origins-Pattern:: "origin=Debian,codename=${distro_codename},label=Debian-Security";' 56 | 57 | - name: "Check absence of Debian defaults" 58 | ansible.builtin.assert: 59 | that: "item not in aptconfig.stdout" 60 | with_items: "{{ debian_defaults }}" 61 | 62 | - name: "Dry run unattended-upgrades" 63 | ansible.builtin.command: "/usr/bin/unattended-upgrades --dry-run" 64 | register: "dry_run" 65 | failed_when: "dry_run.rc != 0" 66 | changed_when: false 67 | 68 | - name: "Verify custom apt-daily timers" # noqa command-instead-of-shell 69 | when: "unattended_systemd_timer_override" 70 | ansible.builtin.shell: 71 | cmd: "{{ item }}" 72 | changed_when: false 73 | loop: 74 | - 'systemctl list-timers apt-daily* | grep apt-daily.service | grep "11:08:00"' 75 | - 'systemctl list-timers apt-daily* | grep apt-daily-upgrade.service | grep "11:31:00"' 76 | 77 | ... 78 | -------------------------------------------------------------------------------- /molecule/zammad/converge.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | - name: "Converge" 8 | hosts: "all" 9 | tasks: 10 | 11 | - name: "Get private key content" 12 | ansible.builtin.command: "cat /etc/ssl/private/ssl-cert-snakeoil.key" 13 | changed_when: false 14 | check_mode: false 15 | register: "private_key" 16 | 17 | - name: "Get SSL certificate content" 18 | ansible.builtin.command: "cat /etc/ssl/certs/ssl-cert-snakeoil.pem" 19 | changed_when: false 20 | check_mode: false 21 | register: "certificate" 22 | 23 | - name: "Pass SSL key pair to zammad role" 24 | ansible.builtin.set_fact: 25 | zammad_ssl_key: "{{ private_key.stdout }}" 26 | zammad_ssl_cert: "{{ certificate.stdout }}" 27 | 28 | - name: "Include ansible-role-zammad" 29 | ansible.builtin.include_role: 30 | name: "hifis.toolkit.zammad" 31 | -------------------------------------------------------------------------------- /molecule/zammad/molecule.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | dependency: 8 | name: "galaxy" 9 | options: 10 | requirements-file: "molecule/zammad/requirements.yml" 11 | driver: 12 | name: "podman" 13 | platforms: 14 | - name: "instance" 15 | image: "${MOLECULE_IMAGE:-ghcr.io/hifis-net/ubuntu-systemd:24.04}" 16 | pre_build_image: true 17 | privileged: true 18 | override_command: false 19 | systemd: true 20 | tty: true 21 | published_ports: 22 | - "0.0.0.0:8080:80" 23 | - "0.0.0.0:8443:443" 24 | provisioner: 25 | name: "ansible" 26 | playbooks: 27 | prepare: "prepare.yml" 28 | converge: "converge.yml" 29 | verifier: 30 | name: "ansible" 31 | -------------------------------------------------------------------------------- /molecule/zammad/prepare.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | - name: "Prepare" 8 | hosts: "all" 9 | vars: 10 | # Apply suggested Elasticsearch configuration 11 | elasticsearch_version: "8.x" 12 | elasticsearch_package: "elasticsearch=8.8.1" 13 | elasticsearch_heap_size_min: "256m" 14 | elasticsearch_heap_size_max: "256m" 15 | elasticsearch_extra_options: | 16 | xpack.security.enabled: false 17 | xpack.security.http.ssl.enabled: false 18 | xpack.security.transport.ssl.enabled: false 19 | http.max_content_length: 400mb 20 | indices.query.bool.max_clause_count: 2000 21 | 22 | tasks: 23 | 24 | - name: "Install required packages" 25 | ansible.builtin.apt: 26 | name: 27 | - "sudo" 28 | - "gpg" 29 | - "ca-certificates" 30 | - "python3-cryptography" 31 | - "python3-debian" 32 | - "ssl-cert" 33 | state: "present" 34 | update_cache: true 35 | 36 | - name: "Include geerlingguy.elasticsearch" 37 | ansible.builtin.include_role: 38 | name: "geerlingguy.elasticsearch" 39 | 40 | - name: "Include geerlingguy.postgresql" 41 | ansible.builtin.include_role: 42 | name: "geerlingguy.postgresql" 43 | -------------------------------------------------------------------------------- /molecule/zammad/requirements.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | 8 | collections: 9 | - name: "community.crypto" 10 | version: "2.20.0" 11 | 12 | roles: 13 | - src: "geerlingguy.elasticsearch" 14 | version: "5.1.2" 15 | 16 | - src: "geerlingguy.postgresql" 17 | version: "3.5.2" 18 | -------------------------------------------------------------------------------- /molecule/zammad/verify.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | - name: "Verify" 8 | hosts: "all" 9 | tasks: 10 | - name: "Check that Zammad web interface is available" 11 | ansible.builtin.uri: 12 | url: "https://localhost" 13 | validate_certs: false 14 | return_content: true 15 | register: "zammad_web" 16 | failed_when: "'Zammad Helpdesk' not in zammad_web.content" 17 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | [project] 7 | name = "ansible-collection-toolkit" 8 | version = "5.3.0" 9 | description = "This collection provides production-ready Ansible roles used for providing services used in research and by research software engineers, but not exclusively." 10 | readme = "README.md" 11 | requires-python = ">=3.11" 12 | dependencies = [ 13 | "ansible>=11.3.0", 14 | ] 15 | 16 | [dependency-groups] 17 | dev = [ 18 | "ansible-lint>=25.1.3", 19 | "molecule>=25.3.1", 20 | "molecule-plugins[podman]>=23.7.0", 21 | "netaddr>=1.3.0", 22 | "reuse>=5.0.2", 23 | "yamllint>=1.35.1", 24 | ] 25 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | collections: 9 | - name: "ansible.posix" 10 | - name: "community.crypto" 11 | - name: "community.general" 12 | 13 | roles: 14 | - name: "geerlingguy.docker" 15 | -------------------------------------------------------------------------------- /roles/gitlab/.ansible-lint: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: 2020 Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | skip_list: 9 | - '503' 10 | 11 | ... 12 | -------------------------------------------------------------------------------- /roles/gitlab/GITLAB_BASE_HISTORY.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # Changelog gitlab-base role 9 | 10 | **Attention:** The gitlab-base role has been migrated to this gitlab role. 11 | 12 | Please find information on any changes made in this [CHANGELOG](CHANGELOG.md) file. 13 | 14 | ## [0.3.1](https://gitlab.com/hifis/ansible/gitlab-base-role/-/releases/v0.3.1) - 2021-02-22 15 | 16 | [List of commits](https://gitlab.com/hifis/ansible/gitlab-base-role/-/compare/v0.3.0...v0.3.1) 17 | 18 | ### Fixed 19 | - Check that command gitlab-rails exists before executing it 20 | ([!15](https://gitlab.com/hifis/ansible/gitlab-base-role/-/merge_requests/15) 21 | by [christian.hueser.hzdr](https://gitlab.com/christian.hueser.hzdr)). 22 | 23 | ## [0.3.0](https://gitlab.com/hifis/ansible/gitlab-base-role/-/releases/v0.3.0) - 2021-02-02 24 | 25 | [List of commits](https://gitlab.com/hifis/ansible/gitlab-base-role/-/compare/v0.2.1...v0.3.0) 26 | 27 | ### Changed 28 | - Improve and speed up the CI pipeline 29 | ([!9](https://gitlab.com/hifis/ansible/gitlab-base-role/-/merge_requests/9) 30 | by [tobiashuste](https://gitlab.com/tobiashuste)). 31 | 32 | ### Fixed 33 | - Check for background migrations before updating GitLab 34 | ([!13](https://gitlab.com/hifis/ansible/gitlab-base-role/-/merge_requests/13) 35 | by [christian.hueser.hzdr](https://gitlab.com/christian.hueser.hzdr)). 36 | 37 | ## [0.2.1](https://gitlab.com/hifis/ansible/gitlab-base-role/-/releases/v0.2.1) - 2020-09-10 38 | 39 | [List of commits](https://gitlab.com/hifis/ansible/gitlab-base-role/-/compare/v0.2.0...v0.2.1) 40 | 41 | ### Fixed 42 | - Add trigger for handler 'GitLab reconfigure' if GitLab upgrade has been performed 43 | ([!8](https://gitlab.com/hifis/ansible/gitlab-base-role/-/merge_requests/8) 44 | by [christian.hueser.hzdr](https://gitlab.com/christian.hueser.hzdr)). 45 | 46 | ## [0.2.0](https://gitlab.com/hifis/ansible/gitlab-base-role/-/releases/v0.2.0) - 2020-09-08 47 | 48 | [List of commits](https://gitlab.com/hifis/ansible/gitlab-base-role/-/compare/v0.1.0...v0.2.0) 49 | 50 | ### Added 51 | - Set Ansible fact that GitLab is upgraded during provisioning 52 | ([!6](https://gitlab.com/hifis/ansible/gitlab-base-role/-/merge_requests/6) 53 | by [christian.hueser.hzdr](https://gitlab.com/christian.hueser.hzdr)). 54 | 55 | ## [0.1.0](https://gitlab.com/hifis/ansible/gitlab-base-role/-/releases/v0.1.0) - 2020-08-20 56 | 57 | ### Added 58 | 59 | Initial release of the Ansible GitLab Base Role. 60 | -------------------------------------------------------------------------------- /roles/gitlab/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | gitlab_edition: "gitlab-ee" 9 | gitlab_version: "" 10 | gitlab_release: "" 11 | gitlab_gpg_key_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/gpgkey" 12 | gitlab_gpg_key_id: "F6403F6544A38863DAA0B6E03F01618A51312F3F" 13 | 14 | # Do not display sensitive changes in diffs by default 15 | gitlab_hide_sensitive_changes: true 16 | 17 | # Specify whether this is the GitLab primary node 18 | gitlab_is_primary: false 19 | 20 | # Name ot the GitLab configuration template 21 | gitlab_configuration_file_template: "gitlab.rb.j2" 22 | # Path to the GitLab configuration file 23 | gitlab_configuration_file_path: "/etc/gitlab/gitlab.rb" 24 | 25 | # URL of the GitLab application 26 | gitlab_external_url: "http://localhost" 27 | # GitLab Theme to use 28 | gitlab_default_theme: "2" 29 | # Time Zone to set 30 | gitlab_time_zone: "Europe/Berlin" 31 | # Keep backups for a week 32 | gitlab_backup_keep_time: "604800" 33 | # Backup directory 34 | gitlab_backup_path: "/var/opt/gitlab/backups" 35 | # Port for web-requests 36 | gitlab_nginx_listen_port: "80" 37 | # Whether to use https 38 | gitlab_nginx_listen_https: "false" 39 | # Whether to redirect to https 40 | gitlab_nginx_redirect_http_to_https: "false" 41 | 42 | # Whether to use GitLab Omnibus internal Redis 43 | gitlab_use_internal_redis: "true" 44 | # Password for authentication 45 | gitlab_redis_password: "changeme" 46 | # Name of the Redis cluster 47 | gitlab_redis_cluster_name: "redis-cluster" 48 | # List of IP addresses of Redis Sentinel instances 49 | gitlab_redis_sentinel_ips: [] 50 | # Port on which Redis Sentinel instances are listening 51 | gitlab_redis_sentinel_port: "26379" 52 | # GitLap IP address range 53 | gitlab_ip_range: "{{ ansible_facts.default_ipv4.address }}/24" 54 | 55 | # Whether to use GitLab Omnibus internal Gitaly 56 | gitlab_use_internal_gitaly: "true" 57 | # Data directory to use 58 | gitlab_git_data_dir: "/var/opt/gitlab/git-data" 59 | # Gitaly token 60 | gitlab_gitaly_token: "changeme" 61 | # GitLab Shell token 62 | gitlab_secret_token: "changeme" 63 | # IP address of the Gitaly instance 64 | gitlab_gitaly_instance_ip: "127.0.0.1" 65 | # Port of the Gitaly instance 66 | gitlab_gitaly_instance_port: "8075" 67 | # Set to false to define gitlab_rails['repositories_storages'] on your own 68 | gitlab_use_default_repositories_storages: true 69 | 70 | # Whether to use GitLab Omnibus internal PostgreSQL database 71 | gitlab_use_internal_postgresql: "true" 72 | # External PostgreSQL database host IP / domain 73 | gitlab_postgresql_db_host: "127.0.0.1" 74 | # External PostgreSQL database port 75 | gitlab_postgresql_db_port: 5432 76 | # External PostgreSQL database password 77 | gitlab_postgresql_db_password: "changeme" 78 | 79 | # Whether to enable email 80 | gitlab_email_enabled: "false" 81 | # Whether to enable LDAP 82 | gitlab_ldap_enabled: "false" 83 | # Whether to enable SMTP 84 | gitlab_smtp_enable: "false" 85 | 86 | # Registry configuration 87 | # Whether to enable GitLab Registry 88 | gitlab_registry_enable: "false" 89 | # External URL for the container registry 90 | gitlab_registry_external_url: "http://localhost:5005" 91 | 92 | # Mattermost configuration 93 | # Whether GitLab Omnibus is used to run Mattermost only without GitLab 94 | gitlab_mattermost_only_context: "false" 95 | 96 | gitlab_feature_flags: [] 97 | 98 | # Internal variable to determine whether the configuration object for Gitaly 99 | # is already present in gitlab_additional_configurations 100 | __gitaly_configuration_exists: false 101 | ... 102 | -------------------------------------------------------------------------------- /roles/gitlab/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "GitLab has been installed or upgraded" 9 | become: true 10 | ansible.builtin.set_fact: 11 | gitlab_is_upgraded: true 12 | 13 | - name: "Reconfigure Primary GitLab" 14 | become: true 15 | ansible.builtin.shell: 16 | cmd: "gitlab-ctl reconfigure || (touch /etc/gitlab/reconfigure_failed && /bin/false)" 17 | changed_when: true 18 | environment: 19 | SKIP_POST_DEPLOYMENT_MIGRATIONS: true 20 | listen: "GitLab has been installed or upgraded" 21 | when: "gitlab_is_primary" 22 | 23 | - name: "Reconfigure Non Primary GitLab" 24 | become: true 25 | ansible.builtin.shell: 26 | cmd: "gitlab-ctl reconfigure || (touch /etc/gitlab/reconfigure_failed && /bin/false)" 27 | changed_when: true 28 | listen: "GitLab has been installed or upgraded" 29 | when: "not gitlab_is_primary" 30 | 31 | - name: "Restart GitLab" 32 | become: true 33 | ansible.builtin.command: "gitlab-ctl restart" 34 | changed_when: true 35 | register: "gitlab_restart" 36 | 37 | - name: "Send SIGHUP to puma worker" 38 | become: true 39 | ansible.builtin.command: "gitlab-ctl hup puma" 40 | changed_when: true 41 | listen: "GitLab has been installed or upgraded" 42 | when: "not gitlab_mattermost_only_context" 43 | 44 | - name: "Restart sidekiq" 45 | become: true 46 | ansible.builtin.command: "gitlab-ctl restart sidekiq" 47 | changed_when: true 48 | listen: "GitLab has been installed or upgraded" 49 | when: "not gitlab_mattermost_only_context" 50 | 51 | ... 52 | -------------------------------------------------------------------------------- /roles/gitlab/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | galaxy_info: 8 | role_name: "gitlab" 9 | namespace: "hifis" 10 | author: "HIFIS Software Team" 11 | description: "Install and configure official GitLab Omnibus package" 12 | company: "Helmholtz Association" 13 | 14 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 15 | 16 | license: "Apache-2.0" 17 | 18 | min_ansible_version: "2.17" 19 | 20 | platforms: 21 | - name: "Ubuntu" 22 | versions: 23 | - "jammy" 24 | - "noble" 25 | - name: "Debian" 26 | versions: 27 | - "bullseye" 28 | 29 | galaxy_tags: 30 | - "git" 31 | - "gitlab" 32 | - "omnibus" 33 | 34 | dependencies: [] 35 | 36 | ... 37 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/configure.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Copy gitlab-secrets.json" 9 | ansible.builtin.copy: 10 | src: "{{ gitlab_secrets_file }}" 11 | dest: "/etc/gitlab/gitlab-secrets.json" 12 | owner: "root" 13 | group: "root" 14 | mode: "0600" 15 | backup: true 16 | when: "gitlab_secrets_file is defined" 17 | no_log: "{{ gitlab_hide_sensitive_changes }}" 18 | notify: 19 | - "Reconfigure Primary GitLab" 20 | - "Reconfigure Non Primary GitLab" 21 | 22 | - name: "Ensure gitaly['configuration'] is not present in gitlab_additional_configurations" 23 | when: "gitlab_use_internal_gitaly" 24 | block: 25 | - name: "Check if gitaly is present" 26 | when: 27 | - "gitlab_additional_configurations | length > 0" 28 | - "item.gitaly is defined" 29 | ansible.builtin.set_fact: 30 | __gitaly_item: "{{ item.gitaly }}" 31 | with_items: "{{ gitlab_additional_configurations }}" 32 | 33 | - name: "Check if gitaly['configuration'] is present" 34 | when: 35 | - "item.key is defined" 36 | - "item.key == 'configuration'" 37 | ansible.builtin.set_fact: 38 | __gitaly_configuration_exists: true 39 | with_items: "{{ __gitaly_item | default([]) }}" 40 | 41 | - name: "Warn if gitaly['configuration'] is already present" 42 | when: 43 | - "__gitaly_configuration_exists" 44 | ansible.builtin.debug: 45 | msg: "Please make sure to configure gitaly storage paths yourself in gitaly['configuration']" 46 | 47 | - name: "Copy GitLab Configuration File." 48 | become: true 49 | ansible.builtin.template: 50 | src: "{{ gitlab_configuration_file_template }}" 51 | dest: "{{ gitlab_configuration_file_path }}" 52 | owner: "root" 53 | group: "root" 54 | mode: "0644" 55 | no_log: "{{ gitlab_hide_sensitive_changes }}" 56 | notify: 57 | - "Reconfigure Primary GitLab" 58 | - "Reconfigure Non Primary GitLab" 59 | 60 | - name: "Create file to prevent Gitlab to restart before migrations" 61 | ansible.builtin.copy: 62 | content: "" 63 | dest: "/etc/gitlab/skip-auto-reconfigure" 64 | force: false 65 | owner: "root" 66 | group: "root" 67 | mode: "0644" 68 | when: "gitlab_is_primary" 69 | 70 | - name: "Create file to prevent Gitlab to backup database" 71 | ansible.builtin.copy: 72 | content: "" 73 | dest: "/etc/gitlab/skip-auto-backup" 74 | force: false 75 | owner: "root" 76 | group: "root" 77 | mode: "0644" 78 | when: "not gitlab_is_primary" 79 | 80 | ... 81 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/feature-flag.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Check if feature flag is already enabled for {{ gitlab_feature_flag.name }}" 9 | ansible.builtin.command: 10 | cmd: "gitlab-rails runner 'is_feature_enabled = Feature.enabled?(:{{ gitlab_feature_flag.name }}); puts is_feature_enabled'" 11 | register: "gitlab_is_feature_enabled" 12 | changed_when: false 13 | 14 | - name: "Enable or disable feature flag {{ gitlab_feature_flag.name }}" 15 | ansible.builtin.command: 16 | cmd: "gitlab-rails runner 'Feature.{{ 'enable' if gitlab_feature_flag.enabled else 'disable' }}(:{{ gitlab_feature_flag.name }})'" 17 | changed_when: true 18 | when: "(gitlab_is_feature_enabled.stdout == 'true' and not gitlab_feature_flag.enabled) or (gitlab_is_feature_enabled.stdout == 'false' and gitlab_feature_flag.enabled)" 19 | 20 | ... 21 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Set OS distribution dependent variables" 9 | ansible.builtin.include_vars: "{{ ansible_facts.distribution }}.yml" 10 | 11 | - name: "Check whether gitlab-rails binary is installed" 12 | ansible.builtin.stat: 13 | path: "/usr/bin/gitlab-rails" 14 | register: "gitlab_rails_binary" 15 | 16 | - name: "Determine if this is an initial dry-run" 17 | ansible.builtin.set_fact: 18 | gitlab_is_initial_dryrun: "{{ ansible_check_mode and not gitlab_rails_binary.stat.exists }}" 19 | 20 | - name: "Check if a previous reconfigure had failed" 21 | ansible.builtin.stat: 22 | path: "/etc/gitlab/reconfigure_failed" 23 | register: "gitlab_reconfigure_failed" 24 | 25 | - name: "Reconfigure GitLab" 26 | ansible.builtin.import_tasks: "reconfigure.yml" 27 | become: true 28 | when: "gitlab_reconfigure_failed.stat.exists" 29 | 30 | - name: "Install GitLab" 31 | ansible.builtin.import_tasks: "install.yml" 32 | become: true 33 | 34 | - name: "Configure GitLab" 35 | ansible.builtin.import_tasks: "configure.yml" 36 | become: true 37 | 38 | - name: "Check if GitLab is already configured" 39 | ansible.builtin.stat: 40 | path: "/opt/gitlab/etc/gitlab-rails-rc" 41 | register: "gitlab_rails_rc" 42 | 43 | - name: "Force all notified handlers to run at this point. Required for feature flags." 44 | ansible.builtin.meta: "flush_handlers" 45 | when: "not gitlab_rails_rc.stat.exists and gitlab_feature_flags | length > 0" 46 | 47 | - name: "Set feature flags" 48 | ansible.builtin.include_tasks: "feature-flag.yml" 49 | loop: "{{ gitlab_feature_flags }}" 50 | loop_control: 51 | loop_var: "gitlab_feature_flag" 52 | 53 | ... 54 | -------------------------------------------------------------------------------- /roles/gitlab/tasks/reconfigure.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Reconfigure Primary GitLab" 9 | become: true 10 | ansible.builtin.command: "gitlab-ctl reconfigure" 11 | changed_when: true 12 | environment: 13 | SKIP_POST_DEPLOYMENT_MIGRATIONS: "true" 14 | when: 15 | - "gitlab_is_primary" 16 | 17 | - name: "Reconfigure Non Primary GitLab" 18 | become: true 19 | ansible.builtin.command: "gitlab-ctl reconfigure" 20 | changed_when: true 21 | when: 22 | - "not gitlab_is_primary" 23 | 24 | - name: "Remove file that indicates a failed reconfigure" 25 | ansible.builtin.file: 26 | path: "/etc/gitlab/reconfigure_failed" 27 | state: "absent" 28 | 29 | ... 30 | -------------------------------------------------------------------------------- /roles/gitlab/templates/gitlab.rb.j2: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: 2020 Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | external_url "{{ gitlab_external_url }}" 7 | 8 | gitlab_rails['gitlab_default_theme'] = "{{ gitlab_default_theme }}" 9 | gitlab_rails['time_zone'] = "{{ gitlab_time_zone }}" 10 | gitlab_rails['backup_keep_time'] = "{{ gitlab_backup_keep_time }}" 11 | gitlab_rails['backup_path'] = "{{ gitlab_backup_path }}" 12 | 13 | nginx['listen_port'] = "{{ gitlab_nginx_listen_port }}" 14 | nginx['listen_https'] = {{ gitlab_nginx_listen_https }} 15 | nginx['redirect_http_to_https'] = {{ gitlab_nginx_redirect_http_to_https }} 16 | 17 | {% if not gitlab_use_internal_redis %} 18 | redis['enable'] = false 19 | gitlab_rails['redis_password'] = "{{ gitlab_redis_password }}" 20 | redis['master_name'] = "{{ gitlab_redis_cluster_name }}" 21 | redis['master_password'] = "{{ gitlab_redis_password }}" 22 | gitlab_rails['redis_sentinels'] = [ 23 | {% for redis_sentinel_ip in gitlab_redis_sentinel_ips %} 24 | { "host" => "{{ redis_sentinel_ip }}", "port" => "{{ gitlab_redis_sentinel_port }}" }, 25 | {% endfor %} 26 | ] 27 | {% if gitlab_redis_sentinel_password | default('') | length %} 28 | gitlab_rails['redis_sentinels_password'] = "{{ gitlab_redis_sentinel_password }}" 29 | {% endif %} 30 | {% endif %} 31 | gitlab_rails['monitoring_whitelist'] = ["{{ gitlab_ip_range }}"] 32 | 33 | {% if gitlab_use_internal_gitaly %} 34 | {% if not __gitaly_configuration_exists %} 35 | gitaly['configuration'] = { 36 | "storage": [ 37 | { 38 | "name": "default", 39 | "path": "{{ (gitlab_git_data_dir, 'repositories') | path_join }}", 40 | }, 41 | ], 42 | } 43 | {% endif %} 44 | {% else %} 45 | gitaly['enable'] = false 46 | gitlab_rails['gitaly_token'] = "{{ gitlab_gitaly_token }}" 47 | gitlab_shell['secret_token'] = "{{ gitlab_secret_token }}" 48 | {% if gitlab_use_default_repositories_storages %} 49 | gitlab_rails['repositories_storages'] = { 50 | "default" => { 51 | "gitaly_address" => "tcp://{{ gitlab_gitaly_instance_ip }}:{{ gitlab_gitaly_instance_port }}" 52 | } 53 | } 54 | {% endif %} 55 | {% endif %} 56 | 57 | gitlab_rails['gitlab_email_enabled'] = {{ gitlab_email_enabled }} 58 | gitlab_rails['ldap_enabled'] = {{ gitlab_ldap_enabled }} 59 | gitlab_rails['smtp_enable'] = {{ gitlab_smtp_enable }} 60 | 61 | registry['enable'] = {{ gitlab_registry_enable }} 62 | 63 | {% if not gitlab_use_internal_postgresql %} 64 | # Disable the bundled Omnibus provided PostgreSQL 65 | postgresql['enable'] = false 66 | # PostgreSQL connection details 67 | gitlab_rails['db_adapter'] = 'postgresql' 68 | gitlab_rails['db_encoding'] = 'unicode' 69 | gitlab_rails['db_host'] = "{{ gitlab_postgresql_db_host }}" 70 | gitlab_rails['db_port'] = {{ gitlab_postgresql_db_port }} 71 | gitlab_rails['db_password'] = "{{ gitlab_postgresql_db_password }}" 72 | {% endif %} 73 | 74 | {# 75 | Code Attribution / Terms of Use: This derived code snippet is attributed 76 | to the work of Jeff Geerling which is originally licensed under the MIT License: 77 | https://github.com/geerlingguy/ansible-role-gitlab/blob/master/templates/gitlab.rb.j2 78 | Configurations are mostly done via key-value pairs. 79 | This is a generic way to add custom key-value pairs to GitLab's configuration file. 80 | Usage example by setting Ansible variables: 81 | gitlab_additional_configurations: 82 | - gitlab_rails: 83 | - key: "time_zone" 84 | value: "Europe/Berlin" 85 | - nginx: 86 | - key: "listen_port" 87 | type: "plain" 88 | value: "80" 89 | - key: "listen_https" 90 | type: "plain" 91 | value: "false" 92 | Resulting configuration: 93 | gitlab_rails['time_zone'] = 'Europe/Berlin' 94 | nginx['listen_port'] = 80 95 | nginx['listen_https'] = false 96 | #} 97 | {% if gitlab_additional_configurations is defined %} 98 | {% for configurations in gitlab_additional_configurations %} 99 | {% for config in configurations %} 100 | {% for kvpair in configurations[config] %} 101 | {% if (kvpair.type is defined and kvpair.type == 'plain') or (kvpair.value is not string) %} 102 | {{ config }}['{{ kvpair.key }}'] = {{ kvpair.value }} 103 | {% else %} 104 | {{ config }}['{{ kvpair.key }}'] = '{{ kvpair.value }}' 105 | {% endif %} 106 | {% endfor %} 107 | {% endfor %} 108 | {% endfor %} 109 | {% endif %} 110 | 111 | {# 112 | This is a generic way to add Ruby function calls to the 113 | configuration file. 114 | Usage example by setting Ansible variables: 115 | gitlab_ruby_configuration_calls: 116 | - key: "pages_external_url" 117 | value: "https://pages.example.com" 118 | - key: "registry_external_url" 119 | value: "https://registry.example.com" 120 | - key: "mattermost_external_url" 121 | value: "https://mattermost.example.com" 122 | #} 123 | {% if gitlab_ruby_configuration_calls is defined %} 124 | {% for kvpair in gitlab_ruby_configuration_calls %} 125 | {{ kvpair.key }} "{{ kvpair.value }}" 126 | {% endfor %} 127 | {% endif %} 128 | -------------------------------------------------------------------------------- /roles/gitlab/vars/AlmaLinux.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_dependencies: 8 | - "curl" 9 | - "openssh-server" 10 | - "policycoreutils" 11 | - "tzdata" 12 | - "yum-utils" 13 | gitlab_repo_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/el/{{ ansible_facts.distribution_major_version }}/$basearch" 14 | gitlab_source_repo_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/el/{{ ansible_facts.distribution_major_version }}/SRPMS" 15 | gitlab_package_name: "{{ gitlab_edition + '-' + gitlab_version + '-' + gitlab_release if gitlab_version and gitlab_release else gitlab_edition }}" 16 | -------------------------------------------------------------------------------- /roles/gitlab/vars/CentOS.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_dependencies: 8 | - "curl" 9 | - "openssh-server" 10 | - "policycoreutils" 11 | - "tzdata" 12 | - "yum-utils" 13 | gitlab_repo_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/el/{{ ansible_facts.distribution_major_version }}/$basearch" 14 | gitlab_source_repo_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/el/{{ ansible_facts.distribution_major_version }}/SRPMS" 15 | gitlab_package_name: "{{ gitlab_edition + '-' + gitlab_version + '-' + gitlab_release if gitlab_version and gitlab_release else gitlab_edition }}" 16 | -------------------------------------------------------------------------------- /roles/gitlab/vars/Debian.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_dependencies: 8 | - "apt-transport-https" 9 | - "curl" 10 | - "gnupg" 11 | - "openssh-server" 12 | - "openssl" 13 | - "tzdata" 14 | gitlab_repo_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/debian/" 15 | gitlab_package_name: "{{ gitlab_edition + '=' + gitlab_version + '-' + gitlab_release if gitlab_version and gitlab_release else gitlab_edition }}" 16 | -------------------------------------------------------------------------------- /roles/gitlab/vars/Ubuntu.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_dependencies: 8 | - "apt-transport-https" 9 | - "curl" 10 | - "gnupg" 11 | - "openssh-server" 12 | - "openssl" 13 | - "tzdata" 14 | gitlab_repo_url: "https://packages.gitlab.com/gitlab/{{ gitlab_edition }}/ubuntu/" 15 | gitlab_package_name: "{{ gitlab_edition + '=' + gitlab_version + '-' + gitlab_release if gitlab_version and gitlab_release else gitlab_edition }}" 16 | -------------------------------------------------------------------------------- /roles/gitlab_runner/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_runner_version: "" 8 | 9 | gitlab_runner_pkg_version: "{{ gitlab_runner_version + '-1' if gitlab_runner_version | length > 0 and gitlab_runner_version is version('16.9.0', 'ge') else gitlab_runner_version }}" 10 | 11 | gitlab_runner_deb_file: "" 12 | 13 | gitlab_runner_docker_machine_binary_url: "https://gitlab.com/gitlab-org/ci-cd/docker-machine/-/releases/v0.16.2-gitlab.25/downloads/docker-machine-Linux-{{ ansible_architecture }}" 14 | 15 | gitlab_runner_docker_machine_binary_checksum: "sha256:04cc18c8f6ee0d71614064fa81116f20f3a37af53eeebf19bfb832ab9c46d3a0" 16 | 17 | gitlab_runner_transpiler_binary_url: "https://github.com/coreos/butane/releases/download/v0.23.0/butane-{{ ansible_architecture }}-unknown-linux-gnu" 18 | 19 | gitlab_runner_transpiler_binary_checksum: "sha256:5833ce9f9c2932d9b02bc05821ffb6927d1e896a524c8dd53a4c9d2d90c47e2c" 20 | 21 | gitlab_runner_install_docker: true 22 | 23 | gitlab_runner_namerservers: 24 | - "9.9.9.9" 25 | - "149.112.112.112" 26 | 27 | gitlab_runner_mtu: 1450 28 | 29 | gitlab_runner_set_default_network_opts: false 30 | 31 | gitlab_runner_config_path: "/etc/gitlab-runner/config.toml" 32 | 33 | gitlab_runner_listen_address: "" 34 | 35 | gitlab_runner_sentry_dsn: "" 36 | 37 | gitlab_runner_list: [] 38 | 39 | gitlab_runner_insecure_registries: [] 40 | 41 | gitlab_runner_ssh_private_key_path: "/etc/gitlab-runner/gitlab_runner_key" 42 | gitlab_runner_ssh_public_key_path: "/etc/gitlab-runner/gitlab_runner_key.pub" 43 | 44 | gitlab_runner_enable_session_server: false 45 | gitlab_runner_session_server_listen_address: "0.0.0.0:8093" 46 | gitlab_runner_session_server_advertise_address: "{{ gitlab_runner_session_server_listen_address }}" 47 | gitlab_runner_session_server_timeout: 1800 48 | 49 | gitlab_runner_autoscaler_plugin_version: "v0.28.0" 50 | gitlab_runner_autoscaler_binary_version: "{{ gitlab_runner_autoscaler_plugin_version | replace('v', '') }}" 51 | gitlab_runner_autoscaler_plugin_url: "https://github.com/sardinasystems/fleeting-plugin-openstack/releases/download/{{ gitlab_runner_autoscaler_plugin_version }}/fleeting-plugin-openstack_{{ gitlab_runner_autoscaler_binary_version }}_linux_amd64.tar.gz" 52 | gitlab_runner_autoscaler_plugin_checksumfile: "https://github.com/sardinasystems/fleeting-plugin-openstack/releases/download/{{ gitlab_runner_autoscaler_plugin_version }}/fleeting-plugin-openstack_{{ gitlab_runner_autoscaler_binary_version }}_sha512-checksums.txt" 53 | 54 | gitlab_runner_butane_config_template: "butane-config.bu.j2" 55 | -------------------------------------------------------------------------------- /roles/gitlab_runner/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Transpile the flatcar linux configuration" 9 | ansible.builtin.command: "butane -o /etc/gitlab-runner/ignition.json /etc/gitlab-runner/butane-config.bu" 10 | changed_when: true 11 | 12 | - name: "Restart GitLab-Runner" 13 | ansible.builtin.service: 14 | name: "gitlab-runner" 15 | state: "restarted" 16 | when: "not gitlab_runner_is_initial_dryrun" 17 | 18 | ... 19 | -------------------------------------------------------------------------------- /roles/gitlab_runner/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | galaxy_info: 8 | role_name: "gitlab_runner" 9 | author: "hifis" 10 | description: "Install GitLab CI in Openstack" 11 | company: "Helmholtz Association" 12 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 13 | license: "Apache-2.0" 14 | min_ansible_version: "2.17" 15 | 16 | platforms: 17 | - name: "Ubuntu" 18 | versions: 19 | - "jammy" 20 | - "noble" 21 | - name: "Debian" 22 | versions: 23 | - "bullseye" 24 | - "bookworm" 25 | 26 | galaxy_tags: 27 | - "gitlab" 28 | - "runner" 29 | - "ci" 30 | - "cd" 31 | - "openstack" 32 | 33 | collections: 34 | - "community.crypto" 35 | 36 | dependencies: 37 | - role: "geerlingguy.docker" 38 | when: "gitlab_runner_install_docker" 39 | vars: 40 | docker_install_compose: false 41 | ... 42 | -------------------------------------------------------------------------------- /roles/gitlab_runner/requirements.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | roles: 8 | - name: "geerlingguy.docker" 9 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/configuration.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Prepare SSH keys" 8 | when: 9 | - "gitlab_runner_ssh_public_key | default('') | length > 0" 10 | - "gitlab_runner_ssh_private_key | default('') | length > 0" 11 | block: 12 | - name: "Place SSH public key on the host for communicating with Runners." 13 | ansible.builtin.copy: 14 | src: "{{ gitlab_runner_ssh_public_key }}" 15 | dest: "{{ gitlab_runner_ssh_public_key_path }}" 16 | owner: "root" 17 | group: "root" 18 | mode: "0644" 19 | 20 | - name: "Place SSH private key on the host for communicating with Runners." 21 | ansible.builtin.copy: 22 | src: "{{ gitlab_runner_ssh_private_key }}" 23 | dest: "{{ gitlab_runner_ssh_private_key_path }}" 24 | owner: "root" 25 | group: "root" 26 | mode: "0600" 27 | 28 | - name: "Create SSH key pair for communicating with Runners." 29 | community.crypto.openssh_keypair: # noqa: args[module] 30 | path: "{{ gitlab_runner_ssh_private_key_path }}" 31 | type: "{{ gitlab_runner_ssh_key_type | default('ed25519') }}" 32 | register: "gitlab_runner_ssh_keypair" 33 | when: "not gitlab_runner_is_initial_dryrun" # skip if run for the first time in check mode 34 | 35 | - name: "Download and install container-linux-config-transpiler" 36 | ansible.builtin.get_url: 37 | url: "{{ gitlab_runner_transpiler_binary_url }}" 38 | dest: "/usr/local/bin/butane" 39 | mode: "0755" 40 | checksum: "{{ gitlab_runner_transpiler_binary_checksum }}" 41 | 42 | - name: "Place the container linux configuration on the host" 43 | ansible.builtin.template: 44 | src: "{{ gitlab_runner_butane_config_template }}" 45 | dest: "/etc/gitlab-runner/butane-config.bu" 46 | owner: "root" 47 | group: "root" 48 | mode: "0644" 49 | register: "flatcar_config_task" 50 | when: "not gitlab_runner_is_initial_dryrun" # skip if run for the first time in check mode 51 | notify: 52 | - "Transpile the flatcar linux configuration" 53 | 54 | - name: "Check if ignition.json is available and create it in any case" 55 | when: "not flatcar_config_task.changed" # noqa no-handler 56 | ansible.builtin.stat: 57 | path: "/etc/gitlab-runner/ignition.json" 58 | register: "ignition_exists" 59 | changed_when: "not ignition_exists.stat.exists" 60 | notify: 61 | - "Transpile the flatcar linux configuration" 62 | 63 | # This block is required to prepare for possible updates of the transpiler 64 | # tool resulting in a different result. Also this helps to fix any kind of 65 | # manual manipulation. 66 | - name: "Check if ignition.json is up-to-date" 67 | when: "not flatcar_config_task.changed and ignition_exists.stat.exists" # noqa no-handler 68 | block: 69 | - name: "Create temporary directory" 70 | ansible.builtin.tempfile: 71 | state: "directory" 72 | suffix: "ignition" 73 | register: "temp_directory" 74 | changed_when: false 75 | check_mode: false 76 | 77 | - name: "Dry-run of transpile the flatcar linux configuration" 78 | ansible.builtin.command: "butane -o {{ (temp_directory.path, 'ignition.json') | path_join }} /etc/gitlab-runner/butane-config.bu" 79 | changed_when: false 80 | check_mode: false 81 | 82 | - name: "Stat temporary ignition.json file" 83 | ansible.builtin.stat: 84 | path: "{{ (temp_directory.path, 'ignition.json') | path_join }}" 85 | register: "temp_ignition_stats" 86 | changed_when: 87 | - "temp_ignition_stats.stat.checksum != ignition_exists.stat.checksum" 88 | check_mode: false 89 | notify: 90 | - "Transpile the flatcar linux configuration" 91 | 92 | always: 93 | - name: "Remove temporary directory" 94 | ansible.builtin.file: 95 | path: "{{ temp_directory.path }}" 96 | state: "absent" 97 | changed_when: false 98 | check_mode: false 99 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/docker-machine-init.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Check if docker-machine initialization is necessary" 8 | ansible.builtin.stat: 9 | path: "/root/.docker/machine/certs/ca.pem" 10 | register: "docker_machine_config" 11 | 12 | - name: "Initialize docker-machine once" 13 | when: "not docker_machine_config.stat.exists" 14 | block: 15 | - name: "Extract machine options as command line parameters" 16 | ansible.builtin.set_fact: 17 | machine_options: "--{{ gitlab_runner.machine_options | join(' --') }}" 18 | 19 | - name: "Create a VM once via docker-machine" 20 | when: "not ansible_check_mode" 21 | ansible.builtin.command: "docker-machine create -d {{ gitlab_runner.machine_driver }} {{ machine_options }} test" 22 | register: "creation_cmd" 23 | changed_when: "creation_cmd.rc == 0" 24 | tags: "notest" 25 | 26 | always: 27 | - name: "Remove the VM" 28 | when: "not ansible_check_mode" 29 | ansible.builtin.command: "docker-machine rm -y --force test" 30 | register: "removal_cmd" 31 | changed_when: "removal_cmd.rc == 0" 32 | failed_when: false 33 | tags: "notest" 34 | ... 35 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/install.autoscaler-plugin.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | 5 | --- 6 | 7 | - name: "Check if fleeting-plugin-openstack is installed" 8 | ansible.builtin.stat: 9 | path: "/usr/local/bin/fleeting-plugin-openstack" 10 | register: "_fleeting_plugin_openstack_stat" 11 | 12 | - name: "Check version of installed fleeting plugin" 13 | when: "_fleeting_plugin_openstack_stat.stat.exists" 14 | ansible.builtin.shell: 15 | cmd: | 16 | set -o pipefail 17 | strings /usr/local/bin/fleeting-plugin-openstack | grep -oP "(?<=fleeting-plugin-openstack.Version=)(\d+\.\d+\.\d+)" | head -n 1 18 | executable: "/bin/bash" 19 | register: "_fleeting_plugin_version_installed" 20 | changed_when: false 21 | check_mode: false 22 | 23 | - name: "Download and install fleeting plugin" 24 | when: "not _fleeting_plugin_openstack_stat.stat.exists or _fleeting_plugin_version_installed.stdout != gitlab_runner_autoscaler_binary_version" 25 | block: 26 | - name: "Create temporary directory" 27 | ansible.builtin.tempfile: 28 | state: "directory" 29 | register: "tempdir_fleeting_plugin" 30 | check_mode: false 31 | changed_when: false 32 | 33 | - name: "Download fleeting-plugin-openstack" 34 | ansible.builtin.get_url: 35 | url: "{{ gitlab_runner_autoscaler_plugin_url }}" 36 | dest: "{{ (tempdir_fleeting_plugin.path, 'fleeting-plugin-openstack.tar.gz') | path_join }}" 37 | checksum: "sha512:{{ gitlab_runner_autoscaler_plugin_checksumfile }}" 38 | owner: "root" 39 | group: "root" 40 | mode: "0600" 41 | check_mode: false 42 | 43 | - name: "Extract fleeting-plugin-openstack binary" 44 | ansible.builtin.unarchive: 45 | src: "{{ (tempdir_fleeting_plugin.path, 'fleeting-plugin-openstack.tar.gz') | path_join }}" 46 | dest: "/usr/local/bin/" 47 | include: 48 | - "bin/fleeting-plugin-openstack" 49 | owner: "root" 50 | group: "root" 51 | mode: "0755" 52 | remote_src: true 53 | extra_opts: ['--strip-components=1'] 54 | 55 | always: 56 | - name: "Remove temporary directory" 57 | ansible.builtin.file: 58 | path: "{{ tempdir_fleeting_plugin.path }}" 59 | state: "absent" 60 | check_mode: false 61 | changed_when: false 62 | 63 | - name: "Place clouds.yaml template" 64 | ansible.builtin.template: 65 | src: "clouds.yaml.j2" 66 | dest: "/etc/gitlab-runner/clouds.yaml" 67 | owner: "root" 68 | group: "root" 69 | mode: '0600' 70 | no_log: true 71 | 72 | ... 73 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/install.debianlike.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Install GitLab-Runner dependencies" 9 | ansible.builtin.apt: 10 | pkg: 11 | - "debian-archive-keyring" 12 | - "apt-transport-https" 13 | - "gnupg" 14 | - "binutils" 15 | state: "present" 16 | update_cache: true 17 | 18 | - name: "Install gitlab-runner via apt-get" 19 | when: "gitlab_runner_deb_file | length == 0" 20 | 21 | block: 22 | - name: "Add packages repository packages.gitlab.com/runner/gitlab-runner" 23 | ansible.builtin.deb822_repository: 24 | name: "gitlab-runner" 25 | types: "deb" 26 | uris: "https://packages.gitlab.com/runner/gitlab-runner/{{ ansible_distribution | lower }}/" 27 | suites: "{{ ansible_distribution_release }}" 28 | components: "main" 29 | signed_by: "https://packages.gitlab.com/runner/gitlab-runner/gpgkey" 30 | state: "present" 31 | enabled: true 32 | 33 | - name: "Use APT pinning for Debian os" 34 | ansible.builtin.template: 35 | src: "pin-gitlab-runner.pref.j2" 36 | dest: "/etc/apt/preferences.d/pin-gitlab-runner.pref" 37 | owner: "root" 38 | group: "root" 39 | mode: '0644' 40 | when: "ansible_distribution == 'Debian'" 41 | 42 | - name: "Install gitlab-runner-helper-images with downgrade option" 43 | ansible.builtin.apt: 44 | name: "{{ gitlab_runner_helper_images_package_name }}" 45 | state: "present" 46 | update_cache: true 47 | allow_downgrade: true 48 | when: 49 | - "not gitlab_runner_is_initial_dryrun" # skip if run for the first time in check mode 50 | - "gitlab_runner_version is version('17.7.0', 'ge') or gitlab_runner_version | length == 0" 51 | 52 | - name: "Install gitlab-runner with downgrade option" 53 | ansible.builtin.apt: 54 | name: "{{ gitlab_runner_package_name }}" 55 | state: "present" 56 | update_cache: true 57 | allow_downgrade: true 58 | when: "not gitlab_runner_is_initial_dryrun" # skip if run for the first time in check mode 59 | 60 | - name: "Gather the package facts" 61 | ansible.builtin.package_facts: 62 | manager: "auto" 63 | 64 | - name: "Install gitlab-runner manually using deb package" 65 | when: 66 | - "gitlab_runner_deb_file | length > 0" 67 | - "'gitlab-runner' not in ansible_facts.packages or 68 | ansible_facts.packages['gitlab-runner'][0].version is version(gitlab_runner_pkg_version, 'ne')" 69 | block: 70 | 71 | - name: "Install gitlab-runner-helper-images from a .deb file" 72 | ansible.builtin.apt: 73 | deb: "{{ gitlab_runner_helper_images_deb_file }}" 74 | allow_downgrade: true 75 | when: "gitlab_runner_version is version('17.7.0', 'ge') or gitlab_runner_version | length == 0" 76 | 77 | - name: "Install gitlab-runner from a .deb file" 78 | ansible.builtin.apt: 79 | deb: "{{ gitlab_runner_deb_file }}" 80 | allow_downgrade: true 81 | ignore_errors: "{{ ansible_check_mode }}" # ignore errors due to unresolvable dependencies in check mode 82 | 83 | ... 84 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/install.docker-machine.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Download and install docker-machine binary" 8 | ansible.builtin.get_url: 9 | url: "{{ gitlab_runner_docker_machine_binary_url }}" 10 | dest: "/usr/local/bin/docker-machine" 11 | mode: '0755' 12 | checksum: "{{ gitlab_runner_docker_machine_binary_checksum }}" 13 | 14 | ... 15 | -------------------------------------------------------------------------------- /roles/gitlab_runner/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Set OS family dependent variables" 8 | ansible.builtin.include_vars: "{{ ansible_os_family | lower }}.yml" 9 | 10 | - name: "Set variable if autoscaling runner must be configured" 11 | ansible.builtin.set_fact: 12 | gitlab_runner_install_docker_machine: "{{ gitlab_runner_list | selectattr('executor', 'equalto', 'docker+machine') | list | length > 0 }}" 13 | gitlab_runner_install_autoscaler: "{{ gitlab_runner_list | selectattr('executor', 'equalto', 'docker-autoscaler') | list | length > 0 }}" 14 | 15 | - name: "Check if directory /etc/gitlab-runner already exists" 16 | ansible.builtin.stat: 17 | path: "/etc/gitlab-runner" 18 | register: "gitlab_runner_dir" 19 | 20 | - name: "Determine if this is an initial dry-run" 21 | ansible.builtin.set_fact: 22 | gitlab_runner_is_initial_dryrun: "{{ ansible_check_mode and not gitlab_runner_dir.stat.exists }}" 23 | 24 | - name: "Include docker-machine tasks" 25 | ansible.builtin.include_tasks: "install.docker-machine.yml" 26 | when: "gitlab_runner_install_docker_machine" 27 | 28 | - name: "Include installation tasks for Debian-like OS" 29 | ansible.builtin.include_tasks: "install.debianlike.yml" 30 | when: "ansible_os_family == 'Debian'" 31 | 32 | - name: "Include autoscaler install tasks" 33 | ansible.builtin.include_tasks: "install.autoscaler-plugin.yml" 34 | when: "gitlab_runner_install_autoscaler" 35 | 36 | - name: "Include tasks to configure the system" 37 | ansible.builtin.include_tasks: "configuration.yml" 38 | 39 | - name: "Ignition configuration must be generated before docker-machine init" 40 | ansible.builtin.meta: "flush_handlers" 41 | 42 | - name: "Initialize docker-machine" 43 | ansible.builtin.include_tasks: "docker-machine-init.yml" 44 | when: "gitlab_runner_install_docker_machine" 45 | no_log: true 46 | loop: "{{ gitlab_runner_list }}" 47 | loop_control: 48 | loop_var: "gitlab_runner" 49 | 50 | - name: "Slurp ignition json" 51 | ansible.builtin.slurp: 52 | src: "/etc/gitlab-runner/ignition.json" 53 | register: "ignition_json" 54 | when: 55 | - "gitlab_runner_install_autoscaler" 56 | - "not gitlab_runner_is_initial_dryrun" 57 | 58 | - name: "Template config file" 59 | ansible.builtin.template: 60 | src: "config.toml.j2" 61 | dest: "{{ gitlab_runner_config_path }}" 62 | owner: "{{ gitlab_runner_config_owner | default('root') }}" 63 | group: "{{ gitlab_runner_config_group | default('root') }}" 64 | mode: "0600" 65 | notify: "Restart GitLab-Runner" 66 | no_log: true 67 | vars: 68 | ignition_content: "{{ ignition_json['content'] | b64decode }}" 69 | when: "not gitlab_runner_is_initial_dryrun" 70 | 71 | - name: "Start GitLab-Runner" 72 | ansible.builtin.service: 73 | name: "gitlab-runner" 74 | state: "started" 75 | when: "not gitlab_runner_is_initial_dryrun" 76 | 77 | 78 | ... 79 | -------------------------------------------------------------------------------- /roles/gitlab_runner/templates/butane-config.bu.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | variant: flatcar 8 | version: 1.1.0 9 | passwd: 10 | users: 11 | - name: core 12 | ssh_authorized_keys: 13 | - {{ gitlab_runner_ssh_keypair.public_key }} 14 | storage: 15 | files: 16 | - path: /etc/resolv.conf 17 | overwrite: true 18 | mode: 0644 19 | contents: 20 | inline: | 21 | {% for nameserver in gitlab_runner_namerservers %} 22 | nameserver {{ nameserver }} 23 | {% endfor %} 24 | - path: /opt/docker/daemon.json 25 | mode: 0644 26 | contents: 27 | inline: | 28 | { 29 | {% set registry_mirrors_list = [] %} 30 | {% if gitlab_runner_registry_mirrors is defined %} 31 | {%- set registry_mirrors_list = gitlab_runner_registry_mirrors %} 32 | {% elif gitlab_runner_registry_mirror is defined %} 33 | {%- set registry_mirrors_list = [gitlab_runner_registry_mirror] %} 34 | {% endif %} 35 | {% if registry_mirrors_list | length > 0 %} 36 | "registry-mirrors": {{ registry_mirrors_list | to_json }}, 37 | {% endif %} 38 | {% if gitlab_runner_insecure_registries | length > 0 %} 39 | "insecure-registries": {{ gitlab_runner_insecure_registries | to_json }}, 40 | {% endif %} 41 | {% if gitlab_runner_set_default_network_opts %} 42 | "default-network-opts": { 43 | "bridge": { 44 | "com.docker.network.bridge.mtu": "{{ gitlab_runner_mtu }}" 45 | } 46 | }, 47 | {% endif %} 48 | "mtu": {{ gitlab_runner_mtu }} 49 | } 50 | - path: /etc/flatcar/update.conf 51 | overwrite: true 52 | contents: 53 | inline: | 54 | REBOOT_STRATEGY=off 55 | mode: 0420 56 | systemd: 57 | units: 58 | - name: docker.service 59 | enabled: true 60 | dropins: 61 | - name: 10-docker-opts.conf 62 | contents: | 63 | [Service] 64 | Environment="DOCKER_OPTS=--mtu={{ gitlab_runner_mtu }} {% if gitlab_runner_set_default_network_opts %}--default-network-opt bridge=com.docker.network.bridge.mtu={{ gitlab_runner_mtu }}{% endif %}{% if registry_mirrors_list | length > 0 %}{% for registry_mirror in registry_mirrors_list %} --registry-mirror={{ registry_mirror }}{% endfor %}{% endif %}{% if gitlab_runner_insecure_registries | length > 0 %}{% for insecure_registry in gitlab_runner_insecure_registries %} --insecure-registry={{ insecure_registry }}{% endfor %}{% endif %}" 65 | - name: binfmt-init.service 66 | enabled: true 67 | contents: | 68 | [Unit] 69 | Description=Initialize binfmt_misc support. 70 | After=docker.service network-online.target 71 | 72 | [Service] 73 | Type=oneshot 74 | Restart=on-failure 75 | RemainAfterExit=true 76 | ExecStartPre=/usr/bin/docker pull multiarch/qemu-user-static:register 77 | ExecStart=/usr/bin/docker run --rm --privileged multiarch/qemu-user-static:register --reset 78 | Restart=on-failure 79 | RestartSec=15 80 | 81 | [Install] 82 | WantedBy=multi-user.target 83 | -------------------------------------------------------------------------------- /roles/gitlab_runner/templates/clouds.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | #} 6 | clouds: 7 | openstack: 8 | auth: 9 | auth_url: "{{ gitlab_runner_autoscaler_openstack_auth_url }}" 10 | username: "{{ gitlab_runner_autoscaler_openstack_username }}" 11 | password: "{{ gitlab_runner_autoscaler_openstack_password }}" 12 | project_id: "{{ gitlab_runner_autoscaler_openstack_project_id }}" 13 | project_name: "{{ gitlab_runner_autoscaler_openstack_project_name }}" 14 | user_domain_name: "{{ gitlab_runner_autoscaler_openstack_user_domain_name }}" 15 | region_name: "{{ gitlab_runner_autoscaler_openstack_region_name }}" 16 | interface: "public" 17 | identity_api_version: 3 18 | -------------------------------------------------------------------------------- /roles/gitlab_runner/templates/pin-gitlab-runner.pref.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | Explanation: Prefer GitLab provided packages over the Debian native ones 8 | Package: gitlab-runner 9 | Pin: origin packages.gitlab.com{% if gitlab_runner_version | length > 0 %}, version {{ gitlab_runner_pkg_version }}{% endif +%} 10 | Pin-Priority: 1001 11 | -------------------------------------------------------------------------------- /roles/gitlab_runner/templates/runner_config.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | {{ runner_config }} 8 | -------------------------------------------------------------------------------- /roles/gitlab_runner/vars/debian.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden - Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | gitlab_runner_package_name: "gitlab-runner{{ '=' + gitlab_runner_pkg_version if gitlab_runner_version else '' }}" 8 | gitlab_runner_helper_images_package_name: "gitlab-runner-helper-images{{ '=' + gitlab_runner_pkg_version if gitlab_runner_version else '' }}" 9 | -------------------------------------------------------------------------------- /roles/haproxy/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | # Path to the executable of HAProxy 8 | haproxy_executable_path: "/usr/sbin/haproxy" 9 | # HAProxy PPA version 10 | haproxy_ppa_version: "ppa:vbernat/haproxy-3.2" 11 | # HAProxy version 12 | haproxy_version: "3.2.*" 13 | # HAProxy user 14 | haproxy_user: "haproxy" 15 | # HAProxy group 16 | haproxy_group: "haproxy" 17 | # HAProxy dependencies to be installed 18 | haproxy_dependencies: 19 | - "software-properties-common" 20 | - "python3-cryptography" 21 | - "python3-openssl" 22 | # Number of processors used by HAProxy 23 | haproxy_nbproc: "1" 24 | # Number of threads used by HAProxy 25 | haproxy_nbthread: "2" 26 | # HAProxy CPU Map 27 | haproxy_cpumap: "auto:1/1-2 0-1" 28 | # HAProxy name 29 | haproxy_name: "haproxy" 30 | # HAProxy configuration template 31 | haproxy_config_template: "haproxy.cfg.j2" 32 | # HAProxy configuration directory 33 | haproxy_conf_dir: "/etc/haproxy" 34 | # HAProxy configuration file path 35 | haproxy_conf_file_path: "{{ haproxy_conf_dir }}/{{ haproxy_name }}.cfg" 36 | # HAProxy log socket 37 | haproxy_log_socket: "/dev/log" 38 | # Log level of HAProxy, possible values are: 39 | # emerg, alert, crit, err, warning, notice, info, debug 40 | haproxy_log_level: "info" 41 | # HAProxy socket file 42 | haproxy_socket: "/run/haproxy/admin.sock" 43 | # HAProxy SSL directory 44 | haproxy_ssl_certificate_dir: "/etc/haproxy/ssl" 45 | # Generate a self-signed SSL certificate 46 | haproxy_create_self_signed_cert: true 47 | # Country name for SSL certificate 48 | haproxy_country_name: "DE" 49 | # State name for SSL certificate 50 | haproxy_state_or_province_name: "Saxony" 51 | # Locality name for SSL certificate 52 | haproxy_locality_name: "Dresden" 53 | # Organization name for SSL certificate 54 | haproxy_organization_name: "Helmholtz-Zentrum Dresden-Rossendorf (HZDR)" 55 | # Organization unit name for SSL certificate 56 | haproxy_organizational_unit_name: "FWCC / Computational Science" 57 | # Email address for SSL certificate 58 | haproxy_email_address: "hifis-help@hzdr.de" 59 | # Name for SSL certificate 60 | haproxy_common_name: "Helmholtz Association" 61 | # HAProxy Private Key file 62 | haproxy_ssl_certificate_key_file: "{{ haproxy_ssl_certificate_dir }}/haproxy.key" 63 | # HAProxy Certificate Signing Request file 64 | haproxy_ssl_certificate_csr_file: "{{ haproxy_ssl_certificate_dir }}/haproxy.csr" 65 | # HAProxy Certificate file 66 | haproxy_ssl_certificate_crt_file: "{{ haproxy_ssl_certificate_dir }}/haproxy.crt" 67 | # HAProxy Certificate pkcs12 file 68 | haproxy_ssl_certificate_pkcs12_file: "{{ haproxy_ssl_certificate_dir }}/haproxy.p12" 69 | # HAProxy Certificate Chain file 70 | haproxy_ssl_certificate_chain_file: "{{ haproxy_ssl_certificate_dir }}/haproxy.pem" 71 | # HAProxy DH Parameter file 72 | haproxy_ssl_dhparam_file: "{{ haproxy_ssl_certificate_dir }}/dhparam.pem" 73 | # Size in bits of generated DH-params 74 | haproxy_ssl_dhparam_size: 4096 75 | # Enable/disable stats 76 | haproxy_stats_enable: "enable" 77 | # Stats admin user name 78 | haproxy_stats_admin_user: "admin" 79 | # Stats admin user password 80 | haproxy_stats_admin_user_password: "changeme" 81 | 82 | ... 83 | -------------------------------------------------------------------------------- /roles/haproxy/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Check HAProxy configuration file" 9 | ansible.builtin.command: 10 | cmd: "{{ haproxy_executable_path }} -c -q -f {{ haproxy_conf_file_path }}" 11 | register: "check_haproxy_config" 12 | changed_when: "check_haproxy_config.rc != 0" 13 | failed_when: "check_haproxy_config.rc != 0" 14 | 15 | - name: "Restart HAProxy" 16 | become: true 17 | ansible.builtin.service: 18 | name: "{{ haproxy_name }}" 19 | state: "restarted" 20 | ignore_errors: "{{ ignore_errors_in_check_mode }}" # noqa ignore-errors 21 | 22 | - name: "Reload HAProxy" 23 | become: true 24 | ansible.builtin.service: 25 | name: "{{ haproxy_name }}" 26 | state: "reloaded" 27 | ignore_errors: "{{ ignore_errors_in_check_mode }}" # noqa ignore-errors 28 | 29 | ... 30 | -------------------------------------------------------------------------------- /roles/haproxy/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | galaxy_info: 8 | role_name: "haproxy" 9 | namespace: "hifis" 10 | author: "HIFIS Software Team" 11 | description: "Install and configure HAProxy to be used for load-balancing in a high availability and scalability context." 12 | company: "Helmholtz Association" 13 | 14 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 15 | 16 | license: "Apache-2.0" 17 | min_ansible_version: "2.17" 18 | 19 | platforms: 20 | - name: "Ubuntu" 21 | versions: 22 | - "jammy" 23 | - "noble" 24 | - name: "Debian" 25 | versions: 26 | - "bullseye" 27 | - "bookworm" 28 | 29 | galaxy_tags: 30 | - "haproxy" 31 | - "loadbalancer" 32 | - "networking" 33 | - "web" 34 | 35 | collections: 36 | - "community.crypto" 37 | - "ansible.posix" 38 | 39 | dependencies: [] 40 | 41 | ... 42 | -------------------------------------------------------------------------------- /roles/haproxy/templates/haproxy.cfg.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | global 8 | # global settings here 9 | maxconn 50000 10 | log {{ haproxy_log_socket }} local0 {{ haproxy_log_level }} 11 | user {{ haproxy_user }} 12 | group {{ haproxy_group }} 13 | daemon 14 | stats socket {{ haproxy_socket }} user {{ haproxy_user }} group {{ haproxy_group }} mode 660 level admin 15 | {% if haproxy_version is version('2.6', 'lt') %} 16 | nbproc {{ haproxy_nbproc }} 17 | {% endif %} 18 | nbthread {{ haproxy_nbthread }} 19 | cpu-map {{ haproxy_cpumap }} 20 | 21 | # Default SSL material locations 22 | ca-base {{ haproxy_ssl_certificate_dir }} 23 | crt-base {{ haproxy_ssl_certificate_dir }} 24 | 25 | # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate 26 | ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 27 | ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 28 | ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets 29 | ssl-dh-param-file {{ haproxy_ssl_dhparam_file }} 30 | 31 | defaults 32 | # defaults here 33 | retries 3 34 | timeout http-request 10s 35 | timeout queue 1m 36 | timeout connect 10s 37 | timeout client 30s 38 | timeout server 30s 39 | log global 40 | mode http 41 | option httplog 42 | 43 | frontend haproxy_http 44 | mode http 45 | bind {{ haproxy_frontend_ip }}:80 46 | redirect scheme https if !{ ssl_fc } 47 | 48 | frontend haproxy_https 49 | # a frontend that accepts requests from clients 50 | bind {{ haproxy_frontend_ip }}:443 ssl crt {{ haproxy_ssl_certificate_chain_file }} alpn h2,http1.1 51 | default_backend gitlab 52 | 53 | frontend haproxy_stats 54 | bind *:9000 ssl crt {{ haproxy_ssl_certificate_chain_file }} alpn h2,http1.1 55 | stats {{ haproxy_stats_enable }} 56 | stats uri /stats 57 | stats hide-version 58 | stats auth {{ haproxy_stats_admin_user }}:{{ haproxy_stats_admin_user_password }} 59 | stats admin if TRUE 60 | 61 | backend gitlab 62 | # servers that fulfill the requests 63 | balance roundrobin 64 | option httpchk 65 | http-check send meth HEAD uri / 66 | http-request add-header X-Forwarded-Proto https if { ssl_fc } 67 | default-server check maxconn 20 68 | {% for backend in haproxy_backends %} 69 | server {{ backend.backend_name }} {{ backend.backend_ip }}:{{ backend.backend_port | default(80, true) }} check 70 | {% endfor %} 71 | -------------------------------------------------------------------------------- /roles/keepalived/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | # Keepalived version 9 | keepalived_version: "2.3.2" 10 | # URL from which Keepalived can be downloaded 11 | keepalived_download_url: "https://www.keepalived.org/software/keepalived-{{ keepalived_version }}.tar.gz" 12 | # List of dependencies of Keepalived 13 | keepalived_dependencies: 14 | - "build-essential" 15 | - "curl" 16 | - "gcc" 17 | - "libssl-dev" 18 | - "libnl-3-dev" 19 | - "libnl-genl-3-dev" 20 | - "libsnmp-dev" 21 | 22 | # Path to Keepalived executable 23 | keepalived_executable_path: "/usr/local/sbin/keepalived" 24 | 25 | # Name of the template file for Keepalived configuration file 26 | keepalived_conf_template: "keepalived.conf.j2" 27 | 28 | # Folder for configuration files 29 | keepalived_conf_dir: "/etc/keepalived" 30 | 31 | # Path to Keepalived configuration file 32 | keepalived_conf_file_path: "{{ keepalived_conf_dir }}/keepalived.conf" 33 | 34 | # Path to Keepalived sysconfig file 35 | keepalived_sysconfig_file_path: "{{ keepalived_conf_dir }}/keepalived.sysconfig" 36 | 37 | # Name of the template file for Systemd service 38 | keepalived_service_template: "keepalived.service.j2" 39 | 40 | # Path to Keepalived service file 41 | keepalived_service_file_path: "/etc/systemd/system/keepalived.service" 42 | 43 | # Directory for Keepalived PID file 44 | keepalived_pid_file_path: "/run/keepalived/keepalived.pid" 45 | 46 | 47 | # Configure email accounts that will receive notification mails 48 | keepalived_notification_emails: ["root@localhost"] 49 | # Configure notification sender 50 | keepalived_notification_email_from: "keepalived@localhost" 51 | # Configure SMTP Server 52 | keepalived_smtp_server: "127.0.0.1" 53 | # Keepalived instance authentication password 54 | keepalived_auth_pass: "changeme" 55 | # Keepalived instance virtual router ID 56 | keepalived_virtual_router_id: "51" 57 | # Keepalived instance priority 58 | keepalived_priority: "{{ '100' if keepalived_state == 'MASTER' else '99' }}" 59 | # Keepalived instance state MASTER or BACKUP 60 | keepalived_state: "MASTER" 61 | # Keepalived instance network interface 62 | keepalived_interface: "{{ ansible_default_ipv4.interface }}" 63 | # Keepalived instance virtual IP address and network interface 64 | keepalived_virtual_ipaddress_config: "{{ keepalived_virtual_ip_address }} dev {{ keepalived_interface }}" 65 | # Keepalived instance unicast source IP address 66 | keepalived_unicast_src_ip: "{{ ansible_default_ipv4.address }}" 67 | 68 | # Enable process tracking 69 | keepalived_enable_process_tracking: true 70 | # Define which process shall be tracked 71 | keepalived_track_process: "haproxy" 72 | 73 | # Flag to activate a script to be executed 74 | keepalived_activate_script: false 75 | # User for executing Keepalived script 76 | keepalived_script_user: "haproxy" 77 | # Group for executing Keepalived script 78 | keepalived_script_group: "haproxy" 79 | # Name of the script to be executed 80 | keepalived_script_name: "chk_haproxy_process" 81 | # Command of the script to be executed 82 | keepalived_script_command: "/usr/bin/killall -0 haproxy" 83 | # Enable script security 84 | keepalived_set_script_security_flag: true 85 | 86 | ... 87 | -------------------------------------------------------------------------------- /roles/keepalived/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Restart Keepalived" 9 | become: true 10 | ansible.builtin.service: 11 | name: "keepalived" 12 | state: "restarted" 13 | daemon_reload: true 14 | when: "not initial_dry_run" 15 | 16 | - name: "Reload Keepalived" 17 | become: true 18 | ansible.builtin.service: 19 | name: "keepalived" 20 | state: "reloaded" 21 | daemon_reload: true 22 | when: "not initial_dry_run" 23 | 24 | ... 25 | -------------------------------------------------------------------------------- /roles/keepalived/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | galaxy_info: 9 | role_name: "keepalived" 10 | namespace: "hifis" 11 | author: "HIFIS Software Team" 12 | description: "A role to set up Keepalived in a high availability and scalability context." 13 | company: "Helmholtz Association" 14 | 15 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 16 | 17 | license: "Apache-2.0" 18 | min_ansible_version: "2.17" 19 | 20 | platforms: 21 | - name: "Ubuntu" 22 | versions: 23 | - "jammy" 24 | - "noble" 25 | 26 | galaxy_tags: 27 | - "keepalived" 28 | - "vrrp" 29 | - "networking" 30 | 31 | dependencies: [] 32 | 33 | ... 34 | -------------------------------------------------------------------------------- /roles/keepalived/templates/keepalived.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | global_defs { 8 | {% if keepalived_activate_script %} 9 | script_user {{ keepalived_script_user }} {{ keepalived_script_group }} 10 | {% endif %} 11 | {% if keepalived_set_script_security_flag %} 12 | enable_script_security 13 | {% endif %} 14 | {% if keepalived_notification_emails | default([]) | length > 0 %} 15 | notification_email { 16 | {% for email in keepalived_notification_emails %} 17 | {{ email }} 18 | {% endfor %} 19 | } 20 | notification_email_from {{ keepalived_notification_email_from }} 21 | smtp_server {{ keepalived_smtp_server }} 22 | smtp_connect_timeout 30 23 | {% endif %} 24 | {% if keepalived_router_id is defined %} 25 | router_id {{ keepalived_router_id }} 26 | {% endif %} 27 | {% if keepalived_max_auto_priority is defined %} 28 | max_auto_priority {{ keepalived_max_auto_priority }} 29 | {% endif %} 30 | } 31 | 32 | {% if keepalived_enable_process_tracking %} 33 | vrrp_track_process {{ keepalived_track_process }} { 34 | process {{ keepalived_track_process }} 35 | {% if keepalived_weight is defined %} 36 | weight {{ keepalived_weight }} 37 | {% endif %} 38 | quorum 1 39 | delay 2 40 | } 41 | {% endif %} 42 | 43 | {% if keepalived_activate_script %} 44 | vrrp_script {{ keepalived_script_name }} { 45 | script "{{ keepalived_script_command }}" 46 | interval 2 47 | {% if keepalived_weight is defined %} 48 | weight {{ keepalived_weight }} 49 | {% endif %} 50 | } 51 | {% endif %} 52 | 53 | vrrp_instance VI_1 { 54 | 55 | interface {{ keepalived_interface }} 56 | state {{ keepalived_state }} 57 | priority {{ keepalived_priority }} 58 | 59 | virtual_router_id {{ keepalived_virtual_router_id }} 60 | unicast_src_ip {{ keepalived_unicast_src_ip }} 61 | unicast_peer { 62 | {% for keepalived_unicast_peer in keepalived_unicast_peers %} 63 | {{ keepalived_unicast_peer }} 64 | {% endfor %} 65 | } 66 | 67 | virtual_ipaddress { 68 | {% if keepalived_virtual_ipaddress_configs is defined %} 69 | {% for config in keepalived_virtual_ipaddress_configs %} 70 | {{ config }} 71 | {% endfor %} 72 | {% else %} 73 | {{ keepalived_virtual_ipaddress_config }} 74 | {% endif %} 75 | } 76 | 77 | authentication { 78 | auth_type PASS 79 | auth_pass {{ keepalived_auth_pass }} 80 | } 81 | 82 | {% if keepalived_enable_process_tracking %} 83 | track_process { 84 | {{ keepalived_track_process }} 85 | } 86 | {% endif %} 87 | 88 | {% if keepalived_activate_script %} 89 | track_script { 90 | {{ keepalived_script_name }} 91 | } 92 | {% endif %} 93 | 94 | smtp_alert 95 | 96 | } 97 | -------------------------------------------------------------------------------- /roles/keepalived/templates/keepalived.service.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | [Unit] 8 | Description=LVS and VRRP High Availability Monitor 9 | After=network-online.target syslog.target 10 | Wants=network-online.target 11 | 12 | [Service] 13 | Type=forking 14 | RuntimeDirectory=keepalived 15 | PIDFile={{ keepalived_pid_file_path }} 16 | KillMode=process 17 | EnvironmentFile=-{{ keepalived_sysconfig_file_path }} 18 | ExecStart={{ keepalived_executable_path }} -p {{ keepalived_pid_file_path }} --use-file {{ keepalived_conf_file_path }} $KEEPALIVED_OPTIONS 19 | ExecReload=/bin/kill -HUP $MAINPID 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /roles/netplan/README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # `hifis.toolkit.netplan` Ansible Role 9 | 10 | [![CI Status](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/netplan.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/netplan.yml) 11 | 12 | Ansible role to install and configure Netplan. 13 | 14 | Currently [supported platforms](meta/main.yml) are: 15 | 16 | - Ubuntu 22.04 LTS 17 | - Ubuntu 24.04 LTS 18 | 19 | ## Requirements 20 | 21 | None. 22 | 23 | ## Role variables 24 | 25 | ### Mandatory variables which are not set by default 26 | 27 | #### Sample network configuration 28 | 29 | Sample configuration to set up networking with Netplan: 30 | 31 | ```yaml 32 | netplan_ethernets: 33 | - interface_name: 'eth0' 34 | dhcp4: 'no' 35 | routes: 36 | - to: 'default' 37 | via: '10.123.0.1' 38 | addresses: 39 | - '10.123.0.10/24' 40 | nameservers: 41 | addresses: 42 | - '8.8.8.8' 43 | - '9.9.9.9' 44 | search: 45 | - 'domain.local' 46 | - 'domain.name' 47 | ``` 48 | 49 | ### Variables that are set with defaults 50 | 51 | #### Flag to delete any pre-existing Netplan configuration files 52 | 53 | Flag decides on whether pre-existing Netplan configuration files should be deleted: 54 | 55 | ```yaml 56 | netplan_remove_existing_configs: true 57 | ``` 58 | 59 | #### Name of the Netplan configuration file template 60 | 61 | Name of the template providing the Netplan configuration file: 62 | 63 | ```yaml 64 | netplan_configuration_file_template: 'config.yaml.j2' 65 | ``` 66 | 67 | #### Directory of the Netplan configuration files 68 | 69 | Directory of the Netplan configuration files: 70 | 71 | ```yaml 72 | netplan_configuration_dir: '/etc/netplan' 73 | ``` 74 | 75 | #### Name of the Netplan configuration file 76 | 77 | Name of the Netplan configuration file: 78 | 79 | ```yaml 80 | netplan_configuration_file: 'config.yaml' 81 | ``` 82 | 83 | #### Path to the Netplan configuration file 84 | 85 | Path to the Netplan configuration file: 86 | 87 | ```yaml 88 | netplan_configuration_file_path: "{{ (netplan_configuration_dir, netplan_configuration_file) | path_join }}" 89 | ``` 90 | 91 | #### Packages to be installed 92 | 93 | List of packages that need to be installed: 94 | 95 | ```yaml 96 | netplan_packages: 97 | - 'netplan.io' 98 | ``` 99 | 100 | #### Package ifupdown network configuration file 101 | 102 | Network configuration file that is present if networking is managed by package ifupdown: 103 | 104 | ```yaml 105 | ifupdown_ifstate_file: '/run/network/ifstate' 106 | ``` 107 | 108 | ## Troubleshooting 109 | 110 | ### Cleaning Up: Please uninstall package ifupdown manually 111 | 112 | Before the package `ifupdown` can be safely removed netplan networking 113 | needs to be properly configured. 114 | If the package is removed too early, the role will hang. 115 | 116 | For that reason this role does **not** handle the removal of the `ifupdown` package. 117 | 118 | ## Limitations 119 | 120 | ### Bootstrapping network configurations is not supported 121 | 122 | Please note that networking configurations can not be bootstrapped during 123 | role execution. 124 | The respective managed nodes need networking to be configured beforehand. 125 | 126 | ### No support for changing the IP over which Ansible connects 127 | 128 | Be aware that this role does not support changing the IP addresses 129 | over which Ansible connects out of the box. 130 | If you change the IP address over which Ansible connects, 131 | you might end up in a hanging role as soon as `netplan apply` 132 | is executed. 133 | Ansible loses its SSH connection in that case. 134 | 135 | ## Dependencies 136 | 137 | None. 138 | 139 | ## Example Playbook 140 | 141 | ```yaml 142 | - hosts: servers 143 | vars: 144 | netplan_ethernets: 145 | - interface_name: 'eth0' 146 | dhcp4: 'no' 147 | routes: 148 | - to: 'default' 149 | via: '10.123.0.1' 150 | addresses: 151 | - '10.123.0.10/24' 152 | nameservers: 153 | addresses: 154 | - '8.8.8.8' 155 | - '9.9.9.9' 156 | search: 157 | - 'domain.local' 158 | - 'domain.name' 159 | roles: 160 | - role: hifis.toolkit.netplan 161 | ``` 162 | 163 | ## License 164 | 165 | [Apache-2.0](LICENSES/Apache-2.0.txt) 166 | 167 | ## Author Information 168 | 169 | This role was created by [HIFIS Software Services](https://hifis.net/). 170 | -------------------------------------------------------------------------------- /roles/netplan/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | # Flag to decide whether all other pre-existing config files should be deleted before applying network settings 8 | netplan_remove_existing_configs: true 9 | # Name of netplan configuration file template 10 | netplan_configuration_file_template: "config.yaml.j2" 11 | # Directory containing netplan configuration file 12 | netplan_configuration_dir: "/etc/netplan" 13 | # Name of netplan configuration file 14 | netplan_configuration_file: "config.yaml" 15 | # Path of netplan configuration file 16 | netplan_configuration_file_path: "{{ (netplan_configuration_dir, netplan_configuration_file) | path_join }}" 17 | # Packages to be installed 18 | netplan_packages: 19 | - "netplan.io" 20 | # Package ifupdown network configuration file 21 | ifupdown_ifstate_file: "/run/network/ifstate" 22 | 23 | ... 24 | -------------------------------------------------------------------------------- /roles/netplan/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Generate netplan networking" 9 | become: true 10 | ansible.builtin.command: 11 | cmd: "netplan generate" 12 | changed_when: true 13 | 14 | - name: "Apply netplan networking" 15 | become: true 16 | ansible.builtin.command: 17 | cmd: "netplan apply" 18 | changed_when: true 19 | 20 | - name: "Gather network facts" 21 | become: true 22 | ansible.builtin.setup: 23 | gather_subset: 24 | - "network" 25 | 26 | - name: "Reboot managed node" 27 | become: true 28 | ansible.builtin.reboot: 29 | reboot_timeout: 300 30 | 31 | ... 32 | -------------------------------------------------------------------------------- /roles/netplan/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | galaxy_info: 7 | role_name: "netplan" 8 | namespace: "hifis" 9 | author: "HIFIS Software Team" 10 | description: "Configure network with netplan." 11 | company: "Helmholtz Association" 12 | 13 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 14 | 15 | license: "Apache-2.0" 16 | 17 | min_ansible_version: "2.17" 18 | 19 | platforms: 20 | - name: "Ubuntu" 21 | versions: 22 | - "jammy" 23 | - "noble" 24 | 25 | galaxy_tags: 26 | - "netplan" 27 | - "networking" 28 | 29 | dependencies: [] 30 | 31 | ... 32 | -------------------------------------------------------------------------------- /roles/netplan/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | - name: "Check whether network configurations are given." 9 | ansible.builtin.assert: 10 | that: 11 | - "netplan_ethernets is defined and netplan_ethernets | length > 0" 12 | 13 | - name: "Gather package facts" 14 | ansible.builtin.package_facts: 15 | manager: "auto" 16 | 17 | - name: "Check whether package ifupdown is installed" 18 | ansible.builtin.debug: 19 | msg: | 20 | "Package 'ifupdown' is installed in version '{{ ansible_facts.packages['ifupdown'][0].version }}'. 21 | Please consider removing it after Netplan role has been executed successfully." 22 | when: "'ifupdown' in ansible_facts.packages" 23 | 24 | - name: "Install netplan packages." 25 | become: true 26 | ansible.builtin.package: 27 | name: "{{ netplan_packages }}" 28 | state: "present" 29 | update_cache: true 30 | 31 | - name: "Delete pre-existing network settings files." 32 | when: "netplan_remove_existing_configs" 33 | block: 34 | - name: "Get netplan config files." 35 | ansible.builtin.find: 36 | paths: "{{ netplan_configuration_dir }}" 37 | file_type: "file" 38 | excludes: 39 | - "{{ netplan_configuration_file }}" 40 | register: "netplan_config_files" 41 | 42 | - name: "Remove netplan config files." 43 | ansible.builtin.file: 44 | path: "{{ item.path }}" 45 | state: "absent" 46 | with_items: "{{ netplan_config_files['files'] }}" 47 | 48 | - name: "Create a netplan config file from template." 49 | ansible.builtin.template: 50 | src: "{{ netplan_configuration_file_template }}" 51 | dest: "{{ netplan_configuration_file_path }}" 52 | owner: "root" 53 | group: "root" 54 | mode: "0600" 55 | backup: true 56 | notify: 57 | - "Generate netplan networking" 58 | - "Apply netplan networking" 59 | - "Gather network facts" 60 | 61 | - name: "Check if file ifstate exists." 62 | ansible.builtin.stat: 63 | path: "{{ ifupdown_ifstate_file }}" 64 | register: "file_ifstate" 65 | 66 | - name: "Check whether to reboot host if file ifstate exists." 67 | when: "file_ifstate.stat.exists" 68 | block: 69 | - name: "Read in ifstate file content." 70 | ansible.builtin.slurp: 71 | src: "{{ ifupdown_ifstate_file }}" 72 | register: "slurped_file" 73 | 74 | - name: "Compare ifstate file content to determine whether reboot is necessary." 75 | ansible.builtin.set_fact: 76 | reboot_to_switch_to_netplan: "{{ slurped_file.content != 'lo=lo\n' | b64encode }}" 77 | 78 | - name: "Trigger reboot to switch to netplan." 79 | ansible.builtin.debug: 80 | msg: | 81 | "Reboot is required to switch from ifupdown to netplan. 82 | Triggering the reboot handler now." 83 | changed_when: "reboot_to_switch_to_netplan | bool" 84 | when: 85 | - "reboot_to_switch_to_netplan | bool" 86 | notify: "Reboot managed node" 87 | 88 | ... 89 | -------------------------------------------------------------------------------- /roles/netplan/templates/config.yaml.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | 8 | --- 9 | 10 | network: 11 | version: 2 12 | renderer: networkd 13 | {% if netplan_ethernets is defined %} 14 | ethernets: 15 | {% for ethernet in netplan_ethernets %} 16 | {% if ethernet['interface_name'] is defined %} 17 | {{ ethernet['interface_name'] }}: 18 | {% if ethernet['dhcp4'] is defined %} 19 | dhcp4: "{{ ethernet['dhcp4'] }}" 20 | {% endif %} 21 | {% if ethernet['gateway4'] is defined %} 22 | routes: 23 | - to: "default" 24 | via: "{{ ethernet['gateway4'] }}" 25 | {% if ethernet['routes'] is defined %} 26 | {% for route in ethernet['routes']%} 27 | - to: "{{ route.to }}" 28 | via: "{{ route.via }}" 29 | {% endfor %} 30 | {% endif %} 31 | {% endif %} 32 | {% if ethernet['gateway4'] is not defined %} 33 | {% if ethernet['routes'] is defined %} 34 | routes: 35 | {% for route in ethernet['routes']%} 36 | - to: "{{ route.to }}" 37 | via: "{{ route.via }}" 38 | {% endfor %} 39 | {% endif %} 40 | {% endif %} 41 | {% if ethernet['addresses'] is defined %} 42 | addresses: 43 | {%for addresses in ethernet['addresses'] %} 44 | - "{{ addresses }}" 45 | {% endfor %} 46 | {% endif %} 47 | {% if ethernet['nameservers'] is defined %} 48 | nameservers: 49 | {% if ethernet['nameservers']['addresses'] is defined %} 50 | addresses: 51 | {%for addresses in ethernet['nameservers']['addresses'] %} 52 | - "{{ addresses }}" 53 | {% endfor %} 54 | {% endif %} 55 | {% if ethernet['nameservers']['search'] is defined %} 56 | search: 57 | {%for search in ethernet['nameservers']['search'] %} 58 | - "{{ search }}" 59 | {% endfor %} 60 | {% endif %} 61 | {% endif %} 62 | {% endif %} 63 | {% endfor %} 64 | {% endif %} 65 | 66 | ... 67 | -------------------------------------------------------------------------------- /roles/redis/README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # `hifis.toolkit.redis` Ansible Role 9 | 10 | [![CI Status](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/redis.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/redis.yml) 11 | 12 | A role to set up Redis instances to be used as caching servers in a high 13 | availability and scalability context. 14 | 15 | Currently [supported platforms](meta/main.yml) are: 16 | 17 | - Ubuntu 22.04 LTS 18 | - Ubuntu 24.04 LTS 19 | 20 | ## Requirements 21 | 22 | None. 23 | 24 | ## Role variables 25 | 26 | The Redis version to install: 27 | 28 | ```yaml 29 | redis_version: '8.0.1' 30 | ``` 31 | 32 | Specifies whether the current node is `master`, or a `replica` instance: 33 | 34 | ```yaml 35 | redis_instance_type: 'master' 36 | ``` 37 | 38 | The IP address to bind Redis to: 39 | 40 | ```yaml 41 | redis_instance_ip: "127.0.0.1" 42 | ``` 43 | 44 | The Redis Master instance IP address: 45 | 46 | ```yaml 47 | redis_master_instance_ip: "{{ redis_instance_ip if redis_instance_type == 'master' else None }}" 48 | ``` 49 | 50 | The name of the Redis cluster monitored by Sentinel: 51 | 52 | ```yaml 53 | redis_cluster_name: 'redis-cluster' 54 | ``` 55 | 56 | Password used to authenticate in the Redis cluster: 57 | 58 | ```yaml 59 | redis_password: 'changeme' 60 | ``` 61 | 62 | List of dependent packages required by Redis Server: 63 | 64 | ```yaml 65 | redis_dependencies: 66 | - 'build-essential' 67 | ``` 68 | 69 | URL from which Redis Server can be downloaded: 70 | 71 | ```yaml 72 | redis_download_url: "https://download.redis.io/releases/redis-{{ redis_version }}.tar.gz" 73 | ``` 74 | 75 | File path to the Redis Server binary: 76 | 77 | ```yaml 78 | redis_bin: '/usr/local/bin/redis-server' 79 | ``` 80 | 81 | File path to the directory in which Redis Server is build: 82 | 83 | ```yaml 84 | redis_build_dir: '/usr/local/src/redis-{{ redis_version }}' 85 | ``` 86 | 87 | Directory into which Redis service files are copied: 88 | 89 | ```yaml 90 | redis_systemd_dir: '/etc/systemd/system' 91 | ``` 92 | 93 | Redis Server service file path: 94 | 95 | ```yaml 96 | redis_server_service_file: '{{ redis_systemd_dir }}/redis-server.service' 97 | ``` 98 | 99 | Redis Sentinel service file path: 100 | 101 | ```yaml 102 | redis_sentinel_service_file: '{{ redis_systemd_dir }}/redis-sentinel.service' 103 | ``` 104 | 105 | Password for Redis Sentinel. This is unset by default. 106 | 107 | ```yaml 108 | redis_sentinel_password: 'changeme' 109 | ``` 110 | 111 | Redis configuration directory path: 112 | 113 | ```yaml 114 | redis_configuration_dir: '/etc/redis' 115 | ``` 116 | 117 | Path to Redis Server configuration file: 118 | 119 | ```yaml 120 | redis_server_configuration_file: '{{ redis_configuration_dir }}/redis.conf' 121 | ``` 122 | 123 | Path to Redis Sentinel configuration file: 124 | 125 | ```yaml 126 | redis_sentinel_configuration_file: '{{ redis_configuration_dir }}/sentinel.conf' 127 | ``` 128 | 129 | Redis library directory: 130 | 131 | ```yaml 132 | redis_lib_dir: '/var/lib/redis' 133 | ``` 134 | 135 | Redis logging directory: 136 | 137 | ```yaml 138 | redis_log_dir: '/var/log/redis' 139 | ``` 140 | 141 | Path to Redis Server log file: 142 | 143 | ```yaml 144 | redis_server_log_file_path: "{{ redis_log_dir }}/redis-server.log" 145 | ``` 146 | 147 | Path to Redis Sentinel log file: 148 | 149 | ```yaml 150 | redis_sentinel_log_file_path: "{{ redis_log_dir }}/redis-sentinel.log" 151 | ``` 152 | 153 | Redis log level, can be one of: `debug`, `verbose`, `notice`, `warning`: 154 | 155 | ```yaml 156 | redis_log_level: 'notice' 157 | ``` 158 | 159 | Sentinel log level, can be one of: `debug`, `verbose`, `notice`, `warning`: 160 | 161 | ```yaml 162 | sentinel_log_level: 'notice' 163 | ``` 164 | 165 | Enable/disable Redis Server protected mode: 166 | 167 | ```yaml 168 | redis_protected_mode: 'yes' 169 | ``` 170 | 171 | Enable/disable Redis Sentinel protected mode: 172 | 173 | ```yaml 174 | sentinel_protected_mode: 'yes' 175 | ``` 176 | 177 | Redis username: 178 | 179 | ```yaml 180 | redis_user: 'redis' 181 | ``` 182 | 183 | Redis group name: 184 | 185 | ```yaml 186 | redis_group: 'redis' 187 | ``` 188 | 189 | Redis Server service name: 190 | 191 | ```yaml 192 | redis_server_service_name: 'redis-server' 193 | ``` 194 | 195 | Redis Sentinel service name: 196 | 197 | ```yaml 198 | redis_sentinel_service_name: 'redis-sentinel' 199 | 200 | ``` 201 | 202 | ## Dependencies 203 | 204 | None. 205 | 206 | ## Example Playbook 207 | 208 | ```yaml 209 | - hosts: servers 210 | roles: 211 | - role: hifis.toolkit.redis 212 | ``` 213 | 214 | ## License 215 | 216 | [Apache-2.0](LICENSES/Apache-2.0.txt) 217 | 218 | ## Author Information 219 | 220 | This role was created by [HIFIS Software Services](https://hifis.net) 221 | -------------------------------------------------------------------------------- /roles/redis/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | 8 | # Here you specify whether it is a "master" or "replica" instance: 9 | redis_instance_type: "master" 10 | # You need to provide the IP address of your Redis instance: 11 | redis_instance_ip: "127.0.0.1" 12 | # This is the name of the Redis cluster: 13 | redis_cluster_name: "redis-cluster" 14 | # You need to provide the IP address of your Redis master instance: 15 | redis_master_instance_ip: "{{ redis_instance_ip if redis_instance_type == 'master' else None }}" 16 | # Password used to authenticate in the Redis cluster 17 | redis_password: "changeme" 18 | 19 | # Redis version 20 | redis_version: "8.0.1" 21 | # Path to the Redis Server binary 22 | redis_bin: "/usr/local/bin/redis-server" 23 | # List of dependencies of Redis Server 24 | redis_dependencies: 25 | - "build-essential" 26 | # URL from which Redis Server can be downloaded 27 | redis_download_url: "https://download.redis.io/releases/redis-{{ redis_version }}.tar.gz" 28 | # Path to the directory in which Redis Server is build 29 | redis_build_dir: "/usr/local/src/redis-{{ redis_version }}" 30 | # Directory into which Redis service file is copied 31 | redis_systemd_dir: "/etc/systemd/system" 32 | # Name of Redis Server service file 33 | redis_server_service_file: "{{ redis_systemd_dir }}/redis-server.service" 34 | # Name of Redis Sentinel service file 35 | redis_sentinel_service_file: "{{ redis_systemd_dir }}/redis-sentinel.service" 36 | # Directory of Redis Server configuration files 37 | redis_configuration_dir: "/etc/redis" 38 | # Path to Redis Server configuration file 39 | redis_server_configuration_file: "{{ redis_configuration_dir }}/redis.conf" 40 | # Path to Redis Sentinel configuration file 41 | redis_sentinel_configuration_file: "{{ redis_configuration_dir }}/sentinel.conf" 42 | # Redis library directory 43 | redis_lib_dir: "/var/lib/redis" 44 | # Redis logging directory 45 | redis_log_dir: "/var/log/redis" 46 | # Path to Redis Server log file 47 | redis_server_log_file_path: "{{ redis_log_dir }}/redis-server.log" 48 | # Path to Redis Sentinel log file 49 | redis_sentinel_log_file_path: "{{ redis_log_dir }}/redis-sentinel.log" 50 | # Redis log level, can be one of: debug, verbose, notice, warning 51 | redis_log_level: "notice" 52 | # Sentinel log level, can be one of: debug, verbose, notice, warning 53 | sentinel_log_level: "notice" 54 | # Redis protected-mode 55 | redis_protected_mode: "yes" 56 | # Sentinel protected-mode 57 | sentinel_protected_mode: "yes" 58 | # Redis user name 59 | redis_user: "redis" 60 | # Redis group name 61 | redis_group: "redis" 62 | # Redis Server service name 63 | redis_server_service_name: "redis-server" 64 | # Redis Sentinel service name 65 | redis_sentinel_service_name: "redis-sentinel" 66 | 67 | ... 68 | -------------------------------------------------------------------------------- /roles/redis/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Remove auto-generated Redis config section" 8 | become: true 9 | ansible.builtin.replace: 10 | path: "{{ redis_server_configuration_file }}" 11 | after: "# END ANSIBLE MANAGED BLOCK" 12 | regexp: "^.*$" 13 | replace: "" 14 | when: "not is_initial_dryrun" 15 | 16 | - name: "Remove auto-generated Sentinel config section" 17 | become: true 18 | ansible.builtin.replace: 19 | path: "{{ redis_sentinel_configuration_file }}" 20 | after: "# END ANSIBLE MANAGED BLOCK" 21 | regexp: "^.*$" 22 | replace: "" 23 | when: "not is_initial_dryrun" 24 | 25 | - name: "Restart Redis Server" 26 | become: true 27 | ansible.builtin.service: 28 | name: "{{ redis_server_service_name }}" 29 | state: "restarted" 30 | when: "not is_initial_dryrun" 31 | 32 | - name: "Restart Redis Sentinel" 33 | become: true 34 | ansible.builtin.service: 35 | name: "{{ redis_sentinel_service_name }}" 36 | state: "restarted" 37 | when: "not is_initial_dryrun" 38 | 39 | ... 40 | -------------------------------------------------------------------------------- /roles/redis/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: 2020 Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | galaxy_info: 7 | role_name: "redis" 8 | namespace: "hifis" 9 | author: "HIFIS Software Team" 10 | description: "Install and configure Redis" 11 | company: "Helmholtz Association" 12 | 13 | issue_tracker_url: "https://github.com/hifis-net/ansible-role-redis/issues" 14 | 15 | license: "Apache-2.0" 16 | 17 | min_ansible_version: "2.17" 18 | 19 | platforms: 20 | - name: "Ubuntu" 21 | versions: 22 | - "jammy" 23 | - "noble" 24 | 25 | galaxy_tags: 26 | - "redis" 27 | - "sentinel" 28 | - "cache" 29 | - "database" 30 | 31 | dependencies: [] 32 | 33 | ... 34 | -------------------------------------------------------------------------------- /roles/redis/templates/redis-sentinel.service.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | [Unit] 8 | Description=Redis Sentinel service 9 | Documentation=https://redis.io/documentation 10 | AssertPathExists={{ redis_lib_dir }} 11 | 12 | [Service] 13 | ExecStart={{ redis_bin }} {{ redis_sentinel_configuration_file }} --sentinel 14 | LimitNOFILE=10032 15 | NoNewPrivileges=yes 16 | Type=forking 17 | TimeoutStartSec=300 18 | TimeoutStopSec=300 19 | UMask=0077 20 | User={{ redis_user }} 21 | Group={{ redis_group }} 22 | WorkingDirectory={{ redis_lib_dir }} 23 | 24 | [Install] 25 | WantedBy=multi-user.target 26 | -------------------------------------------------------------------------------- /roles/redis/templates/redis-server.service.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | [Unit] 8 | Description=Redis Server service 9 | Documentation=https://redis.io/documentation 10 | AssertPathExists={{ redis_lib_dir }} 11 | 12 | [Service] 13 | ExecStart={{ redis_bin }} {{ redis_server_configuration_file }} 14 | LimitNOFILE=10032 15 | NoNewPrivileges=yes 16 | Type=forking 17 | TimeoutStartSec=300 18 | TimeoutStopSec=300 19 | UMask=0077 20 | User={{ redis_user }} 21 | Group={{ redis_group }} 22 | WorkingDirectory={{ redis_lib_dir }} 23 | 24 | [Install] 25 | WantedBy=multi-user.target 26 | -------------------------------------------------------------------------------- /roles/redis/templates/redis.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | supervised no 8 | daemonize yes 9 | pidfile "/var/run/redis/redis-server.pid" 10 | logfile "{{ redis_server_log_file_path }}" 11 | loglevel {{ redis_log_level }} 12 | dir "/var/lib/redis" 13 | bind {{ redis_instance_ip }} 14 | port 6379 15 | 16 | requirepass "{{ redis_password }}" 17 | masterauth "{{ redis_password }}" 18 | 19 | timeout 300 20 | 21 | databases 16 22 | 23 | save 900 1 24 | save 300 10 25 | save 60 10000 26 | 27 | rdbcompression yes 28 | 29 | dbfilename "dump.rdb" 30 | 31 | appendonly no 32 | appendfsync everysec 33 | no-appendfsync-on-rewrite no 34 | 35 | protected-mode {{ redis_protected_mode }} 36 | 37 | {% if redis_instance_type == "replica" %} 38 | replicaof {{ redis_master_instance_ip }} 6379 39 | {% endif %} 40 | -------------------------------------------------------------------------------- /roles/redis/templates/sentinel.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: Apache-2.0 6 | #} 7 | supervised no 8 | daemonize yes 9 | pidfile "/var/run/redis/redis-sentinel.pid" 10 | logfile "{{ redis_sentinel_log_file_path }}" 11 | loglevel {{ sentinel_log_level }} 12 | dir "/var/lib/redis" 13 | bind {{ redis_instance_ip }} 14 | port 26379 15 | {% if (redis_sentinel_password is defined) and (redis_sentinel_password|length > 0) %} 16 | 17 | requirepass "{{ redis_sentinel_password }}" 18 | {% endif %} 19 | 20 | sentinel monitor {{ redis_cluster_name }} {{ redis_master_instance_ip }} 6379 2 21 | sentinel auth-pass {{ redis_cluster_name }} {{ redis_password }} 22 | sentinel down-after-milliseconds {{ redis_cluster_name }} 10000 23 | sentinel failover-timeout {{ redis_cluster_name }} 30000 24 | 25 | protected-mode {{ sentinel_protected_mode }} 26 | -------------------------------------------------------------------------------- /roles/ssh_keys/README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # `hifis.toolkit.ssh_keys` Ansible Role 9 | 10 | [![CI Status](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/ssh_keys.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/ssh_keys.yml) 11 | 12 | This Ansible role distributes authorized SSH public keys to users. 13 | 14 | Currently [supported platforms](meta/main.yml) are: 15 | 16 | - AlmaLinux 8 17 | - AlmaLinux 9 18 | - Ubuntu 22.04 LTS 19 | - Ubuntu 24.04 LTS 20 | - Debian 11 Bullseye 21 | - Debian 12 Bookworm 22 | 23 | ## Requirements 24 | 25 | None. 26 | 27 | ## Role Variables 28 | 29 | ```yaml 30 | ssh_user_list: 31 | - name: jane 32 | create_user_account: true 33 | authorized_keys: 34 | - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJi3wBlOT+oR8Rd+YQsV8tUoQOd3NSUuyzJYQp8finD6 john@example.com 35 | - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDXkvy8jMmw45grnmYK+Ylk/mcc7IyG9taNseNiVrGjR8KRHVJpzEntW1g6SAomIGIpBLvviiyhal4E1v1bhpv2JopbiM3JDOck6gwc4AfpanjuZFPuq6stq5pF7bb2C+zliw16zTFL7bp09tD7nNs30GlchB5DU2sSn1zq4iC+eQ== john@example.com 36 | ``` 37 | 38 | In order to authorize SSH public keys you need to edit the variable 39 | `ssh_user_list` and add a list entry containing the `name` of the user, a 40 | list of `authorized_keys` and optionally the `create_user_account` flag if you 41 | want the role to take care of creating the account. Each list entry corresponds 42 | to one user account. 43 | 44 | ```yaml 45 | ssh_authorized_keys_exclusive: true 46 | ``` 47 | 48 | Whether to remove all other non-specified keys from the authorized_keys file. 49 | 50 | ## Dependencies 51 | 52 | None. 53 | 54 | ## Example Playbook 55 | 56 | ```yaml 57 | - hosts: servers 58 | roles: 59 | - role: hifis.toolkit.ssh_keys 60 | ``` 61 | 62 | ## License 63 | 64 | [Apache-2.0](LICENSES/Apache-2.0.txt) 65 | 66 | ## Author Information 67 | 68 | This role was created by [HIFIS Software Services](https://hifis.net/). 69 | -------------------------------------------------------------------------------- /roles/ssh_keys/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | ssh_user_list: [] 8 | ssh_authorized_keys_exclusive: true 9 | -------------------------------------------------------------------------------- /roles/ssh_keys/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | galaxy_info: 8 | role_name: "ssh_keys" 9 | author: "HIFIS Software Services" 10 | description: "Add provided authorized SSH public keys to a user." 11 | company: "Helmholtz Association" 12 | 13 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 14 | 15 | license: "Apache-2.0" 16 | min_ansible_version: "2.17" 17 | 18 | platforms: 19 | - name: "EL" 20 | versions: 21 | - "8" 22 | - "9" 23 | - name: "Ubuntu" 24 | versions: 25 | - "jammy" 26 | - "noble" 27 | - name: "Debian" 28 | versions: 29 | - "bullseye" 30 | - "bookworm" 31 | 32 | galaxy_tags: 33 | - "ssh" 34 | - "authorized" 35 | - "key" 36 | - "keys" 37 | 38 | dependencies: [] 39 | 40 | ... 41 | -------------------------------------------------------------------------------- /roles/ssh_keys/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | --- 7 | - name: "Ensure user account is present" 8 | ansible.builtin.user: 9 | name: "{{ ssh_user.name }}" 10 | state: "present" 11 | when: 12 | - "ssh_user.name | default('')" 13 | - "ssh_user.name | length > 0" 14 | - "ssh_user.create_user_account | default(false) | bool" 15 | loop: "{{ ssh_user_list }}" 16 | loop_control: 17 | loop_var: "ssh_user" 18 | 19 | - name: "Manage authorized ssh keys" 20 | ansible.posix.authorized_key: 21 | user: "{{ ssh_user.name }}" 22 | key: "{{ ssh_user.authorized_keys | default([]) | join('\n') }}" 23 | exclusive: "{{ ssh_authorized_keys_exclusive }}" 24 | when: 25 | - "ssh_user.name | default('')" 26 | - "ssh_user.name | length > 0" 27 | loop: "{{ ssh_user_list }}" 28 | loop_control: 29 | loop_var: "ssh_user" 30 | ignore_errors: "{{ ansible_check_mode }}" 31 | 32 | ... 33 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | # handlers file for unattended-upgrades 9 | 10 | - name: 'Restart apt-daily timer' 11 | ansible.builtin.systemd: 12 | daemon_reload: true 13 | name: 'apt-daily.timer' 14 | state: 'restarted' 15 | enabled: true 16 | 17 | - name: 'Restart apt-daily-upgrade timer' 18 | ansible.builtin.systemd: 19 | daemon_reload: true 20 | name: 'apt-daily-upgrade.timer' 21 | state: 'restarted' 22 | enabled: true 23 | ... 24 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | galaxy_info: 9 | role_name: "unattended_upgrades" 10 | author: "hifis" 11 | description: "Setup unattended-upgrades on Debian-based systems" 12 | license: "GPLv2" 13 | min_ansible_version: "2.17" 14 | platforms: 15 | - name: "Ubuntu" 16 | versions: 17 | - "jammy" 18 | - "noble" 19 | - name: "Debian" 20 | versions: 21 | - "bullseye" 22 | - "bookworm" 23 | 24 | galaxy_tags: 25 | - "system" 26 | 27 | dependencies: [] 28 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | - name: "Import tasks from the unattended-upgrades playbook" 9 | ansible.builtin.import_tasks: "unattended-upgrades.yml" 10 | tags: "unattended" 11 | 12 | - name: "Import tasks to install systemd timer schedule overrides" 13 | ansible.builtin.import_tasks: "systemd_timers.yml" 14 | tags: "unattended_systemd_timers" 15 | when: 'unattended_systemd_timer_override' 16 | 17 | - name: "Import tasks to remove systemd timer schedule overrides" 18 | ansible.builtin.import_tasks: "systemd_timers_remove.yml" 19 | tags: "unattended_systemd_timers" 20 | when: 'not unattended_systemd_timer_override' 21 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/tasks/reboot.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | # Ignored, since newer distros don't need this package 9 | # https://github.com/jnv/ansible-role-unattended-upgrades/issues/6 10 | - name: "Install update-notifier-common" 11 | ansible.builtin.apt: 12 | name: "update-notifier-common" 13 | state: "present" 14 | force_apt_get: "yes" 15 | failed_when: false 16 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/tasks/systemd_timers.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | --- 7 | 8 | - name: 'Test apt-daily timer expression' 9 | ansible.builtin.command: 10 | cmd: 'systemd-analyze calendar "{{ unattended_apt_daily_oncalendar }}"' 11 | register: '_apt_daily' 12 | changed_when: '_apt_daily.rc != 0' 13 | check_mode: false 14 | 15 | - name: 'Test apt-daily-upgrade timer expression' 16 | ansible.builtin.command: 17 | cmd: 'systemd-analyze calendar "{{ unattended_apt_daily_upgrade_oncalendar }}"' 18 | register: '_apt_daily_upgrade' 19 | changed_when: '_apt_daily_upgrade.rc != 0' 20 | check_mode: false 21 | 22 | - name: 'Ensure directory apt-daily.timer.d exists' 23 | ansible.builtin.file: 24 | path: '/etc/systemd/system/apt-daily.timer.d' 25 | mode: '0755' 26 | state: 'directory' 27 | owner: 'root' 28 | group: 'root' 29 | register: '_apt_daily_timer_d' 30 | 31 | - name: 'Ensure directory apt-daily-upgrade.timer.d exists' 32 | ansible.builtin.file: 33 | path: '/etc/systemd/system/apt-daily-upgrade.timer.d' 34 | mode: '0755' 35 | state: 'directory' 36 | owner: 'root' 37 | group: 'root' 38 | register: '_apt_daily_upgrade_timer_d' 39 | 40 | - name: 'Deploy apt-daily timer' 41 | ansible.builtin.template: 42 | src: 'apt_daily_override.conf.j2' 43 | dest: '/etc/systemd/system/apt-daily.timer.d/schedule_override.conf' 44 | mode: '0644' 45 | owner: 'root' 46 | group: 'root' 47 | when: 48 | - '_apt_daily.rc == 0' 49 | - '_apt_daily_timer_d' # skip if run for the first time in check mode 50 | notify: 51 | - 'Restart apt-daily timer' 52 | 53 | - name: 'Deploy apt-daily-upgrade timer' 54 | ansible.builtin.template: 55 | src: 'apt_daily_upgrade_override.conf.j2' 56 | dest: '/etc/systemd/system/apt-daily-upgrade.timer.d/schedule_override.conf' 57 | mode: '0644' 58 | owner: 'root' 59 | group: 'root' 60 | when: 61 | - '_apt_daily_upgrade.rc == 0' 62 | - '_apt_daily_upgrade_timer_d' # skip if run for the first time in check mode 63 | notify: 64 | - 'Restart apt-daily-upgrade timer' 65 | ... 66 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/tasks/systemd_timers_remove.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | --- 7 | 8 | - name: 'Remove apt-daily timer override' 9 | ansible.builtin.file: 10 | path: '/etc/systemd/system/apt-daily.timer.d/schedule_override.conf' 11 | state: 'absent' 12 | notify: 13 | - 'Restart apt-daily timer' 14 | 15 | - name: 'Remove apt-daily-upgrade timer override' 16 | ansible.builtin.file: 17 | path: '/etc/systemd/system/apt-daily-upgrade.timer.d/schedule_override.conf' 18 | state: 'absent' 19 | notify: 20 | - 'Restart apt-daily-upgrade timer' 21 | ... 22 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/tasks/unattended-upgrades.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | - name: "Add distribution-specific variables" 9 | ansible.builtin.include_vars: "{{ lookup('ansible.builtin.first_found', params) }}" 10 | vars: 11 | params: 12 | files: 13 | - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_release }}.yml" 14 | - "{{ ansible_facts.distribution }}.yml" 15 | paths: 16 | - 'vars' 17 | 18 | - name: "Install powermgmt-base" 19 | ansible.builtin.apt: 20 | name: "powermgmt-base" 21 | state: "present" 22 | cache_valid_time: "{{ unattended_cache_valid_time }}" 23 | update_cache: "yes" 24 | force_apt_get: "yes" 25 | when: "unattended_only_on_ac_power" 26 | 27 | - name: "Install unattended-upgrades" 28 | ansible.builtin.apt: 29 | name: "unattended-upgrades" 30 | state: "present" 31 | cache_valid_time: "{{ unattended_cache_valid_time }}" 32 | update_cache: "yes" 33 | force_apt_get: "yes" 34 | 35 | - name: "Install reboot dependencies" 36 | ansible.builtin.import_tasks: "reboot.yml" 37 | when: "unattended_automatic_reboot | bool" 38 | 39 | - name: "Create Apt auto-upgrades & unattended-upgrades configuration" 40 | ansible.builtin.template: 41 | src: "unattended-upgrades.j2" 42 | dest: "/etc/apt/apt.conf.d/90-ansible-unattended-upgrades" 43 | owner: "root" 44 | group: "root" 45 | mode: "0644" 46 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/templates/apt_daily_override.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: GPL-2.0-or-later 6 | #} 7 | [Unit] 8 | Description=Daily apt download activities 9 | 10 | [Timer] 11 | OnCalendar= 12 | OnCalendar={{ unattended_apt_daily_oncalendar }} 13 | RandomizedDelaySec={{ unattended_apt_daily_randomizeddelaysec }} 14 | Persistent=true 15 | 16 | [Install] 17 | WantedBy=timers.target 18 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/templates/apt_daily_upgrade_override.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: GPL-2.0-or-later 6 | #} 7 | [Unit] 8 | Description=Daily apt upgrade and clean activities 9 | After=apt-daily.timer 10 | 11 | [Timer] 12 | OnCalendar= 13 | OnCalendar={{ unattended_apt_daily_upgrade_oncalendar }} 14 | RandomizedDelaySec={{ unattended_apt_daily_upgrade_randomizeddelaysec }} 15 | Persistent=true 16 | 17 | [Install] 18 | WantedBy=timers.target 19 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/vars/Debian-buster.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | --- 7 | __unattended_origins_patterns: 8 | - 'origin=Debian,codename=${distro_codename},label=Debian-Security' 9 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/vars/Debian.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | # From https://metadata.ftp-master.debian.org/changelogs//main/u/unattended-upgrades/unattended-upgrades_2.8_changelog 9 | # Allow both ${distro_codename} or ${distro_codename}-security on Debian 10 | # as security update codenames. The latter will be used starting with 11 | # Bullseye, but to help backporting and testing the configuration file keeps 12 | # working on Buster and older releases. (Closes: #933138) 13 | __unattended_origins_patterns: 14 | - 'origin=Debian,codename=${distro_codename},label=Debian-Security' 15 | - 'origin=Debian,codename=${distro_codename}-security,label=Debian-Security' 16 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/vars/Ubuntu.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | __unattended_origins_patterns: 9 | - 'origin=Ubuntu,archive=${distro_codename}-security,label=Ubuntu' 10 | -------------------------------------------------------------------------------- /roles/unattended_upgrades/vars/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # SPDX-FileCopyrightText: Jan Vlnas 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | --- 8 | # List of unattended-upgrades options that need to be erased before set by this role 9 | # See https://github.com/hifis-net/ansible-collection-toolkit/issues/94 10 | __clear_options: 11 | - "Acquire::http::Dl-Limit" 12 | - "APT::Periodic::Update-Package-Lists" 13 | - "APT::Periodic::Unattended-Upgrade" 14 | - "Unattended-Upgrade" 15 | - "Unattended-Upgrade::Allow-downgrade" 16 | - "Unattended-Upgrade::Allowed-Origins" 17 | - "Unattended-Upgrade::Allow-APT-Mark-Fallback" 18 | - "Unattended-Upgrade::AutoFixInterruptedDpkg" 19 | - "Unattended-Upgrade::Automatic-Reboot" 20 | - "Unattended-Upgrade::Automatic-Reboot-Time" 21 | - "Unattended-Upgrade::Automatic-Reboot-WithUsers" 22 | - "Unattended-Upgrade::Debug" 23 | - "Unattended-Upgrade::DevRelease" 24 | - "Unattended-Upgrade::InstallOnShutdown" 25 | - "Unattended-Upgrade::Keep-Debs-After-Install" 26 | - "Unattended-Upgrade::Mail" 27 | - "Unattended-Upgrade::MailReport" 28 | - "Unattended-Upgrade::MinimalSteps" 29 | - "Unattended-Upgrade::OnlyOnACPower" 30 | - "Unattended-Upgrade::Origins-Pattern" 31 | - "Unattended-Upgrade::Package-Blacklist" 32 | - "Unattended-Upgrade::Package-Whitelist" 33 | - "Unattended-Upgrade::Package-Whitelist-Strict" 34 | - "Unattended-Upgrade::Remove-New-Unused-Dependencies" 35 | - "Unattended-Upgrade::Remove-Unused-Dependencies" 36 | - "Unattended-Upgrade::Remove-Unused-Kernel-Packages" 37 | - "Unattended-Upgrade::Sender" 38 | - "Unattended-Upgrade::Skip-Updates-On-Metered-Connections" 39 | - "Unattended-Upgrade::SyslogEnable" 40 | - "Unattended-Upgrade::SyslogFacility" 41 | - "Unattended-Upgrade::Update-Days" 42 | - "Unattended-Upgrade::Verbose" 43 | -------------------------------------------------------------------------------- /roles/zammad/README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # `hifis.toolkit.zammad` Ansible Role 9 | 10 | [![CI Status](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/zammad.yml/badge.svg)](https://github.com/hifis-net/ansible-collection-toolkit/actions/workflows/zammad.yml) 11 | [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/hifis-net/ansible-collection-toolkit/blob/main/LICENSES/MIT.txt) 12 | 13 | An Ansible Role that installs and configures the web-based open source user 14 | support/ticketing solution [Zammad](https://zammad.org/). 15 | 16 | **Note:** This role does not install elasticsearch and postgresql server. 17 | See [Dependencies](#dependencies). 18 | 19 | Currently [supported platforms](meta/main.yml) are: 20 | 21 | - Ubuntu 22.04 LTS 22 | - Ubuntu 24.04 LTS 23 | 24 | ## Requirements 25 | 26 | The below requirements are needed on the target host: 27 | 28 | - [cryptography](https://pypi.org/project/cryptography/) >= 1.6.0 29 | 30 | ## Role Variables 31 | 32 | ```yaml 33 | zammad_version: "6.5.0" 34 | ``` 35 | 36 | Zammad version to be installed. 37 | 38 | ```yaml 39 | zammad_release_channel: "stable" 40 | ``` 41 | 42 | Choose another release channel for the Zammad packages. 43 | Please refer to for a complete list. 44 | 45 | ```yaml 46 | zammad_domain_name: "{{ ansible_fqdn }}" 47 | ``` 48 | 49 | Zammad's fully qualified domain name. 50 | 51 | ```yaml 52 | zammad_nginx_config_path: "/etc/nginx/sites-available/zammad.conf" 53 | ``` 54 | 55 | File path to Zammad's Nginx config. 56 | 57 | ```yaml 58 | zammad_ssl_cert_path: "/etc/ssl/certs/zammad_cert.pem" 59 | ``` 60 | 61 | File path to the SSL/TLS certificate which is used for HTTPS. 62 | 63 | ```yaml 64 | zammad_ssl_key_path: "/etc/ssl/private/zammad_key.pem" 65 | ``` 66 | 67 | File path to the SSL/TLS private key which is used for HTTPS. 68 | 69 | ```yaml 70 | zammad_ssl_cert: 71 | ``` 72 | 73 | Content of SSL/TLS certificate (**required**). 74 | 75 | ```yaml 76 | zammad_ssl_key: 77 | ``` 78 | 79 | Content of SSL/TLS private key (**required**). 80 | **Please note:** In the special case, that you previously put an SSL keypair 81 | on the host, e.g. via Let's Encrypt, you must not configure the variables 82 | `zammad_ssl_cert` and `zammad_ssl_key`. 83 | Nevertheless, in each case the role will 84 | validate, if the SSL key pair is given under the paths `zammad_ssl_key_path` and 85 | `zammad_ssl_cert_path` are valid. 86 | 87 | ```yaml 88 | zammad_nginx_server_tokens: "off" 89 | ``` 90 | 91 | Enable or disable emitting nginx version information in error pages or in the 92 | _Server_ response header field. Please read the nginx 93 | [docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) 94 | for further information. 95 | 96 | ```yaml 97 | zammad_nginx_additional_server_configs: 98 | - | 99 | server { 100 | listen 80; 101 | server_name zammad.example.com zammad-old.example.com; 102 | return 301 https://zammad.example.com$request_uri; 103 | } 104 | - | 105 | server { 106 | listen 443 ssl; 107 | 108 | # ... SSL configuration 109 | 110 | server_name zammad-old.example.com; 111 | return 301 https://zammad.example.com$request_uri; 112 | } 113 | ``` 114 | 115 | Configure additional server directives in the Nginx configuration. 116 | This allows to implement more use case specific adjustments, e.g. 117 | configuring multiple domains or the redirection of outdated domains to the 118 | most recent one. 119 | 120 | ```yaml 121 | zammad_elasticsearch_url: "http://localhost:9200" 122 | ``` 123 | 124 | Elasticsearch server address. 125 | 126 | ```yaml 127 | zammad_force_es_searchindex_rebuild: false 128 | ``` 129 | 130 | By default, the Elasticsearch indexes are only rebuilt during the initial 131 | installation. 132 | Set this variable to `true` to force Ansible to trigger the rebuild of the 133 | Zammad search index when Zammad is updated. 134 | 135 | ## Dependencies 136 | 137 | Zammad requires Elasticsearch and PostgreSQL database server. 138 | This role has been successfully tested together with the following roles: 139 | 140 | - Elasticsearch - [geerlingguy.elasticsearch](https://github.com/geerlingguy/ansible-role-elasticsearch) 141 | - PostgreSQL - [geerlingguy.postgresql](https://galaxy.ansible.com/geerlingguy/postgresql) 142 | 143 | ## Example Playbook 144 | 145 | ```yaml 146 | - hosts: servers 147 | roles: 148 | - role: hifis.toolkit.zammad 149 | become: yes 150 | ``` 151 | 152 | ## License 153 | 154 | MIT 155 | 156 | ## Author Information 157 | 158 | This role was created by [HIFIS Software Services](https://hifis.net/). 159 | -------------------------------------------------------------------------------- /roles/zammad/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | zammad_version: "6.5.0" 8 | zammad_release_channel: "stable" 9 | zammad_repo_url: "https://dl.packager.io/srv/deb/zammad/zammad/{{ zammad_release_channel }}/{{ ansible_facts.distribution | lower }}" 10 | zammad_domain_name: "{{ ansible_fqdn }}" 11 | 12 | zammad_nginx_config_path: "/etc/nginx/sites-available/zammad.conf" 13 | zammad_ssl_cert_path: "/etc/ssl/certs/zammad_cert.pem" 14 | zammad_ssl_key_path: "/etc/ssl/private/zammad_key.pem" 15 | 16 | zammad_nginx_additional_server_configs: [] 17 | zammad_nginx_server_tokens: "off" 18 | 19 | zammad_force_es_searchindex_rebuild: false 20 | 21 | zammad_elasticsearch_url: "http://localhost:9200" 22 | ... 23 | -------------------------------------------------------------------------------- /roles/zammad/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | - name: "Reload nginx" 8 | ansible.builtin.service: 9 | name: "nginx" 10 | state: "reloaded" 11 | 12 | - name: "Set Elasticsearch server address" 13 | ansible.builtin.command: >- 14 | zammad run rails r "Setting.set('es_url', '{{ zammad_elasticsearch_url | quote }}')" 15 | changed_when: true 16 | 17 | - name: "Build search index" 18 | ansible.builtin.command: "zammad run rake zammad:searchindex:rebuild" 19 | changed_when: true 20 | when: "not __zammad_is_installed or zammad_force_es_searchindex_rebuild" 21 | 22 | ... 23 | -------------------------------------------------------------------------------- /roles/zammad/meta/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | 7 | galaxy_info: 8 | role_name: "zammad" 9 | namespace: "hifis" 10 | description: "Install Zammad helpdesk on Linux." 11 | author: "HIFIS Software Services" 12 | company: "Helmholtz Association of German Research Centres" 13 | license: "MIT" 14 | issue_tracker_url: "https://github.com/hifis-net/ansible-collection-toolkit/issues" 15 | min_ansible_version: "2.17" 16 | 17 | platforms: 18 | - name: "Ubuntu" 19 | versions: 20 | - "jammy" 21 | - "noble" 22 | 23 | galaxy_tags: 24 | - "zammad" 25 | 26 | dependencies: [] 27 | -------------------------------------------------------------------------------- /roles/zammad/tasks/install.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | 8 | - name: "Configure Zammad repository for Centos-like" 9 | when: "ansible_distribution | lower == 'centos'" 10 | block: 11 | 12 | - name: "Install | Install EPEL repo" 13 | ansible.builtin.dnf: 14 | name: "epel-release" 15 | state: "present" 16 | 17 | - name: "Install | Add Zammad yum repository" 18 | ansible.builtin.yum_repository: 19 | name: "zammad" 20 | state: "present" 21 | description: "Repository for zammad/zammad ({{ zammad_release_channel }}) packages." 22 | baseurl: "https://dl.packager.io/srv/rpm/zammad/zammad/{{ zammad_release_channel }}/el/7/$basearch" 23 | enabled: true 24 | gpgcheck: false 25 | repo_gpgcheck: true 26 | gpgkey: "https://dl.packager.io/srv/zammad/zammad/key" 27 | mode: "0644" 28 | 29 | - name: "Configure Zammad repository for Ubuntu" 30 | when: "ansible_distribution | lower == 'ubuntu'" 31 | block: 32 | 33 | - name: "Remove Zammad apt key from legacy trusted.gpg keyring" 34 | ansible.builtin.apt_key: 35 | url: "https://dl.packager.io/srv/zammad/zammad/key" 36 | state: "absent" 37 | 38 | - name: "Remove Zammad DEB repository from sources.list" 39 | ansible.builtin.apt_repository: 40 | repo: "deb https://dl.packager.io/srv/deb/zammad/zammad/{{ zammad_release_channel }}/ubuntu {{ ansible_distribution_version }} main" 41 | state: "absent" 42 | filename: "zammad" 43 | update_cache: false 44 | 45 | - name: "Install | Add Zammad DEB repository" 46 | ansible.builtin.deb822_repository: 47 | name: "zammad" 48 | types: "deb" 49 | uris: "{{ zammad_repo_url }}" 50 | suites: "{{ ansible_facts.distribution_version }}" 51 | components: "main" 52 | signed_by: "https://dl.packager.io/srv/zammad/zammad/key" 53 | architectures: "amd64" 54 | state: "present" 55 | mode: "0644" 56 | enabled: true 57 | 58 | - name: "Update apt cache" 59 | ansible.builtin.apt: 60 | update_cache: true 61 | changed_when: false 62 | 63 | - name: "Gather the package facts to check wether Zammad has already been installed" 64 | ansible.builtin.package_facts: 65 | manager: "auto" 66 | 67 | - name: "Check if Zammad is already installed" 68 | ansible.builtin.set_fact: 69 | __zammad_is_installed: "{{ 'zammad' in ansible_facts.packages }}" 70 | 71 | - name: "Install | Install Zammad package" 72 | ansible.builtin.package: 73 | name: "zammad={{ zammad_version }}*" 74 | state: "present" 75 | force: true 76 | notify: 77 | - "Set Elasticsearch server address" 78 | - "Build search index" 79 | 80 | - name: "Install | Start and enable services" 81 | ansible.builtin.service: 82 | name: "{{ item }}" 83 | state: "started" 84 | enabled: true 85 | loop: 86 | - "zammad" 87 | - "zammad-web" 88 | - "zammad-worker" 89 | - "zammad-websocket" 90 | notify: "Build search index" 91 | 92 | ... 93 | -------------------------------------------------------------------------------- /roles/zammad/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | 8 | - name: "Install zammad" 9 | ansible.builtin.import_tasks: "install.yml" 10 | 11 | - name: "Set up SSL/TLS" 12 | ansible.builtin.import_tasks: "ssl.yml" 13 | 14 | - name: "Configure nginx" 15 | ansible.builtin.import_tasks: "nginx-config.yml" 16 | 17 | ... 18 | -------------------------------------------------------------------------------- /roles/zammad/tasks/nginx-config.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | 8 | - name: "Nginx | Create config" 9 | ansible.builtin.template: 10 | src: "nginx-zammad.conf.j2" 11 | dest: "{{ zammad_nginx_config_path }}" 12 | mode: "0644" 13 | owner: "root" 14 | group: "root" 15 | notify: "Reload nginx" 16 | 17 | ... 18 | -------------------------------------------------------------------------------- /roles/zammad/tasks/ssl.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | # SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | # 4 | # SPDX-License-Identifier: MIT 5 | 6 | --- 7 | 8 | - name: "SSL | Insert private key" 9 | ansible.builtin.blockinfile: 10 | path: "{{ zammad_ssl_key_path }}" 11 | create: true 12 | block: | 13 | {{ zammad_ssl_key }} 14 | mode: "0640" 15 | owner: "root" 16 | group: "root" 17 | when: "zammad_ssl_key | default('') | length > 0" 18 | 19 | - name: "SSL | Insert certificate" 20 | ansible.builtin.blockinfile: 21 | path: "{{ zammad_ssl_cert_path }}" 22 | create: true 23 | block: | 24 | {{ zammad_ssl_cert }} 25 | mode: "0644" 26 | owner: "root" 27 | group: "root" 28 | when: "zammad_ssl_cert | default('') | length > 0" 29 | 30 | - name: "SSL | Check if certificate is still valid, ignoring failures" 31 | community.crypto.x509_certificate_info: 32 | path: "{{ zammad_ssl_cert_path }}" 33 | register: "certificate" 34 | ignore_errors: "{{ ansible_check_mode }}" 35 | 36 | - name: "SSL | Ensure certificate and private key match" 37 | community.crypto.openssl_privatekey_info: 38 | path: "{{ zammad_ssl_key_path }}" 39 | register: "private_key" 40 | ignore_errors: "{{ ansible_check_mode }}" 41 | 42 | - name: "SSL | Validate that certificate is still valid" 43 | ansible.builtin.assert: 44 | that: 45 | - "not certificate.expired" 46 | - "certificate.public_key == private_key.public_key" 47 | 48 | ... 49 | -------------------------------------------------------------------------------- /roles/zammad/templates/nginx-zammad.conf.j2: -------------------------------------------------------------------------------- 1 | {# 2 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 3 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 4 | 5 | SPDX-License-Identifier: MIT 6 | #} 7 | # {{ ansible_managed }} 8 | # 9 | # this is the nginx config for zammad 10 | # 11 | 12 | upstream zammad-railsserver { 13 | server 127.0.0.1:3000; 14 | } 15 | 16 | upstream zammad-websocket { 17 | server 127.0.0.1:6042; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name {{ zammad_domain_name }}; 23 | server_tokens {{ zammad_nginx_server_tokens }}; 24 | return 301 https://$server_name$request_uri; 25 | } 26 | 27 | server { 28 | listen 443 ssl http2; 29 | server_name {{ zammad_domain_name }}; 30 | 31 | server_tokens {{ zammad_nginx_server_tokens }}; 32 | 33 | ssl_certificate {{ zammad_ssl_cert_path }}; 34 | ssl_certificate_key {{ zammad_ssl_key_path }}; 35 | ssl_protocols TLSv1.2 TLSv1.3; 36 | ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; 37 | ssl_prefer_server_ciphers on; 38 | 39 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 40 | 41 | location = /robots.txt { 42 | access_log off; log_not_found off; 43 | } 44 | 45 | location = /favicon.ico { 46 | access_log off; log_not_found off; 47 | } 48 | 49 | root /opt/zammad/public; 50 | 51 | access_log /var/log/nginx/zammad.access.log; 52 | error_log /var/log/nginx/zammad.error.log; 53 | 54 | client_max_body_size 50M; 55 | 56 | location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png) { 57 | expires max; 58 | } 59 | 60 | location /ws { 61 | proxy_http_version 1.1; 62 | proxy_set_header Upgrade $http_upgrade; 63 | proxy_set_header Connection "Upgrade"; 64 | proxy_set_header CLIENT_IP $remote_addr; 65 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 66 | proxy_set_header X-Forwarded-Proto $scheme; 67 | proxy_read_timeout 86400; 68 | proxy_pass http://zammad-websocket; 69 | } 70 | 71 | {% if zammad_version is version('6.0', 'ge') +%} 72 | location /cable { 73 | proxy_http_version 1.1; 74 | proxy_set_header Upgrade $http_upgrade; 75 | proxy_set_header Connection "Upgrade"; 76 | proxy_set_header Host $http_host; 77 | proxy_set_header CLIENT_IP $remote_addr; 78 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 79 | proxy_set_header X-Forwarded-Proto $scheme; 80 | proxy_read_timeout 86400; 81 | proxy_pass http://zammad-railsserver; 82 | } 83 | {% endif %} 84 | 85 | location / { 86 | proxy_set_header Host $http_host; 87 | proxy_set_header CLIENT_IP $remote_addr; 88 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 89 | proxy_set_header X-Forwarded-Proto $scheme; 90 | proxy_read_timeout 300; 91 | proxy_pass http://zammad-railsserver; 92 | 93 | gzip on; 94 | gzip_types text/plain text/xml text/css image/svg+xml application/javascript application/x-javascript application/json application/xml; 95 | gzip_proxied any; 96 | } 97 | } 98 | 99 | {% for server_config in zammad_nginx_additional_server_configs %} 100 | {{ server_config }} 101 | {% endfor %} 102 | -------------------------------------------------------------------------------- /uv.lock.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Helmholtz Centre for Environmental Research (UFZ) 2 | SPDX-FileCopyrightText: Helmholtz-Zentrum Dresden-Rossendorf (HZDR) 3 | 4 | SPDX-License-Identifier: Apache-2.0 5 | --------------------------------------------------------------------------------