├── .editorconfig ├── .github ├── DISCUSSION_TEMPLATE │ └── discussions.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── pull_request_template.md ├── renovate.json5 ├── scripts │ ├── config.js │ ├── documentation.js │ ├── github-api.js │ └── utils.js ├── semantic.yml ├── templates │ └── workflow.md.hbs └── workflows │ └── documentation.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .vscode ├── extensions.json └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ansible.cfg ├── collections └── requirements.yaml ├── docs └── images │ └── logo-services.svg ├── inventory └── cluster │ ├── group_vars │ └── all.yaml │ └── hosts.yaml ├── provisioning.yaml ├── reset.yaml ├── roles ├── README.md ├── argo-cd │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── config_cm.j2 │ │ ├── config_params.j2 │ │ ├── config_rbac.j2 │ │ ├── credentials.j2 │ │ └── values.j2 ├── cert-manager │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── cluster_issuer.j2 │ │ ├── config_controller.j2 │ │ └── values.j2 ├── cilium │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── certificate.j2 │ │ ├── cluster_issuer.j2 │ │ ├── gateway.j2 │ │ ├── http_route_insecure.j2 │ │ ├── http_route_secure.j2 │ │ ├── l2_announcement_policy.j2 │ │ ├── loadbalancer_ip_pool.j2 │ │ └── values.j2 ├── cluster │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── handlers │ │ └── main.yaml │ └── tasks │ │ ├── configuration.yaml │ │ ├── facts.yaml │ │ ├── firewall.yaml │ │ ├── main.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ ├── user.yaml │ │ └── validation.yaml ├── coredns │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── config_servers.j2 │ │ └── values.j2 ├── external-dns │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── api_token.j2 │ │ ├── cluster_issuer.j2 │ │ └── values.j2 ├── helm │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── handlers │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── plugins.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── service.j2 │ │ └── timer.j2 ├── k3s │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── handlers │ │ └── main.yaml │ ├── tasks │ │ ├── configuration.yaml │ │ ├── facts.yaml │ │ ├── loadbalancer.yaml │ │ ├── main.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── config.j2 │ │ ├── haproxy.j2 │ │ ├── keepalived.j2 │ │ ├── registries.j2 │ │ └── service.j2 ├── kured │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ └── values.j2 ├── longhorn │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ ├── credentials.j2 │ │ ├── gateway.j2 │ │ ├── http_route_insecure.j2 │ │ ├── http_route_secure.j2 │ │ └── values.j2 ├── metrics-server │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ └── values.j2 ├── victoria-logs │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ │ └── main.yaml │ ├── tasks │ │ ├── facts.yaml │ │ ├── main.yaml │ │ ├── postinstall.yaml │ │ ├── reset.yaml │ │ ├── upgrade.yaml │ │ └── validation.yaml │ └── templates │ │ └── values.j2 └── victoria-metrics │ ├── Chart.yaml │ ├── README.md │ ├── README.md.gotmpl │ ├── defaults │ └── main.yaml │ ├── tasks │ ├── facts.yaml │ ├── main.yaml │ ├── reset.yaml │ ├── upgrade.yaml │ └── validation.yaml │ └── templates │ ├── config_alertmanager.j2 │ ├── credentials.j2 │ └── values.j2 ├── upgrade.yaml ├── validation.yaml └── vault.yaml /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Default settings for all files 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | indent_style = space 13 | indent_size = 2 14 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/discussions.yml: -------------------------------------------------------------------------------- 1 | body: 2 | - type: markdown 3 | attributes: 4 | value: | 5 | > [!IMPORTANT] 6 | > If you have usage questions, please read first the [Wiki](https://axivo.com/k3s-cluster). 7 | - type: dropdown 8 | id: topic 9 | attributes: 10 | label: Discussion Topic 11 | options: 12 | - Configuration 13 | - New Idea or Feature 14 | - Possible Bug 15 | - Other 16 | default: 0 17 | validations: 18 | required: true 19 | - type: textarea 20 | id: description 21 | attributes: 22 | label: Description 23 | description: Please tell us more about your question or problem. 24 | validations: 25 | required: true 26 | - type: textarea 27 | id: logs 28 | attributes: 29 | label: Relevant Logs 30 | description: | 31 | Please copy and paste any relevant log output. 32 | > [!TIP] 33 | > This will be automatically formatted into code, there is no need to insert backticks. 34 | render: shell 35 | - type: textarea 36 | id: anything-else 37 | attributes: 38 | label: Anything Else 39 | description: | 40 | Links? References? Anything that will provide more context. 41 | > [!TIP] 42 | > You can attach images or log files by clicking this area to highlight it and then dragging files in. 43 | - type: checkboxes 44 | id: terms 45 | attributes: 46 | label: Code of Conduct 47 | description: By submitting this discussion, you agree to follow our [Code of Conduct](https://github.com/axivo/k3s-cluster/blob/main/CODE_OF_CONDUCT.md) 48 | options: 49 | - label: I agree to follow project's Code of Conduct 50 | required: true 51 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report an encountered bug. 3 | labels: ["bug", "triage"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | > [!IMPORTANT] 9 | > If you have usage questions, please read first the [Wiki](https://axivo.com/k3s-cluster) and use [GitHub Discussions](https://github.com/axivo/k3s-cluster/discussions), for community support. 10 | - type: checkboxes 11 | attributes: 12 | label: Existing Issues 13 | description: Please search to see if an issue already exists for the bug you encountered. 14 | options: 15 | - label: I have searched the existing issues 16 | required: true 17 | - type: textarea 18 | id: what-happened 19 | attributes: 20 | label: What Happened 21 | description: What did you expect to happen? 22 | value: "A bug happened!" 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: kernel-version 27 | attributes: 28 | label: Kernel Version 29 | description: | 30 | Which kernel version is the cluster running on? (run `uname -a`) 31 | > [!TIP] 32 | > This will be automatically formatted into code, there is no need to insert backticks. 33 | render: shell 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: k8s-version 38 | attributes: 39 | label: Kubernetes Version 40 | description: | 41 | Which Kubernetes version is the cluster running on? (run `kubectl version`) 42 | > [!TIP] 43 | > This will be automatically formatted into code, there is no need to insert backticks. 44 | render: shell 45 | validations: 46 | required: true 47 | - type: textarea 48 | id: logs 49 | attributes: 50 | label: Relevant Logs 51 | description: | 52 | Please copy and paste any relevant log output. 53 | > [!TIP] 54 | > This will be automatically formatted into code, there is no need to insert backticks. 55 | render: shell 56 | - type: textarea 57 | id: anything-else 58 | attributes: 59 | label: Anything Else 60 | description: | 61 | Links? References? Anything that will provide more context about the issue you are encountering. 62 | > [!TIP] 63 | > You can attach images or log files by clicking this area to highlight it and then dragging files in. 64 | - type: checkboxes 65 | id: terms 66 | attributes: 67 | label: Code of Conduct 68 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/axivo/k3s-cluster/blob/main/CODE_OF_CONDUCT.md) 69 | options: 70 | - label: I agree to follow project's Code of Conduct 71 | required: true 72 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Community Discussions 4 | url: https://github.com/axivo/k3s-cluster/discussions 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest an idea for this project. 3 | labels: ["enhancement", "triage"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | > [!IMPORTANT] 9 | > If you have usage questions, please read first the [Wiki](https://axivo.com/k3s-cluster) and use [GitHub Discussions](https://github.com/axivo/k3s-cluster/discussions), for community support. 10 | - type: checkboxes 11 | attributes: 12 | label: Existing Issues 13 | description: Please search to see if an issue already exists for the feature request. 14 | options: 15 | - label: I have searched the existing issues 16 | required: true 17 | - type: textarea 18 | id: related-problem 19 | attributes: 20 | label: Related Problem 21 | description: Is your feature request related to a problem? 22 | value: "Please describe the related problem." 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: solution-implementation 27 | attributes: 28 | label: Solution Implementation 29 | description: Describe the solution you would like to see implemented. 30 | validations: 31 | required: true 32 | - type: textarea 33 | id: solution-alternatives 34 | attributes: 35 | label: Solution Alternatives 36 | description: Describe any solution alternatives you've considered. 37 | - type: textarea 38 | id: anything-else 39 | attributes: 40 | label: Anything Else 41 | description: | 42 | Links? References? Anything that will provide more context about the feature request. 43 | > [!TIP] 44 | > You can attach images or log files by clicking this area to highlight it and then dragging files in. 45 | - type: checkboxes 46 | id: terms 47 | attributes: 48 | label: Code of Conduct 49 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/axivo/k3s-cluster/blob/main/CODE_OF_CONDUCT.md) 50 | options: 51 | - label: I agree to follow project's Code of Conduct 52 | required: true 53 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Objective 2 | 3 | 10 | 11 | ## Scope 12 | 13 | - [ ] Bug (resolves an issue) 14 | - [ ] Enhancement (improves existing functionality) 15 | - [ ] Feature (adds new functionality) 16 | - [ ] Documentation (adds or improves documentation) 17 | 18 | ### Impact 19 | 20 | - [ ] Non-breaking (backwards compatible) 21 | - [ ] Breaking (backwards incompatible, impacts end-user) 22 | 23 | ## Checklist 24 | 25 | - [ ] My code follows the contributing guidelines of this project 26 | - [ ] I have performed a self-review of my code 27 | - [ ] I have made corresponding changes to the documentation 28 | - [ ] My changes generate no new issues or warnings 29 | -------------------------------------------------------------------------------- /.github/semantic.yml: -------------------------------------------------------------------------------- 1 | titleOnly: true 2 | # See: https://www.conventionalcommits.org 3 | # Valid types listed below can be overridden 4 | types: 5 | - build 6 | - ci 7 | - chore 8 | - docs 9 | - feat 10 | - fix 11 | - perf 12 | - refactor 13 | - revert 14 | - style 15 | - test 16 | -------------------------------------------------------------------------------- /.github/templates/workflow.md.hbs: -------------------------------------------------------------------------------- 1 | Issues were detected during the execution of `{{ Workflow }}` workflow. 2 | 3 | ### Details 4 | 5 | - Branch: [`{{ Branch }}`]({{ RepoURL }}/tree/{{ Branch }}) 6 | - Commit: `{{ Sha }}` 7 | - Run ID: `{{ RunID }}` 8 | 9 | Please review the [workflow logs]({{ RepoURL }}/actions/runs/{{ RunID }}), for additional details. 10 | -------------------------------------------------------------------------------- /.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - roles/*/defaults/main.yaml 7 | - roles/*/Chart.yaml 8 | - roles/*/README.md.gotmpl 9 | 10 | concurrency: 11 | cancel-in-progress: true 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | 14 | defaults: 15 | run: 16 | shell: bash 17 | 18 | permissions: 19 | contents: write 20 | issues: write 21 | 22 | jobs: 23 | update: 24 | name: Update 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v4 29 | 30 | - name: Setup node 31 | uses: actions/setup-node@v4 32 | with: 33 | node-version: 22 34 | 35 | - name: Install node dependencies 36 | run: npm install handlebars 37 | 38 | - name: Configure repository 39 | uses: actions/github-script@v7 40 | with: 41 | script: | 42 | const { configureGitRepository } = require('./.github/scripts/utils.js'); 43 | await configureGitRepository({ core, exec }); 44 | 45 | - name: Install helm-docs 46 | uses: actions/github-script@v7 47 | with: 48 | script: | 49 | const { installHelmDocs } = require('./.github/scripts/documentation.js'); 50 | await installHelmDocs({ core, exec, version: '1.14.2' }); 51 | 52 | - name: Update documentation 53 | uses: actions/github-script@v7 54 | with: 55 | script: | 56 | const { updateDocumentation } = require('./.github/scripts/documentation.js'); 57 | await updateDocumentation({ github, context, core, exec }); 58 | 59 | - name: Report workflow issue 60 | uses: actions/github-script@v7 61 | with: 62 | script: | 63 | const { reportWorkflowIssue } = require('./.github/scripts/utils.js'); 64 | await reportWorkflowIssue({ github, context, core }); 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ansible 2 | .ansible 3 | ansible.log 4 | 5 | # MacOS 6 | **/.DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | ._* 10 | 11 | # Node.js 12 | node_modules/ 13 | package.json 14 | package-lock.json 15 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/axivo/k3s-cluster 4 | rev: v1.0.0 5 | hooks: 6 | - id: argo-cd 7 | args: 8 | - --chart-search-root=./roles/argo-cd 9 | - id: cert-manager 10 | args: 11 | - --chart-search-root=./roles/cert-manager 12 | - id: cilium 13 | args: 14 | - --chart-search-root=./roles/cilium 15 | - id: cluster 16 | args: 17 | - --chart-search-root=./roles/cluster 18 | - id: coredns 19 | args: 20 | - --chart-search-root=./roles/coredns 21 | - id: external-dns 22 | args: 23 | - --chart-search-root=./roles/external-dns 24 | - id: helm 25 | args: 26 | - --chart-search-root=./roles/helm 27 | - id: k3s 28 | args: 29 | - --chart-search-root=./roles/k3s 30 | - id: kured 31 | args: 32 | - --chart-search-root=./roles/kured 33 | - id: longhorn 34 | args: 35 | - --chart-search-root=./roles/longhorn 36 | - id: metrics-server 37 | args: 38 | - --chart-search-root=./roles/metrics-server 39 | - id: victoria-logs-single 40 | args: 41 | - --chart-search-root=./roles/victoria-logs 42 | - id: victoria-metrics-k8s-stack 43 | args: 44 | - --chart-search-root=./roles/victoria-metrics 45 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "github.vscode-github-actions", 4 | "ms-kubernetes-tools.vscode-kubernetes-tools", 5 | "redhat.ansible", 6 | "redhat.vscode-yaml" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[github-actions-workflow]": { 3 | "editor.defaultFormatter": "redhat.vscode-yaml" 4 | }, 5 | "[helm]": { 6 | "editor.autoIndent": "keep", 7 | "editor.formatOnSave": true, 8 | "editor.insertSpaces": true, 9 | "editor.tabSize": 2 10 | }, 11 | "[jsonc]": { 12 | "editor.defaultFormatter": "vscode.json-language-features", 13 | "editor.formatOnSave": true, 14 | "editor.tabSize": 2 15 | }, 16 | "[yaml]": { 17 | "editor.autoIndent": "keep", 18 | "editor.defaultFormatter": "redhat.vscode-yaml", 19 | "editor.formatOnSave": true, 20 | "editor.insertSpaces": true, 21 | "editor.tabSize": 2, 22 | "files.insertFinalNewline": true, 23 | "files.trimFinalNewlines": true, 24 | "files.trimTrailingWhitespace": true 25 | }, 26 | "ansible.python.interpreterPath": "/usr/bin/python3", 27 | "ansible.validation.enabled": true, 28 | "editor.tabSize": 2, 29 | "files.associations": { 30 | "*.gotmpl": "helm", 31 | "*.j2": "ansible-jinja", 32 | "*.yaml": "ansible", 33 | "*.yml": "ansible", 34 | "**/.github/workflows/*.yml": "github-actions-workflow", 35 | "**/renovate.json5": "jsonc" 36 | }, 37 | "files.exclude": { 38 | "**/.git": true, 39 | "**/.DS_Store": true 40 | }, 41 | "files.watcherExclude": { 42 | "**/.git/objects/**": true, 43 | "**/.git/subtree-cache/**": true 44 | }, 45 | "json.schemas": [ 46 | { 47 | "fileMatch": [ 48 | "renovate.json5" 49 | ], 50 | "url": "https://docs.renovatebot.com/renovate-schema.json" 51 | } 52 | ], 53 | "yaml.schemas": { 54 | "https://json.schemastore.org/github-workflow.json": ".github/workflows/*.yml" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Community Code of Conduct 2 | 3 | This is Code of Conduct is based on the [CNCF Code of 4 | Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). 5 | See the referred document for translated versions into different languages. 6 | 7 | ### Contributor Code of Conduct 8 | 9 | As contributors and maintainers of this project, and in the interest of fostering 10 | an open and welcoming community, we pledge to respect all people who contribute 11 | through reporting issues, posting feature requests, updating documentation, 12 | submitting pull requests or patches, and other activities. 13 | 14 | We are committed to making participation in this project a harassment-free 15 | experience for everyone, regardless of level of experience, gender, 16 | sexual orientation, disability, personal appearance, body size, race, ethnicity, 17 | age, religion, or nationality. 18 | 19 | Examples of unacceptable behavior by participants include: 20 | 21 | * The use of sexualized language or imagery 22 | * Personal attacks 23 | * Trolling or insulting/derogatory comments 24 | * Public or private harassment 25 | * Publishing others' private information, without explicit permission 26 | * Other unethical or unprofessional conduct 27 | 28 | Project maintainers have the right and responsibility to remove, edit, or reject 29 | comments, commits, code, wiki edits, issues, and other contributions that are not 30 | aligned to this Code of Conduct. By adopting this Code of Conduct, 31 | project maintainers commit themselves to fairly and consistently applying these 32 | principles to every aspect of managing this project. Project maintainers who 33 | do not follow or enforce the Code of Conduct may be permanently removed from 34 | the project team. 35 | 36 | This code of conduct applies both within project spaces and in public spaces 37 | when an individual is representing the project or its community. 38 | 39 | ### Acknowledgements 40 | 41 | This Code of Conduct is adapted from the Contributor Covenant 42 | (http://contributor-covenant.org), version 2.0 available at 43 | http://contributor-covenant.org/version/2/0/code_of_conduct/. 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024, AXIVO 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AXIVO K3s Cluster 2 | 3 | 4 | AXIVO K3s high-availability cluster, deployed with Ansible 5 | 6 | 7 | [![Ubuntu](https://img.shields.io/badge/Ubuntu-LTS-orange?style=flat&logo=ubuntu&logoColor=white)](https://ubuntu.com/) 8 | [![Helm](https://img.shields.io/badge/Helm-v3-0F1689?style=flat&logo=helm&logoColor=white)](https://helm.sh) 9 | [![Kubernetes](https://img.shields.io/badge/kubernetes-%23326ce5.svg?style=flat&logo=kubernetes&logoColor=white)](https://kubernetes.io) 10 | [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg?style=flat&logo=opensourceinitiative&logoColor=white)](https://github.com/axivo/k3s-cluster/blob/main/LICENSE) 11 | 12 | ### Introduction 13 | 14 | This project provides a comprehensive framework for deploying and managing production-ready Kubernetes clusters on bare-metal and virtual machines. It leverages Ansible automation to create resilient, fully automated K3s environments with minimal configuration effort. 15 | 16 | The automation is built around a collection of specialized Ansible roles that handle every aspect of the cluster lifecycle, from initial deployment and configuration to ongoing maintenance and upgrades. 17 | 18 | ### Key Features 19 | 20 | - **Core Infrastructure**: Fully automated K3s installation on Ubuntu LTS with embedded `etcd` for high availability and HAProxy with Keepalived for Kubernetes API server load balancing 21 | - **Advanced Networking**: Cilium CNI for eBPF-based networking, replacing `kube-proxy` with optimized service load balancing and Gateway API for ingress 22 | - **DNS Management**: CoreDNS for internal cluster DNS resolution and ExternalDNS for automatic external DNS record synchronization 23 | - **Package Management**: Helm for simplified application deployment and management 24 | - **Security**: TLS certificate management via `cert-manager` with automatic renewal and integration with external DNS providers 25 | - **Storage**: Distributed block storage with Longhorn providing volume replication and backup capabilities 26 | - **Observability**: Complete monitoring stack with Metrics Server for core resource metrics, VictoriaMetrics for advanced metrics collection, AlertManager for alert handling and routing, VictoriaLogs for centralized logging, and Grafana for visualization 27 | - **GitOps**: ArgoCD for declarative application deployment following GitOps principles 28 | - **Maintenance**: Coordinated node updates with Kured for minimizing disruption during system maintenance 29 | 30 | ### Documentation 31 | 32 | Visit the [Wiki](https://axivo.com/k3s-cluster) (powered by [Hextra](https://github.com/imfing/hextra)), for detailed configuration instructions. 33 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | callback_result_format = yaml 3 | callbacks_enabled = ansible.posix.profile_tasks 4 | display_skipped_hosts = false 5 | host_key_checking = false 6 | interpreter_python = auto_silent 7 | inventory = ./inventory/cluster/hosts.yaml 8 | -------------------------------------------------------------------------------- /collections/requirements.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: ansible.posix 4 | version: '>=1.6.0' 5 | - name: ansible.utils 6 | version: '>=5.1.0' 7 | - name: kubernetes.core 8 | version: '>=5.1.0' 9 | -------------------------------------------------------------------------------- /inventory/cluster/hosts.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | hosts: 3 | apollo: 4 | boreas: 5 | cerus: 6 | 7 | agent: 8 | hosts: 9 | chaos: 10 | crios: 11 | helios: 12 | hermes: 13 | hypnos: 14 | 15 | cluster: 16 | children: 17 | server: 18 | agent: 19 | -------------------------------------------------------------------------------- /provisioning.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Tags Validation 3 | hosts: localhost 4 | become: false 5 | gather_facts: false 6 | tasks: 7 | - name: Validate tags 8 | ansible.builtin.fail: 9 | msg: | 10 | Improper usage of '--tags' flag: 11 | {% set invalid_tags = ansible_run_tags | difference(global_map.tags.play) %} 12 | {% if invalid_tags | length > 0 %} 13 | - invalid tag{% if invalid_tags | length > 1 %}s{% endif %}: {{ invalid_tags | join(', ') }} 14 | {% endif %} 15 | - valid tags: {{ global_map.tags.play | join(', ') }} 16 | tags: always 17 | when: 18 | - ansible_run_tags not in [[], ['all']] 19 | - ansible_run_tags | difference(global_map.tags.play) | length > 0 20 | 21 | - name: Cluster Provisioning 22 | hosts: cluster 23 | become: true 24 | gather_facts: true 25 | roles: 26 | - cluster 27 | tags: cluster 28 | 29 | - name: LoadBalancer Provisioning 30 | hosts: cluster 31 | become: true 32 | gather_facts: true 33 | tags: 34 | - cluster 35 | - kubernetes 36 | tasks: 37 | - name: Setup loadbalancer 38 | ansible.builtin.import_role: 39 | name: k3s 40 | tasks_from: loadbalancer 41 | 42 | - name: Kubernetes Provisioning 43 | hosts: cluster 44 | become: true 45 | gather_facts: true 46 | roles: 47 | - helm 48 | - k3s 49 | serial: 50 | - 1 51 | - 2 52 | - 5 53 | tags: kubernetes 54 | 55 | - name: Charts Provisioning 56 | hosts: server 57 | become: true 58 | gather_facts: true 59 | post_tasks: 60 | - name: Perform post-install tasks 61 | ansible.builtin.include_role: 62 | name: '{{ postinstall }}' 63 | tasks_from: postinstall 64 | loop: 65 | - argo-cd 66 | - cert-manager 67 | - cilium 68 | - coredns 69 | - external-dns 70 | - kured 71 | - longhorn 72 | - metrics-server 73 | - victoria-logs 74 | loop_control: 75 | loop_var: postinstall 76 | roles: 77 | - cilium 78 | - coredns 79 | - cert-manager 80 | - external-dns 81 | - argo-cd 82 | - kured 83 | - longhorn 84 | - metrics-server 85 | - victoria-logs 86 | - victoria-metrics 87 | tags: charts 88 | -------------------------------------------------------------------------------- /reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Cluster Reset 3 | hosts: cluster 4 | become: true 5 | gather_facts: true 6 | serial: 7 | - 3 8 | - 5 9 | post_tasks: 10 | - name: Remove archived journal files 11 | ansible.builtin.command: 12 | cmd: journalctl --rotate --vacuum-time=1s 13 | changed_when: false 14 | tasks: 15 | - name: Get packages information 16 | ansible.builtin.package_facts: 17 | tags: always 18 | 19 | - name: Reset cluster 20 | ansible.builtin.include_role: 21 | apply: 22 | tags: '{{ reset }}' 23 | name: '{{ reset }}' 24 | tasks_from: reset 25 | loop: 26 | - cluster 27 | - k3s 28 | - argo-cd 29 | - cert-manager 30 | - cilium 31 | - coredns 32 | - external-dns 33 | - kured 34 | - longhorn 35 | - metrics-server 36 | - victoria-logs 37 | - victoria-metrics 38 | - helm 39 | loop_control: 40 | loop_var: reset 41 | tags: always 42 | when: (ansible_run_tags == ['all']) or (reset in ansible_run_tags) 43 | vars_prompt: 44 | - name: prompt_remove_packages 45 | prompt: Remove installed apt packages? [Y/n] 46 | default: 'n' 47 | private: false 48 | -------------------------------------------------------------------------------- /roles/argo-cd/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: argo-cd 3 | description: Documentation generator for argo-cd Ansible role 4 | home: https://github.com/argoproj/argo-helm 5 | version: 7.8.28 6 | dependencies: 7 | - name: argocd 8 | repository: https://github.com/argoproj/argo-cd 9 | version: 2.14.11 10 | -------------------------------------------------------------------------------- /roles/argo-cd/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name | replace "-" "" -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/argocd), for additional details. 12 | 13 | ## Role Dependencies 14 | 15 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 26 | 27 | {{ template "chart.valuesTable" . }} 28 | -------------------------------------------------------------------------------- /roles/argo-cd/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | argocd_map: 5 | credentials: 6 | server: 7 | admin: 8 | password: "{{ global_map.credentials.argocd.server.admin.password | string | password_hash('blowfish') }}" 9 | user: 10 | name: '{{ global_map.credentials.argocd.server.user.name }}' 11 | password: "{{ global_map.credentials.argocd.server.user.password | string | password_hash('blowfish') }}" 12 | ingress: 13 | class: 14 | name: cilium 15 | server: 16 | annotations: 17 | api: 18 | cert-manager.io/cluster-issuer: '{{ externaldns_project.cloudflare.cluster.issuer }}' 19 | grpc: 20 | cert-manager.io/cluster-issuer: '{{ externaldns_project.cloudflare.cluster.issuer }}' 21 | ingress.cilium.io/tls-passthrough: enabled 22 | hostname: '{{ argocd_vars.kubernetes.server.ingress.subdomain }}.{{ externaldns_vars.cloudflare.host.domain }}' 23 | helm: 24 | chart: 25 | reference: '{{ argocd_vars.kubernetes.helm.repository.org }}/{{ argocd_vars.kubernetes.helm.chart.name }}' 26 | version: '{{ argocd_vars.kubernetes.helm.chart.version[1:] }}' 27 | platform: 28 | key: https://github.com 29 | raw: https://raw.githubusercontent.com 30 | repository: 31 | name: '{{ argocd_vars.kubernetes.helm.repository.org }}/{{ argocd_vars.kubernetes.helm.repository.name }}' 32 | url: '{{ argocd_vars.kubernetes.helm.repository.url }}/{{ argocd_vars.kubernetes.helm.repository.name }}' 33 | timeout: 10m0s 34 | metrics: 35 | service: 36 | monitor: 37 | enabled: true 38 | scrape: 39 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 40 | interval: null 41 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 42 | timeout: null 43 | run_once: true 44 | 45 | - name: Set project fact 46 | ansible.builtin.set_fact: 47 | argocd_project: 48 | release: 49 | checksum: '{{ argocd_vars.release.version }}/{{ argocd_vars.release.checksum }}' 50 | file: '{{ argocd_vars.release.version }}/{{ argocd_vars.release.file }}' 51 | url: "{{ 52 | '/'.join([argocd_map.helm.platform.key, 53 | argocd_vars.release.repository.org, 54 | argocd_vars.release.repository.name, 'releases', 'download']) 55 | }}" 56 | tag: '{{ argocd_vars.kubernetes.helm.chart.name }}-{{ argocd_map.helm.chart.version }}' 57 | url: '{{ argocd_map.helm.platform.key }}/{{ argocd_map.helm.repository.name }}/releases/tag' 58 | run_once: true 59 | 60 | - name: Set resources fact 61 | ansible.builtin.set_fact: 62 | argocd_resources: 63 | server: 64 | users: 65 | - name: '{{ argocd_map.credentials.server.user.name }}' 66 | password: '{{ argocd_map.credentials.server.user.password }}' 67 | permissions: 'apiKey, login' 68 | role: admin 69 | enabled: true 70 | -------------------------------------------------------------------------------- /roles/argo-cd/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Set checksums fact 17 | ansible.builtin.uri: 18 | url: '{{ argocd_project.release.url }}/{{ argocd_project.release.checksum }}' 19 | return_content: true 20 | register: checksums 21 | delay: 1 22 | retries: 3 23 | until: checksums is not failed 24 | check_mode: false 25 | run_once: true 26 | 27 | - name: Set sha256 checksum fact 28 | ansible.builtin.set_fact: 29 | sha256_checksum: "{{ item.split(' ')[0] }}" 30 | loop: "{{ checksums.content.split('\n') }}" 31 | when: item | regex_search(argocd_vars.release.file + '$') 32 | run_once: true 33 | 34 | - name: Install binary 35 | ansible.builtin.get_url: 36 | url: '{{ argocd_project.release.url }}/{{ argocd_project.release.file }}' 37 | checksum: sha256:{{ sha256_checksum }} 38 | dest: '{{ k3s_map.node.directory.bin }}/argocd' 39 | owner: root 40 | group: root 41 | mode: '755' 42 | register: result 43 | delay: 1 44 | retries: 3 45 | until: result is not failed 46 | 47 | - name: Add repository 48 | kubernetes.core.helm_repository: 49 | name: '{{ argocd_vars.kubernetes.helm.repository.org }}' 50 | repo_url: '{{ argocd_map.helm.repository.url }}' 51 | force_update: true 52 | 53 | - name: Chart Setup 54 | run_once: true 55 | block: 56 | - name: Set chart postinstall fact 57 | ansible.builtin.set_fact: 58 | argocd_postinstall: false 59 | 60 | - name: Install chart 61 | kubernetes.core.helm: 62 | chart_ref: '{{ argocd_map.helm.chart.reference }}' 63 | chart_version: '{{ argocd_vars.kubernetes.helm.chart.version }}' 64 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 65 | name: '{{ argocd_vars.kubernetes.helm.chart.name }}' 66 | namespace: '{{ argocd_vars.kubernetes.namespace }}' 67 | timeout: '{{ argocd_map.helm.timeout }}' 68 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 69 | create_namespace: true 70 | update_repo_cache: true 71 | wait: true 72 | register: result 73 | delay: 1 74 | retries: 3 75 | until: result is not failed 76 | -------------------------------------------------------------------------------- /roles/argo-cd/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: inventory_hostname in k3s_map.server.hosts 4 | run_once: true 5 | block: 6 | - name: Metrics Setup 7 | when: argocd_map.metrics.service.monitor.enabled is truthy 8 | block: 9 | - name: Update chart postinstall fact 10 | ansible.builtin.set_fact: 11 | argocd_postinstall: true 12 | 13 | - name: Update chart postinstall values 14 | kubernetes.core.helm: 15 | chart_ref: '{{ argocd_map.helm.chart.reference }}' 16 | chart_version: '{{ argocd_vars.kubernetes.helm.chart.version }}' 17 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 18 | name: '{{ argocd_vars.kubernetes.helm.chart.name }}' 19 | namespace: '{{ argocd_vars.kubernetes.namespace }}' 20 | timeout: '{{ argocd_map.helm.timeout }}' 21 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 22 | reset_values: false 23 | reuse_values: true 24 | wait: true 25 | register: result 26 | delay: 1 27 | retries: 3 28 | until: result is not failed 29 | 30 | - name: Update server user credentials 31 | kubernetes.core.k8s: 32 | definition: "{{ lookup('ansible.builtin.template', 'credentials.j2') | from_yaml }}" 33 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 34 | wait: true 35 | no_log: true 36 | -------------------------------------------------------------------------------- /roles/argo-cd/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ argocd_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | 16 | - name: Remove binary file 17 | ansible.builtin.file: 18 | path: '{{ k3s_map.node.directory.bin }}/argocd' 19 | state: absent 20 | -------------------------------------------------------------------------------- /roles/argo-cd/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/argo-cd/templates/config_cm.j2: -------------------------------------------------------------------------------- 1 | {# 2 | ArgoCD ConfigMap 3 | Manual: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cm.yaml 4 | #} 5 | 6 | admin.enabled: {{ argocd_vars.kubernetes.configs.cm.admin.enabled | lower }} 7 | exec.enabled: {{ argocd_vars.kubernetes.configs.cm.exec.enabled | lower }} 8 | statusbadge.enabled: {{ argocd_vars.kubernetes.configs.cm.status_badge.enabled | lower }} 9 | resource.exclusions: | 10 | - apiGroups: 11 | - cilium.io 12 | - snapshot.storage.k8s.io 13 | kinds: 14 | - CiliumClusterwideNetworkPolicy 15 | - CiliumIdentity 16 | - CiliumNetworkPolicy 17 | - VolumeSnapshot 18 | - VolumeSnapshotContent 19 | clusters: 20 | - "*" 21 | 22 | {# See https://argo-cd.readthedocs.io/en/stable/operator-manual/health/#argocd-app 23 | resource.customizations.health.argoproj.io_Application: | 24 | health = {} 25 | health.message = "" 26 | health.status = "Progressing" 27 | if obj.status ~= nil then 28 | if obj.status.health ~= nil then 29 | health.status = obj.status.health.status 30 | if obj.status.health.message ~= nil then 31 | health.message = obj.status.health.message 32 | end 33 | end 34 | end 35 | return health 36 | #} 37 | -------------------------------------------------------------------------------- /roles/argo-cd/templates/config_params.j2: -------------------------------------------------------------------------------- 1 | {# 2 | ArgoCD Parameters 3 | Manual: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cmd-params-cm.yaml 4 | #} 5 | 6 | application.namespaces: {{ argocd_vars.kubernetes.configs.params.application.namespaces | join(', ') }} 7 | applicationsetcontroller.enable.git.submodule: {{ argocd_vars.kubernetes.configs.params.applicationsetcontroller.git.submodule.enabled | lower }} 8 | applicationsetcontroller.enable.new.git.file.globbing: {{ argocd_vars.kubernetes.configs.params.applicationsetcontroller.git.new_file_globbing.enabled | lower }} 9 | applicationsetcontroller.enable.progressive.syncs: {{ argocd_vars.kubernetes.configs.params.applicationsetcontroller.progressive_syncs.enabled | lower }} 10 | applicationsetcontroller.log.level: {{ argocd_vars.kubernetes.configs.params.applicationsetcontroller.log_level }} 11 | controller.log.level: {{ argocd_vars.kubernetes.configs.params.controller.log_level }} 12 | controller.sharding.algorithm: {{ argocd_vars.kubernetes.configs.params.controller.sharding.algorithm }} 13 | dexserver.log.level: {{ argocd_vars.kubernetes.configs.params.dexserver.log_level }} 14 | notificationscontroller.log.level: {{ argocd_vars.kubernetes.configs.params.notificationscontroller.log_level }} 15 | reposerver.log.level: {{ argocd_vars.kubernetes.configs.params.reposerver.log_level }} 16 | server.insecure: {{ argocd_vars.kubernetes.configs.params.server.insecure | lower }} 17 | server.log.level: {{ argocd_vars.kubernetes.configs.params.server.log_level }} 18 | -------------------------------------------------------------------------------- /roles/argo-cd/templates/config_rbac.j2: -------------------------------------------------------------------------------- 1 | {# 2 | ArgoCD RBAC 3 | Manual: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-rbac-cm.yaml 4 | #} 5 | 6 | policy.csv: | 7 | {% for user in argocd_resources.server.users %} 8 | {{ ', '.join(['g', user.name, 'role']) | indent(2) }}:{{ user.role }} 9 | {% endfor %} 10 | policy.default: role:readonly 11 | -------------------------------------------------------------------------------- /roles/argo-cd/templates/credentials.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: argocd-secret 5 | namespace: {{ argocd_vars.kubernetes.namespace }} 6 | labels: 7 | app.kubernetes.io/name: argocd-secret 8 | app.kubernetes.io/part-of: argocd 9 | data: 10 | {% for user in argocd_resources.server.users %} 11 | {{ '.'.join(['accounts', user.name, 'password']) | indent(2) }}: >- 12 | {{ user.password | b64encode | indent(4) }} 13 | {{ '.'.join(['accounts', user.name, 'passwordMtime']) | indent(2) }}: {{ ansible_date_time.iso8601 | b64encode }} 14 | {% endfor %} 15 | -------------------------------------------------------------------------------- /roles/cert-manager/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cert-manager 3 | description: Documentation generator for cert-manager Ansible role 4 | home: https://github.com/cert-manager/cert-manager 5 | version: 1.17.2 6 | dependencies: 7 | - name: cmctl 8 | repository: https://github.com/cert-manager/cmctl 9 | version: 2.1.1 10 | -------------------------------------------------------------------------------- /roles/cert-manager/README.md: -------------------------------------------------------------------------------- 1 | # cert-manager 2 | 3 | ![Version: 1.17.2](https://img.shields.io/badge/Version-1.17.2-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `cert-manager` [chart](https://github.com/cert-manager/cert-manager/tree/v1.17.2/deploy/charts/cert-manager) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/certmanager), for additional details. 6 | 7 | ## Role Dependencies 8 | 9 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 10 | 11 | | Repository | Name | Version | 12 | |------------|------|---------| 13 | | https://github.com/cert-manager/cmctl | cmctl | 2.1.1 | 14 | 15 | ## Role Variables 16 | 17 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `certmanager_map` collection. 18 | 19 | > [!TIP] 20 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 21 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 22 | 23 | | Key | Type | Default | Description | 24 | |-----|------|---------|-------------| 25 | | certmanager_vars.kubernetes.cainjector.resources.limits.cpu | string | `nil` | | 26 | | certmanager_vars.kubernetes.cainjector.resources.limits.memory | string | `"128Mi"` | | 27 | | certmanager_vars.kubernetes.cainjector.resources.requests.cpu | string | `"10m"` | | 28 | | certmanager_vars.kubernetes.cainjector.resources.requests.memory | string | `"128Mi"` | | 29 | | certmanager_vars.kubernetes.controller.replicas | int | `2` | | 30 | | certmanager_vars.kubernetes.controller.resources.limits.cpu | string | `nil` | | 31 | | certmanager_vars.kubernetes.controller.resources.limits.memory | string | `"128Mi"` | | 32 | | certmanager_vars.kubernetes.controller.resources.requests.cpu | string | `"10m"` | | 33 | | certmanager_vars.kubernetes.controller.resources.requests.memory | string | `"128Mi"` | | 34 | | certmanager_vars.kubernetes.global.log_level | int | `2` | | 35 | | certmanager_vars.kubernetes.helm.chart.name | string | `"cert-manager"` | | 36 | | certmanager_vars.kubernetes.helm.chart.version | string | `"v1.17.2"` | | 37 | | certmanager_vars.kubernetes.helm.repository.name | string | `"cert-manager"` | | 38 | | certmanager_vars.kubernetes.helm.repository.org | string | `"jetstack"` | | 39 | | certmanager_vars.kubernetes.helm.repository.url | string | `"https://charts.jetstack.io"` | | 40 | | certmanager_vars.kubernetes.namespace | string | `"kube-system"` | | 41 | | certmanager_vars.kubernetes.webhook.replicas | int | `1` | | 42 | | certmanager_vars.kubernetes.webhook.resources.limits.cpu | string | `nil` | | 43 | | certmanager_vars.kubernetes.webhook.resources.limits.memory | string | `"128Mi"` | | 44 | | certmanager_vars.kubernetes.webhook.resources.requests.cpu | string | `"10m"` | | 45 | | certmanager_vars.kubernetes.webhook.resources.requests.memory | string | `"128Mi"` | | 46 | | certmanager_vars.release.checksum | string | `"checksums.txt"` | | 47 | | certmanager_vars.release.file | string | `"cmctl_linux_arm64"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details | 48 | | certmanager_vars.release.repository.name | string | `"cmctl"` | | 49 | | certmanager_vars.release.repository.org | string | `"cert-manager"` | | 50 | | certmanager_vars.release.version | string | `"v2.1.1"` | | 51 | -------------------------------------------------------------------------------- /roles/cert-manager/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/v%s/deploy/charts/%s" .Home .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name | replace "-" "" -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/certmanager), for additional details. 12 | 13 | ## Role Dependencies 14 | 15 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 26 | 27 | {{ template "chart.valuesTable" . }} 28 | -------------------------------------------------------------------------------- /roles/cert-manager/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | certmanager_vars: 3 | kubernetes: 4 | cainjector: 5 | resources: 6 | limits: 7 | cpu: null 8 | memory: 128Mi 9 | requests: 10 | cpu: 10m 11 | memory: 128Mi 12 | controller: 13 | replicas: 2 14 | resources: 15 | limits: 16 | cpu: null 17 | memory: 128Mi 18 | requests: 19 | cpu: 10m 20 | memory: 128Mi 21 | helm: 22 | chart: 23 | name: cert-manager 24 | version: v1.17.2 25 | repository: 26 | name: cert-manager 27 | org: jetstack 28 | url: https://charts.jetstack.io 29 | global: 30 | log_level: 2 31 | namespace: kube-system 32 | webhook: 33 | replicas: 1 34 | resources: 35 | limits: 36 | cpu: null 37 | memory: 128Mi 38 | requests: 39 | cpu: 10m 40 | memory: 128Mi 41 | release: 42 | checksum: checksums.txt 43 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details 44 | file: cmctl_linux_arm64 45 | repository: 46 | name: cmctl 47 | org: cert-manager 48 | version: v2.1.1 49 | -------------------------------------------------------------------------------- /roles/cert-manager/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | certmanager_map: 5 | ca: 6 | cluster: 7 | issuer: 8 | name: '{{ certmanager_vars.kubernetes.helm.chart.name }}-cluster-issuer' 9 | helm: 10 | chart: 11 | reference: '{{ certmanager_vars.kubernetes.helm.repository.org }}/{{ certmanager_vars.kubernetes.helm.chart.name }}' 12 | platform: 13 | key: https://github.com 14 | raw: https://raw.githubusercontent.com 15 | repository: 16 | name: '{{ certmanager_vars.kubernetes.helm.repository.name }}/{{ certmanager_vars.kubernetes.helm.chart.name }}' 17 | url: '{{ certmanager_vars.kubernetes.helm.repository.url }}/{{ certmanager_vars.kubernetes.helm.repository.name }}' 18 | timeout: 5m0s 19 | metrics: 20 | service: 21 | monitor: 22 | enabled: true 23 | scrape: 24 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 25 | interval: null 26 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 27 | timeout: null 28 | run_once: true 29 | 30 | - name: Set project fact 31 | ansible.builtin.set_fact: 32 | certmanager_project: 33 | release: 34 | checksum: '{{ certmanager_vars.release.version }}/{{ certmanager_vars.release.checksum }}' 35 | file: '{{ certmanager_vars.release.version }}/{{ certmanager_vars.release.file }}' 36 | url: "{{ 37 | '/'.join([certmanager_map.helm.platform.key, 38 | certmanager_vars.release.repository.org, 39 | certmanager_vars.release.repository.name, 'releases', 'download']) 40 | }}" 41 | tag: '{{ certmanager_vars.kubernetes.helm.chart.version }}' 42 | url: '{{ certmanager_map.helm.platform.key }}/{{ certmanager_map.helm.repository.name }}/releases/tag' 43 | run_once: true 44 | 45 | - name: Set variables fact 46 | ansible.builtin.set_fact: 47 | certmanager_vars: '{{ certmanager_vars }}' 48 | run_once: true 49 | -------------------------------------------------------------------------------- /roles/cert-manager/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Set checksums fact 17 | ansible.builtin.uri: 18 | url: '{{ certmanager_project.release.url }}/{{ certmanager_project.release.checksum }}' 19 | return_content: true 20 | register: checksums 21 | delay: 1 22 | retries: 3 23 | until: checksums is not failed 24 | check_mode: false 25 | run_once: true 26 | 27 | - name: Set sha256 checksum fact 28 | ansible.builtin.set_fact: 29 | sha256_checksum: "{{ item.split(' ')[0] }}" 30 | loop: "{{ checksums.content.split('\n') }}" 31 | when: item | regex_search(certmanager_vars.release.file + '$') 32 | run_once: true 33 | 34 | - name: Install binary 35 | ansible.builtin.get_url: 36 | url: '{{ certmanager_project.release.url }}/{{ certmanager_project.release.file }}' 37 | checksum: sha256:{{ sha256_checksum }} 38 | dest: '{{ k3s_map.node.directory.bin }}/cmctl' 39 | owner: root 40 | group: root 41 | mode: '755' 42 | register: result 43 | delay: 1 44 | retries: 3 45 | until: result is not failed 46 | 47 | - name: Create symlink 48 | ansible.builtin.file: 49 | path: '{{ k3s_map.node.directory.bin }}/kubectl-cert_manager' 50 | src: '{{ k3s_map.node.directory.bin }}/cmctl' 51 | state: link 52 | 53 | - name: Add repository 54 | kubernetes.core.helm_repository: 55 | name: '{{ certmanager_vars.kubernetes.helm.repository.org }}' 56 | repo_url: '{{ certmanager_vars.kubernetes.helm.repository.url }}' 57 | force_update: true 58 | 59 | - name: Chart Setup 60 | run_once: true 61 | block: 62 | - name: Set chart postinstall fact 63 | ansible.builtin.set_fact: 64 | certmanager_postinstall: false 65 | 66 | - name: Install chart 67 | kubernetes.core.helm: 68 | chart_ref: '{{ certmanager_map.helm.chart.reference }}' 69 | chart_version: '{{ certmanager_vars.kubernetes.helm.chart.version }}' 70 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 71 | name: '{{ certmanager_vars.kubernetes.helm.chart.name }}' 72 | namespace: '{{ certmanager_vars.kubernetes.namespace }}' 73 | timeout: '{{ certmanager_map.helm.timeout }}' 74 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 75 | create_namespace: true 76 | update_repo_cache: true 77 | wait: true 78 | register: result 79 | delay: 1 80 | retries: 3 81 | until: result is not failed 82 | 83 | - name: Create self-signed cluster issuer 84 | kubernetes.core.k8s: 85 | definition: "{{ lookup('ansible.builtin.template', 'cluster_issuer.j2') | from_yaml }}" 86 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 87 | wait: true 88 | -------------------------------------------------------------------------------- /roles/cert-manager/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: 4 | - inventory_hostname in k3s_map.server.hosts 5 | - certmanager_map.metrics.service.monitor.enabled 6 | run_once: true 7 | block: 8 | - name: Update chart postinstall fact 9 | ansible.builtin.set_fact: 10 | certmanager_postinstall: true 11 | 12 | - name: Update chart postinstall values 13 | kubernetes.core.helm: 14 | chart_ref: '{{ certmanager_map.helm.chart.reference }}' 15 | chart_version: '{{ certmanager_vars.kubernetes.helm.chart.version }}' 16 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 17 | name: '{{ certmanager_vars.kubernetes.helm.chart.name }}' 18 | namespace: '{{ certmanager_vars.kubernetes.namespace }}' 19 | timeout: '{{ certmanager_map.helm.timeout }}' 20 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 21 | reset_values: false 22 | reuse_values: true 23 | wait: true 24 | register: result 25 | delay: 1 26 | retries: 3 27 | until: result is not failed 28 | -------------------------------------------------------------------------------- /roles/cert-manager/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ certmanager_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | 16 | - name: Remove binary files 17 | ansible.builtin.file: 18 | path: '{{ k3s_map.node.directory.bin }}/{{ item }}' 19 | state: absent 20 | loop: 21 | - cmctl 22 | - kubectl-cert_manager 23 | -------------------------------------------------------------------------------- /roles/cert-manager/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/cert-manager/templates/cluster_issuer.j2: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: {{ certmanager_map.ca.cluster.issuer.name }} 5 | spec: 6 | selfSigned: {} 7 | -------------------------------------------------------------------------------- /roles/cert-manager/templates/config_controller.j2: -------------------------------------------------------------------------------- 1 | {# 2 | Controller Configuration 3 | Manual: https://cert-manager.io/docs/cli/controller 4 | #} 5 | 6 | enableGatewayAPI: true 7 | -------------------------------------------------------------------------------- /roles/cert-manager/templates/values.j2: -------------------------------------------------------------------------------- 1 | global: 2 | leaderElection: 3 | namespace: {{ certmanager_vars.kubernetes.namespace }} 4 | logLevel: {{ certmanager_vars.kubernetes.global.log_level }} 5 | cainjector: 6 | podDisruptionBudget: 7 | enabled: true 8 | maxUnavailable: 1 9 | resources: 10 | limits: 11 | {% if certmanager_vars.kubernetes.cainjector.resources.limits.cpu is truthy %} 12 | cpu: {{ certmanager_vars.kubernetes.cainjector.resources.limits.cpu }} 13 | {% endif %} 14 | memory: {{ certmanager_vars.kubernetes.cainjector.resources.limits.memory }} 15 | requests: 16 | cpu: {{ certmanager_vars.kubernetes.cainjector.resources.requests.cpu }} 17 | memory: {{ certmanager_vars.kubernetes.cainjector.resources.requests.memory }} 18 | strategy: 19 | rollingUpdate: 20 | maxSurge: 1 21 | maxUnavailable: 0 22 | type: RollingUpdate 23 | config: 24 | {{ lookup('ansible.builtin.template', 'config_controller.j2') | trim | indent(2) }} 25 | crds: 26 | enabled: true 27 | keep: false 28 | podDisruptionBudget: 29 | enabled: true 30 | maxUnavailable: 1 31 | {% if certmanager_postinstall is truthy and certmanager_map.metrics.service.monitor.enabled is truthy %} 32 | prometheus: 33 | servicemonitor: 34 | enabled: true 35 | {% if certmanager_map.metrics.service.monitor.scrape.interval is falsy %} 36 | interval: {{ victoriametrics_map.service.monitor.scrape.interval }} 37 | {% else %} 38 | interval: {{ certmanager_map.metrics.service.monitor.scrape.interval }} 39 | {% endif %} 40 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 41 | {% if certmanager_map.metrics.service.monitor.scrape.timeout is falsy %} 42 | scrapeTimeout: {{ victoriametrics_map.service.monitor.scrape.timeout }} 43 | {% else %} 44 | scrapeTimeout: {{ certmanager_map.metrics.service.monitor.scrape.timeout }} 45 | {% endif %} 46 | {% endif %} 47 | resources: 48 | limits: 49 | {% if certmanager_vars.kubernetes.controller.resources.limits.cpu is truthy %} 50 | cpu: {{ certmanager_vars.kubernetes.controller.resources.limits.cpu }} 51 | {% endif %} 52 | memory: {{ certmanager_vars.kubernetes.controller.resources.limits.memory }} 53 | requests: 54 | cpu: {{ certmanager_vars.kubernetes.controller.resources.requests.cpu }} 55 | memory: {{ certmanager_vars.kubernetes.controller.resources.requests.memory }} 56 | replicaCount: {{ certmanager_vars.kubernetes.controller.replicas }} 57 | strategy: 58 | rollingUpdate: 59 | maxSurge: 1 60 | maxUnavailable: 0 61 | type: RollingUpdate 62 | webhook: 63 | podDisruptionBudget: 64 | enabled: true 65 | maxUnavailable: 1 66 | replicaCount: {{ certmanager_vars.kubernetes.webhook.replicas }} 67 | resources: 68 | limits: 69 | {% if certmanager_vars.kubernetes.webhook.resources.limits.cpu is truthy %} 70 | cpu: {{ certmanager_vars.kubernetes.webhook.resources.limits.cpu }} 71 | {% endif %} 72 | memory: {{ certmanager_vars.kubernetes.webhook.resources.limits.memory }} 73 | requests: 74 | cpu: {{ certmanager_vars.kubernetes.webhook.resources.requests.cpu }} 75 | memory: {{ certmanager_vars.kubernetes.webhook.resources.requests.memory }} 76 | strategy: 77 | rollingUpdate: 78 | maxSurge: 1 79 | maxUnavailable: 0 80 | type: RollingUpdate 81 | -------------------------------------------------------------------------------- /roles/cilium/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cilium 3 | description: Documentation generator for cilium Ansible role 4 | home: https://github.com/cilium/cilium 5 | version: 1.17.3 6 | dependencies: 7 | - name: cilium-cli 8 | repository: https://github.com/cilium/cilium-cli 9 | version: 0.18.3 10 | - name: gateway-api 11 | repository: https://github.com/kubernetes-sigs/gateway-api 12 | version: 1.3.0 13 | - name: hubble 14 | repository: https://github.com/cilium/hubble 15 | version: 1.17.2 16 | -------------------------------------------------------------------------------- /roles/cilium/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/v%s/install/kubernetes/%s" .Home .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/cilium), for additional details. 12 | 13 | ## Role Dependencies 14 | 15 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 26 | 27 | {{ template "chart.valuesTable" . }} 28 | -------------------------------------------------------------------------------- /roles/cilium/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | cilium_map: 5 | ca: 6 | hubble: 7 | certificate: 8 | common: 9 | name: hubble-common-certs 10 | root: 11 | name: hubble-root-certs 12 | cluster: 13 | issuer: 14 | name: hubble-cluster-issuer 15 | helm: 16 | chart: 17 | reference: '{{ cilium_vars.kubernetes.helm.repository.org }}/{{ cilium_vars.kubernetes.helm.chart.name }}' 18 | platform: 19 | key: https://github.com 20 | raw: https://raw.githubusercontent.com 21 | repository: 22 | name: '{{ cilium_vars.kubernetes.helm.repository.org }}/{{ cilium_vars.kubernetes.helm.repository.name }}' 23 | url: '{{ cilium_vars.kubernetes.helm.repository.url }}' 24 | timeout: 5m0s 25 | gateway: 26 | hubble: 27 | ui: 28 | annotations: 29 | cert-manager.io/cluster-issuer: '{{ externaldns_project.cloudflare.cluster.issuer }}' 30 | hostname: '{{ cilium_vars.kubernetes.hubble.ui.gateway.subdomain }}.{{ externaldns_vars.cloudflare.host.domain }}' 31 | http_route: 32 | insecure: '{{ cilium_vars.kubernetes.hubble.ui.gateway.service }}-http' 33 | secure: '{{ cilium_vars.kubernetes.hubble.ui.gateway.service }}-https' 34 | metrics: 35 | service: 36 | monitor: 37 | enabled: true 38 | scrape: 39 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 40 | interval: 15s 41 | run_once: true 42 | 43 | - name: Set project fact 44 | ansible.builtin.set_fact: 45 | cilium_project: 46 | release: 47 | cli: 48 | file: '{{ cilium_vars.release.cli.version }}/{{ cilium_vars.release.cli.file }}' 49 | url: "{{ 50 | '/'.join([cilium_map.helm.platform.key, 51 | cilium_vars.release.cli.repository.org, 52 | cilium_vars.release.cli.repository.name, 'releases', 'download']) 53 | }}" 54 | gateway_api: 55 | file: '{{ cilium_vars.release.gateway_api.version }}/{{ cilium_vars.release.gateway_api.file }}' 56 | url: "{{ 57 | '/'.join([cilium_map.helm.platform.key, 58 | cilium_vars.release.gateway_api.repository.org, 59 | cilium_vars.release.gateway_api.repository.name, 'releases', 'download']) 60 | }}" 61 | hubble: 62 | file: '{{ cilium_vars.release.hubble.version }}/{{ cilium_vars.release.hubble.file }}' 63 | url: "{{ 64 | '/'.join([cilium_map.helm.platform.key, 65 | cilium_vars.release.hubble.repository.org, 66 | cilium_vars.release.hubble.repository.name, 'releases', 'download']) 67 | }}" 68 | tag: '{{ cilium_vars.kubernetes.helm.chart.version }}' 69 | url: '{{ cilium_map.helm.platform.key }}/{{ cilium_map.helm.repository.name }}/releases/tag' 70 | run_once: true 71 | 72 | - name: Set resources fact 73 | ansible.builtin.set_fact: 74 | cilium_resources: 75 | release: 76 | - file: '{{ cilium_vars.release.cli.file }}' 77 | url: '{{ cilium_project.release.cli.url }}/{{ cilium_project.release.cli.file }}' 78 | - file: '{{ cilium_vars.release.hubble.file }}' 79 | url: '{{ cilium_project.release.hubble.url }}/{{ cilium_project.release.hubble.file }}' 80 | run_once: true 81 | -------------------------------------------------------------------------------- /roles/cilium/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: inventory_hostname in k3s_map.server.hosts 4 | run_once: true 5 | block: 6 | - name: Hubble TLS Setup 7 | when: cilium_vars.kubernetes.hubble.tls.auto.method | lower == 'certmanager' 8 | block: 9 | - name: Create hubble certificate 10 | kubernetes.core.k8s: 11 | definition: "{{ lookup('ansible.builtin.template', 'certificate.j2') | from_yaml }}" 12 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 13 | wait: true 14 | 15 | - name: Create hubble cluster issuer 16 | kubernetes.core.k8s: 17 | definition: "{{ lookup('ansible.builtin.template', 'cluster_issuer.j2') | from_yaml }}" 18 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 19 | wait: true 20 | 21 | - name: Update chart setup fact 22 | ansible.builtin.set_fact: 23 | cilium_setup: false 24 | 25 | - name: Update chart postinstall fact 26 | ansible.builtin.set_fact: 27 | cilium_postinstall: true 28 | 29 | - name: Update chart postinstall values 30 | kubernetes.core.helm: 31 | chart_ref: '{{ cilium_map.helm.chart.reference }}' 32 | chart_version: '{{ cilium_vars.kubernetes.helm.chart.version }}' 33 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 34 | name: '{{ cilium_vars.kubernetes.helm.chart.name }}' 35 | namespace: '{{ cilium_vars.kubernetes.namespace }}' 36 | timeout: '{{ cilium_map.helm.timeout }}' 37 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 38 | reset_values: false 39 | reuse_values: true 40 | wait: true 41 | register: result 42 | delay: 1 43 | retries: 3 44 | until: result is not failed 45 | -------------------------------------------------------------------------------- /roles/cilium/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ cilium_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | 16 | - name: Remove binary files 17 | ansible.builtin.file: 18 | path: '{{ k3s_map.node.directory.bin }}/{{ item }}' 19 | state: absent 20 | loop: 21 | - cilium 22 | - hubble 23 | -------------------------------------------------------------------------------- /roles/cilium/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/cilium/templates/certificate.j2: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: {{ cilium_map.ca.hubble.certificate.common.name }} 5 | namespace: {{ certmanager_vars.kubernetes.namespace }} 6 | spec: 7 | commonName: {{ cilium_map.ca.hubble.certificate.common.name }} 8 | isCA: true 9 | issuerRef: 10 | group: cert-manager.io 11 | kind: ClusterIssuer 12 | name: {{ certmanager_map.ca.cluster.issuer.name }} 13 | privateKey: 14 | algorithm: ECDSA 15 | size: 256 16 | secretName: {{ cilium_map.ca.hubble.certificate.root.name }} 17 | -------------------------------------------------------------------------------- /roles/cilium/templates/cluster_issuer.j2: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: {{ cilium_map.ca.hubble.cluster.issuer.name }} 5 | spec: 6 | ca: 7 | secretName: {{ cilium_map.ca.hubble.certificate.root.name }} 8 | -------------------------------------------------------------------------------- /roles/cilium/templates/gateway.j2: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: Gateway 3 | metadata: 4 | annotations: 5 | {% for key, value in cilium_map.gateway.hubble.ui.annotations.items() %} 6 | {{ key | indent(4) }}: {{ value }} 7 | {% endfor %} 8 | name: {{ cilium_vars.kubernetes.hubble.ui.gateway.service }} 9 | namespace: {{ cilium_vars.kubernetes.namespace }} 10 | spec: 11 | gatewayClassName: cilium 12 | listeners: 13 | - allowedRoutes: 14 | kinds: 15 | - group: gateway.networking.k8s.io 16 | kind: HTTPRoute 17 | namespaces: 18 | from: Same 19 | hostname: {{ cilium_map.gateway.hubble.ui.hostname }} 20 | name: http 21 | port: 80 22 | protocol: HTTP 23 | - allowedRoutes: 24 | kinds: 25 | - group: gateway.networking.k8s.io 26 | kind: HTTPRoute 27 | namespaces: 28 | from: Same 29 | hostname: {{ cilium_map.gateway.hubble.ui.hostname }} 30 | name: https 31 | port: 443 32 | protocol: HTTPS 33 | tls: 34 | certificateRefs: 35 | - kind: Secret 36 | name: {{ externaldns_vars.cloudflare.prefix }}-{{ cilium_vars.kubernetes.hubble.ui.gateway.service }} 37 | mode: Terminate 38 | -------------------------------------------------------------------------------- /roles/cilium/templates/http_route_insecure.j2: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: HTTPRoute 3 | metadata: 4 | name: {{ cilium_map.gateway.hubble.ui.http_route.insecure }} 5 | namespace: {{ cilium_vars.kubernetes.namespace }} 6 | spec: 7 | hostnames: 8 | - {{ cilium_map.gateway.hubble.ui.hostname }} 9 | parentRefs: 10 | - kind: Gateway 11 | name: {{ cilium_vars.kubernetes.hubble.ui.gateway.service }} 12 | namespace: {{ cilium_vars.kubernetes.namespace }} 13 | sectionName: http 14 | rules: 15 | - filters: 16 | - requestRedirect: 17 | scheme: https 18 | statusCode: 301 19 | type: RequestRedirect 20 | -------------------------------------------------------------------------------- /roles/cilium/templates/http_route_secure.j2: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: HTTPRoute 3 | metadata: 4 | name: {{ cilium_map.gateway.hubble.ui.http_route.secure }} 5 | namespace: {{ cilium_vars.kubernetes.namespace }} 6 | spec: 7 | hostnames: 8 | - {{ cilium_map.gateway.hubble.ui.hostname }} 9 | parentRefs: 10 | - kind: Gateway 11 | name: {{ cilium_vars.kubernetes.hubble.ui.gateway.service }} 12 | namespace: {{ cilium_vars.kubernetes.namespace }} 13 | sectionName: https 14 | rules: 15 | - backendRefs: 16 | - kind: Service 17 | name: {{ cilium_vars.kubernetes.hubble.ui.gateway.service }} 18 | port: 80 19 | matches: 20 | - path: 21 | type: PathPrefix 22 | value: / 23 | -------------------------------------------------------------------------------- /roles/cilium/templates/l2_announcement_policy.j2: -------------------------------------------------------------------------------- 1 | apiVersion: cilium.io/v2alpha1 2 | kind: CiliumL2AnnouncementPolicy 3 | metadata: 4 | name: {{ cilium_vars.kubernetes.loadbalancer.l2_announcement_policy.name }} 5 | namespace: {{ cilium_vars.kubernetes.namespace }} 6 | spec: 7 | externalIPs: true 8 | interfaces: 9 | - {{ k3s_vars.network.interface }} 10 | loadBalancerIPs: true 11 | -------------------------------------------------------------------------------- /roles/cilium/templates/loadbalancer_ip_pool.j2: -------------------------------------------------------------------------------- 1 | apiVersion: cilium.io/v2alpha1 2 | kind: CiliumLoadBalancerIPPool 3 | metadata: 4 | name: {{ cilium_vars.kubernetes.loadbalancer.ip_pool.name }} 5 | namespace: {{ cilium_vars.kubernetes.namespace }} 6 | spec: 7 | blocks: 8 | - start: {{ cilium_vars.kubernetes.loadbalancer.ip_pool.blocks.start }} 9 | stop: {{ cilium_vars.kubernetes.loadbalancer.ip_pool.blocks.stop }} 10 | -------------------------------------------------------------------------------- /roles/cluster/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cluster 3 | description: Documentation generator for cluster Ansible role 4 | home: https://ubuntu.com/server 5 | version: 24.04.2 6 | -------------------------------------------------------------------------------- /roles/cluster/README.md: -------------------------------------------------------------------------------- 1 | # cluster 2 | 3 | ![Version: 24.04.2](https://img.shields.io/badge/Version-24.04.2-informational?style=flat-square) 4 | 5 | The role performs various tasks related to Ubuntu LTS OS based [cluster](https://ubuntu.com/server) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/cluster), for additional details. 6 | 7 | > [!IMPORTANT] 8 | > Read the [Ubuntu Server](https://axivo.com/k3s-cluster/tutorials/handbook/server/) tutorial, on bare-metal infrastructure. 9 | 10 | ## Role Variables 11 | 12 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `cluster_map` collection. 13 | 14 | > [!TIP] 15 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 16 | 17 | | Key | Type | Default | Description | 18 | |-----|------|---------|-------------| 19 | | cluster_vars.device.enabled | bool | `true` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#storage-devices), for details | 20 | | cluster_vars.device.id | string | `"2:2"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#deviceid), for details | 21 | | cluster_vars.device.name | string | `"ASMedia Technology"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#devicename), for details | 22 | | cluster_vars.hardware.architecture | string | `"aarch64"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details | 23 | | cluster_vars.hardware.product | string | `"Raspberry Pi"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardwareproduct), for details | 24 | | cluster_vars.service.bluetooth.enabled | bool | `false` | By default, related `apt` packages are not installed | 25 | | cluster_vars.service.cloud_init.enabled | bool | `false` | | 26 | | cluster_vars.service.postfix.enabled | bool | `true` | | 27 | | cluster_vars.service.postfix.protocols | string | `"ipv4"` | | 28 | | cluster_vars.service.postfix.relay.host | string | `"smtp.mail.me.com"` | iCloud mail server relay host | 29 | | cluster_vars.service.postfix.relay.port | int | `587` | | 30 | | cluster_vars.service.postfix.user | string | Set values into [all.yaml](../../inventory/cluster/group_vars/all.yaml) `credentials` collection | Postfix user credentials, set at global level | 31 | | cluster_vars.service.snapd.enabled | bool | `false` | | 32 | | cluster_vars.service.unattended_upgrades.enabled | bool | `true` | See [documentation](https://help.ubuntu.com/community/AutomaticSecurityUpdates), for details | 33 | | cluster_vars.service.unattended_upgrades.mail_report | string | `"only-on-error"` | Available options are `always`, `on-change` and `only-on-error` | 34 | | cluster_vars.service.unattended_upgrades.remove_deps | string | `"true"` | | 35 | | cluster_vars.service.wifi.enabled | bool | `false` | By default, related `apt` packages are not installed | 36 | | cluster_vars.ssh.key | string | `"id_ed25519.pub"` | See [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/user/#ssh-key), for details | 37 | | cluster_vars.ssh.path | string | `"{{ lookup('ansible.builtin.env', 'HOME') + '/.ssh' }}"` | Full path to `.ssh` directory, a hardcoded value can be used | 38 | -------------------------------------------------------------------------------- /roles/cluster/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s" .Home -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to Ubuntu LTS OS based [cluster]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/cluster), for additional details. 12 | 13 | > [!IMPORTANT] 14 | > Read the [Ubuntu Server](https://axivo.com/k3s-cluster/tutorials/handbook/server/) tutorial, on bare-metal infrastructure. 15 | 16 | ## Role Variables 17 | 18 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 19 | 20 | > [!TIP] 21 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 22 | 23 | {{ template "chart.valuesTable" . }} 24 | -------------------------------------------------------------------------------- /roles/cluster/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cluster_vars: 3 | device: 4 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#storage-devices), for details 5 | enabled: true 6 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#deviceid), for details 7 | id: '2:2' 8 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#devicename), for details 9 | name: 'ASMedia Technology' 10 | hardware: 11 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details 12 | architecture: aarch64 13 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardwareproduct), for details 14 | product: 'Raspberry Pi' 15 | service: 16 | bluetooth: 17 | # -- By default, related `apt` packages are not installed 18 | enabled: false 19 | cloud_init: 20 | enabled: false 21 | postfix: 22 | enabled: true 23 | protocols: ipv4 24 | relay: 25 | # -- iCloud mail server relay host 26 | host: smtp.mail.me.com 27 | port: 587 28 | # -- (string) Postfix user credentials, set at global level 29 | # @default -- Set values into [all.yaml](../../inventory/cluster/group_vars/all.yaml) `credentials` collection 30 | user: 31 | snapd: 32 | enabled: false 33 | unattended_upgrades: 34 | # -- See [documentation](https://help.ubuntu.com/community/AutomaticSecurityUpdates), for details 35 | enabled: true 36 | # -- Available options are `always`, `on-change` and `only-on-error` 37 | mail_report: only-on-error 38 | remove_deps: 'true' 39 | wifi: 40 | # -- By default, related `apt` packages are not installed 41 | enabled: false 42 | ssh: 43 | # -- See [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/user/#ssh-key), for details 44 | key: id_ed25519.pub 45 | # -- Full path to `.ssh` directory, a hardcoded value can be used 46 | path: "{{ lookup('ansible.builtin.env', 'HOME') + '/.ssh' }}" 47 | -------------------------------------------------------------------------------- /roles/cluster/handlers/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reboot 3 | ansible.builtin.reboot: 4 | 5 | - name: Restart loadbalancer services 6 | ansible.builtin.systemd_service: 7 | name: '{{ item }}.service' 8 | state: restarted 9 | daemon_reload: true 10 | enabled: true 11 | loop: 12 | - haproxy 13 | - keepalived 14 | 15 | - name: Reload mail service 16 | ansible.builtin.systemd_service: 17 | name: postfix.service 18 | state: reloaded 19 | enabled: true 20 | 21 | - name: Restart unattended upgrades service 22 | ansible.builtin.systemd_service: 23 | name: unattended-upgrades.service 24 | state: restarted 25 | enabled: true 26 | -------------------------------------------------------------------------------- /roles/cluster/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | cluster_map: 5 | ssh: 6 | authorized_key: "{{ '/'.join([cluster_vars.ssh.path, cluster_vars.ssh.key]) }}" 7 | 8 | - name: Set variables fact 9 | ansible.builtin.set_fact: 10 | cluster_vars: '{{ cluster_vars }}' 11 | run_once: true 12 | -------------------------------------------------------------------------------- /roles/cluster/tasks/firewall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set service facts 3 | ansible.builtin.service_facts: 4 | 5 | - name: Disable Firewall 6 | when: 7 | - ansible_facts.services['ufw'] is defined 8 | - ansible_facts.services['ufw'].state == 'running' 9 | block: 10 | - name: Get firewall status 11 | ansible.builtin.command: 12 | cmd: ufw status 13 | changed_when: false 14 | register: firewall_status 15 | 16 | - name: Disable firewall 17 | ansible.builtin.command: 18 | cmd: ufw disable 19 | changed_when: false 20 | when: firewall_status.stdout.find('Status":" active') != -1 21 | -------------------------------------------------------------------------------- /roles/cluster/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | 6 | - name: User Configuration 7 | ansible.builtin.import_tasks: 8 | file: user.yaml 9 | 10 | - name: Cluster Provisioning 11 | when: valid_hardware_product is truthy 12 | block: 13 | - name: Cluster Configuration 14 | ansible.builtin.import_tasks: 15 | file: configuration.yaml 16 | 17 | - name: Cluster Upgrade 18 | ansible.builtin.import_tasks: 19 | file: upgrade.yaml 20 | 21 | - name: Flush handlers 22 | ansible.builtin.meta: flush_handlers 23 | -------------------------------------------------------------------------------- /roles/cluster/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Reset 3 | block: 4 | - name: Remove packages 5 | ansible.builtin.apt: 6 | name: '{{ item }}' 7 | state: absent 8 | autoremove: true 9 | clean: true 10 | purge: true 11 | loop: 12 | - cifs-utils 13 | when: 14 | - item in ansible_facts.packages 15 | - prompt_remove_packages in ['y', 'Y'] 16 | 17 | - name: Clean root mail 18 | ansible.builtin.lineinfile: 19 | path: /var/mail/root 20 | regexp: ^.* 21 | state: absent 22 | -------------------------------------------------------------------------------- /roles/cluster/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Upgrade distribution packages 3 | ansible.builtin.apt: 4 | state: fixed 5 | upgrade: dist 6 | autoremove: true 7 | clean: true 8 | purge: true 9 | update_cache: true 10 | 11 | - name: Firmware Files Cleanup 12 | when: cluster_vars.hardware.product | lower == 'raspberry pi' 13 | block: 14 | - name: Find firmware backup files 15 | ansible.builtin.find: 16 | path: /boot/firmware 17 | patterns: '*.bak' 18 | recurse: true 19 | register: backup_files 20 | 21 | - name: Purge firmware backup files 22 | ansible.builtin.file: 23 | path: '{{ item }}' 24 | state: absent 25 | loop: "{{ backup_files.files | map(attribute='path') | list }}" 26 | -------------------------------------------------------------------------------- /roles/cluster/tasks/user.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set authorized key 3 | ansible.posix.authorized_key: 4 | key: "{{ lookup('ansible.builtin.file', cluster_map.ssh.authorized_key) }}" 5 | user: '{{ ansible_user }}' 6 | 7 | - name: Create sudoers file 8 | ansible.builtin.copy: 9 | content: "{{ ansible_user }} ALL=(ALL:ALL) NOPASSWD:ALL\n" 10 | dest: '/etc/sudoers.d/{{ ansible_user }}' 11 | owner: root 12 | group: root 13 | mode: '440' 14 | -------------------------------------------------------------------------------- /roles/cluster/tasks/validation.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: cluster 5 | tasks_from: facts 6 | 7 | - name: Check device info 8 | ansible.builtin.shell: | 9 | set -eo pipefail 10 | lsusb -s {{ cluster_vars.device.id }} | grep {{ cluster_vars.device.name | quote }} 11 | args: 12 | executable: /bin/bash 13 | changed_when: false 14 | register: device_info 15 | when: cluster_vars.device.enabled is truthy 16 | 17 | - name: Get hardware product 18 | ansible.builtin.shell: | 19 | set -eo pipefail 20 | lshw -class system -quiet | grep {{ cluster_vars.hardware.product | quote }} 21 | args: 22 | executable: /bin/bash 23 | changed_when: false 24 | register: hardware_product 25 | 26 | - name: Set valid hardware product fact 27 | ansible.builtin.set_fact: 28 | valid_hardware_product: true 29 | when: 30 | - ansible_facts.lsb.id | lower == 'ubuntu' 31 | - ansible_facts.lsb.release is version('24.04', '>=') 32 | - ansible_facts.machine == cluster_vars.hardware.architecture 33 | - hardware_product.rc == 0 34 | 35 | - name: Check internet connectivity 36 | ansible.builtin.wait_for: 37 | host: github.com 38 | port: 443 39 | timeout: 30 40 | -------------------------------------------------------------------------------- /roles/coredns/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: coredns 3 | description: Documentation generator for coredns Ansible role 4 | home: https://github.com/coredns/helm 5 | version: 1.40.0 6 | -------------------------------------------------------------------------------- /roles/coredns/README.md: -------------------------------------------------------------------------------- 1 | # coredns 2 | 3 | ![Version: 1.40.0](https://img.shields.io/badge/Version-1.40.0-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `coredns` [chart](https://github.com/coredns/helm/tree/coredns-1.40.0/charts/coredns) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/coredns), for additional details. 6 | 7 | ## Role Variables 8 | 9 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `coredns_map` collection. 10 | 11 | > [!TIP] 12 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 13 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 14 | 15 | | Key | Type | Default | Description | 16 | |-----|------|---------|-------------| 17 | | coredns_vars.kubernetes.deployment.legacy | bool | `false` | Legacy deployment, using `kube-dns` label selectors | 18 | | coredns_vars.kubernetes.helm.chart.name | string | `"coredns"` | | 19 | | coredns_vars.kubernetes.helm.chart.version | string | `"v1.40.0"` | | 20 | | coredns_vars.kubernetes.helm.repository.name | string | `"helm"` | | 21 | | coredns_vars.kubernetes.helm.repository.org | string | `"coredns"` | | 22 | | coredns_vars.kubernetes.helm.repository.url | string | `"https://coredns.github.io"` | | 23 | | coredns_vars.kubernetes.hpa.enabled | bool | `true` | If `false`, `replicas` value is set from `min_replicas` value | 24 | | coredns_vars.kubernetes.hpa.max_replicas | int | `3` | | 25 | | coredns_vars.kubernetes.hpa.min_replicas | int | `1` | | 26 | | coredns_vars.kubernetes.hpa.resource.name | string | `"memory"` | | 27 | | coredns_vars.kubernetes.hpa.resource.target.utilization | int | `80` | Average utilization percentage | 28 | | coredns_vars.kubernetes.namespace | string | `"kube-system"` | | 29 | | coredns_vars.kubernetes.resources.limits.cpu | string | `nil` | | 30 | | coredns_vars.kubernetes.resources.limits.memory | string | `"128Mi"` | | 31 | | coredns_vars.kubernetes.resources.requests.cpu | string | `"10m"` | | 32 | | coredns_vars.kubernetes.resources.requests.memory | string | `"128Mi"` | | 33 | -------------------------------------------------------------------------------- /roles/coredns/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/coredns), for additional details. 12 | 13 | ## Role Variables 14 | 15 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 16 | 17 | > [!TIP] 18 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 19 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 20 | 21 | {{ template "chart.valuesTable" . }} 22 | -------------------------------------------------------------------------------- /roles/coredns/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | coredns_vars: 3 | kubernetes: 4 | helm: 5 | chart: 6 | name: coredns 7 | version: v1.40.0 8 | repository: 9 | name: helm 10 | org: coredns 11 | url: https://coredns.github.io 12 | hpa: 13 | # -- If `false`, `replicas` value is set from `min_replicas` value 14 | enabled: true 15 | min_replicas: 1 16 | max_replicas: 3 17 | resource: 18 | name: memory 19 | target: 20 | # -- Average utilization percentage 21 | utilization: 80 22 | deployment: 23 | # -- Legacy deployment, using `kube-dns` label selectors 24 | legacy: false 25 | namespace: kube-system 26 | resources: 27 | limits: 28 | cpu: null 29 | memory: 128Mi 30 | requests: 31 | cpu: 10m 32 | memory: 128Mi 33 | -------------------------------------------------------------------------------- /roles/coredns/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | coredns_map: 5 | helm: 6 | chart: 7 | reference: '{{ coredns_vars.kubernetes.helm.repository.org }}/{{ coredns_vars.kubernetes.helm.chart.name }}' 8 | version: '{{ coredns_vars.kubernetes.helm.chart.version[1:] }}' 9 | platform: 10 | key: https://github.com 11 | raw: https://raw.githubusercontent.com 12 | repository: 13 | name: '{{ coredns_vars.kubernetes.helm.repository.org }}/{{ coredns_vars.kubernetes.helm.repository.name }}' 14 | url: '{{ coredns_vars.kubernetes.helm.repository.url }}/{{ coredns_vars.kubernetes.helm.repository.name }}' 15 | timeout: 5m0s 16 | metrics: 17 | service: 18 | monitor: 19 | enabled: true 20 | scrape: 21 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 22 | interval: null 23 | run_once: true 24 | 25 | - name: Set project fact 26 | ansible.builtin.set_fact: 27 | coredns_project: 28 | tag: '{{ coredns_vars.kubernetes.helm.chart.name }}-{{ coredns_map.helm.chart.version }}' 29 | url: '{{ coredns_map.helm.platform.key }}/{{ coredns_map.helm.repository.name }}/releases/tag' 30 | run_once: true 31 | -------------------------------------------------------------------------------- /roles/coredns/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Add repository 17 | kubernetes.core.helm_repository: 18 | name: '{{ coredns_vars.kubernetes.helm.repository.org }}' 19 | repo_url: '{{ coredns_map.helm.repository.url }}' 20 | force_update: true 21 | 22 | - name: Chart Setup 23 | run_once: true 24 | block: 25 | - name: Set chart postinstall fact 26 | ansible.builtin.set_fact: 27 | coredns_postinstall: false 28 | 29 | - name: Install chart 30 | kubernetes.core.helm: 31 | chart_ref: '{{ coredns_map.helm.chart.reference }}' 32 | chart_version: '{{ coredns_vars.kubernetes.helm.chart.version }}' 33 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 34 | name: '{{ coredns_vars.kubernetes.helm.chart.name }}' 35 | namespace: '{{ coredns_vars.kubernetes.namespace }}' 36 | timeout: '{{ coredns_map.helm.timeout }}' 37 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 38 | create_namespace: true 39 | update_repo_cache: true 40 | wait: true 41 | register: result 42 | delay: 1 43 | retries: 3 44 | until: result is not failed 45 | -------------------------------------------------------------------------------- /roles/coredns/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: 4 | - inventory_hostname in k3s_map.server.hosts 5 | - coredns_map.metrics.service.monitor.enabled is truthy 6 | run_once: true 7 | block: 8 | - name: Update chart postinstall fact 9 | ansible.builtin.set_fact: 10 | coredns_postinstall: true 11 | 12 | - name: Update chart postinstall values 13 | kubernetes.core.helm: 14 | chart_ref: '{{ coredns_map.helm.chart.reference }}' 15 | chart_version: '{{ coredns_vars.kubernetes.helm.chart.version }}' 16 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 17 | name: '{{ coredns_vars.kubernetes.helm.chart.name }}' 18 | namespace: '{{ coredns_vars.kubernetes.namespace }}' 19 | timeout: '{{ coredns_map.helm.timeout }}' 20 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 21 | reset_values: false 22 | reuse_values: true 23 | wait: true 24 | register: result 25 | delay: 1 26 | retries: 3 27 | until: result is not failed 28 | -------------------------------------------------------------------------------- /roles/coredns/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ coredns_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | -------------------------------------------------------------------------------- /roles/coredns/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/coredns/templates/config_servers.j2: -------------------------------------------------------------------------------- 1 | {# 2 | CoreDNS Servers 3 | Manual: https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns-configmap-options 4 | #} 5 | 6 | - zones: 7 | - zone: . 8 | port: 53 9 | plugins: 10 | - name: errors 11 | - name: health 12 | configBlock: lameduck 5s 13 | - name: ready 14 | - name: kubernetes 15 | parameters: {{ k3s_vars.cluster.domain }} in-addr.arpa ip6.arpa 16 | configBlock: |- 17 | pods insecure 18 | fallthrough in-addr.arpa ip6.arpa 19 | ttl 30 20 | - name: prometheus 21 | parameters: 0.0.0.0:9153 22 | - name: forward 23 | parameters: . /etc/resolv.conf 24 | - name: cache 25 | parameters: 30 26 | - name: loop 27 | - name: reload 28 | - name: loadbalance 29 | -------------------------------------------------------------------------------- /roles/coredns/templates/values.j2: -------------------------------------------------------------------------------- 1 | {% if coredns_vars.kubernetes.hpa.enabled is truthy %} 2 | hpa: 3 | enabled: true 4 | maxReplicas: {{ coredns_vars.kubernetes.hpa.max_replicas }} 5 | minReplicas: {{ coredns_vars.kubernetes.hpa.min_replicas }} 6 | metrics: 7 | - type: Resource 8 | resource: 9 | name: {{ coredns_vars.kubernetes.hpa.resource.name }} 10 | target: 11 | type: Utilization 12 | averageUtilization: {{ coredns_vars.kubernetes.hpa.resource.target.utilization }} 13 | {% else %} 14 | replicaCount: {{ coredns_vars.kubernetes.hpa.min_replicas }} 15 | {% endif %} 16 | {% if coredns_vars.kubernetes.deployment.legacy is truthy %} 17 | k8sAppLabelOverride: kube-dns 18 | {% endif %} 19 | podDisruptionBudget: 20 | maxUnavailable: 1 21 | {% if coredns_postinstall is truthy and coredns_map.metrics.service.monitor.enabled is truthy %} 22 | prometheus: 23 | monitor: 24 | enabled: true 25 | {% if coredns_map.metrics.service.monitor.scrape.interval is falsy %} 26 | interval: {{ victoriametrics_map.service.monitor.scrape.interval }} 27 | {% else %} 28 | interval: {{ coredns_map.metrics.service.monitor.scrape.interval }} 29 | {% endif %} 30 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 31 | service: 32 | enabled: true 33 | {% endif %} 34 | resources: 35 | limits: 36 | {% if coredns_vars.kubernetes.resources.limits.cpu is truthy %} 37 | cpu: {{ coredns_vars.kubernetes.resources.limits.cpu }} 38 | {% endif %} 39 | memory: {{ coredns_vars.kubernetes.resources.limits.memory }} 40 | requests: 41 | cpu: {{ coredns_vars.kubernetes.resources.requests.cpu }} 42 | memory: {{ coredns_vars.kubernetes.resources.requests.memory }} 43 | rollingUpdate: 44 | maxSurge: 1 45 | maxUnavailable: 0 46 | servers: 47 | {{ lookup('ansible.builtin.template', 'config_servers.j2') | trim | indent(2) }} 48 | service: 49 | clusterIP: {{ k3s_map.cluster.dns }} 50 | serviceAccount: 51 | create: true 52 | -------------------------------------------------------------------------------- /roles/external-dns/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: external-dns 3 | description: Documentation generator for external-dns Ansible role 4 | home: https://github.com/kubernetes-sigs/external-dns 5 | version: 1.15.2 6 | -------------------------------------------------------------------------------- /roles/external-dns/README.md: -------------------------------------------------------------------------------- 1 | # external-dns 2 | 3 | ![Version: 1.15.2](https://img.shields.io/badge/Version-1.15.2-informational?style=flat-square) 4 | 5 | The role performs various tasks related to [Cloudflare](https://github.com/kubernetes-sigs/external-dns/blob/external-dns-helm-chart-1.15.2/docs/tutorials/cloudflare.md) based `external-dns` [chart](https://github.com/kubernetes-sigs/external-dns/tree/external-dns-helm-chart-1.15.2/charts/external-dns) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/externaldns), for additional details. 6 | 7 | ## Role Variables 8 | 9 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `externaldns_map` collection. 10 | 11 | > [!TIP] 12 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 13 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 14 | 15 | | Key | Type | Default | Description | 16 | |-----|------|---------|-------------| 17 | | externaldns_vars.cloudflare.acme.server | string | `"staging"` | Available options are [`production`](https://letsencrypt.org/docs/rate-limits/) and [`staging`](https://letsencrypt.org/docs/staging-environment/) | 18 | | externaldns_vars.cloudflare.host.domain | string | `"noty.cc"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/externaldns/#front-ends), for details | 19 | | externaldns_vars.cloudflare.prefix | string | `"cloudflare"` | | 20 | | externaldns_vars.kubernetes.helm.chart.name | string | `"external-dns"` | | 21 | | externaldns_vars.kubernetes.helm.chart.version | string | `"v1.15.2"` | | 22 | | externaldns_vars.kubernetes.helm.repository.name | string | `"external-dns"` | | 23 | | externaldns_vars.kubernetes.helm.repository.org | string | `"kubernetes-sigs"` | | 24 | | externaldns_vars.kubernetes.helm.repository.url | string | `"https://kubernetes-sigs.github.io"` | | 25 | | externaldns_vars.kubernetes.log_level | string | `"warning"` | | 26 | | externaldns_vars.kubernetes.namespace | string | `"kube-system"` | | 27 | | externaldns_vars.kubernetes.policy | string | `"sync"` | | 28 | | externaldns_vars.kubernetes.resources.limits.cpu | string | `nil` | | 29 | | externaldns_vars.kubernetes.resources.limits.memory | string | `"128Mi"` | | 30 | | externaldns_vars.kubernetes.resources.requests.cpu | string | `"10m"` | | 31 | | externaldns_vars.kubernetes.resources.requests.memory | string | `"128Mi"` | | 32 | -------------------------------------------------------------------------------- /roles/external-dns/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-helm-chart-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "chart.urlCloudflare" -}} 5 | {{- printf "%s/blob/%s-helm-chart-%s/docs/tutorials/cloudflare.md" .Home .Name .Version -}} 6 | {{- end -}} 7 | {{- define "role.map" -}} 8 | {{- printf "%s_map" .Name | replace "-" "" -}} 9 | {{- end -}} 10 | # {{ template "chart.name" . }} 11 | 12 | {{ template "chart.versionBadge" . }} 13 | 14 | The role performs various tasks related to [Cloudflare]({{ template "chart.urlCloudflare" . }}) based `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/externaldns), for additional details. 15 | 16 | ## Role Variables 17 | 18 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 19 | 20 | > [!TIP] 21 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 22 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 23 | 24 | {{ template "chart.valuesTable" . }} 25 | -------------------------------------------------------------------------------- /roles/external-dns/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | externaldns_vars: 3 | cloudflare: 4 | acme: 5 | # -- Available options are [`production`](https://letsencrypt.org/docs/rate-limits/) 6 | # and [`staging`](https://letsencrypt.org/docs/staging-environment/) 7 | server: staging 8 | host: 9 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/externaldns/#front-ends), for details 10 | domain: noty.cc 11 | prefix: cloudflare 12 | kubernetes: 13 | helm: 14 | chart: 15 | name: external-dns 16 | version: v1.15.2 17 | repository: 18 | name: external-dns 19 | org: kubernetes-sigs 20 | url: https://kubernetes-sigs.github.io 21 | log_level: warning 22 | namespace: kube-system 23 | policy: sync 24 | resources: 25 | limits: 26 | cpu: null 27 | memory: 128Mi 28 | requests: 29 | cpu: 10m 30 | memory: 128Mi 31 | -------------------------------------------------------------------------------- /roles/external-dns/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | externaldns_map: 5 | cloudflare: 6 | acme: 7 | server: "{{ '-staging' if externaldns_vars.cloudflare.acme.server | lower == 'staging' | default('') }}" 8 | api: 9 | token: 10 | key: token 11 | name: '{{ externaldns_vars.cloudflare.prefix }}-api-token' 12 | ca: 13 | cluster: 14 | issuer: 15 | name: '{{ externaldns_vars.cloudflare.prefix }}-cluster-issuer' 16 | helm: 17 | chart: 18 | reference: '{{ externaldns_vars.kubernetes.helm.repository.org }}/{{ externaldns_vars.kubernetes.helm.chart.name }}' 19 | version: '{{ externaldns_vars.kubernetes.helm.chart.version[1:] }}' 20 | platform: 21 | key: https://github.com 22 | raw: https://raw.githubusercontent.com 23 | repository: 24 | name: '{{ externaldns_vars.kubernetes.helm.repository.org }}/{{ externaldns_vars.kubernetes.helm.repository.name }}' 25 | url: '{{ externaldns_vars.kubernetes.helm.repository.url }}/{{ externaldns_vars.kubernetes.helm.repository.name }}' 26 | timeout: 5m0s 27 | metrics: 28 | service: 29 | monitor: 30 | enabled: true 31 | scrape: 32 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 33 | interval: null 34 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 35 | timeout: null 36 | run_once: true 37 | 38 | - name: Set project fact 39 | ansible.builtin.set_fact: 40 | externaldns_project: 41 | cloudflare: 42 | acme: 43 | server: 44 | url: https://acme{{ externaldns_map.cloudflare.acme.server }}-v02.api.letsencrypt.org/directory 45 | cluster: 46 | issuer: '{{ externaldns_map.cloudflare.ca.cluster.issuer.name }}{{ externaldns_map.cloudflare.acme.server }}' 47 | tag: '{{ externaldns_vars.kubernetes.helm.chart.name }}-helm-chart-{{ externaldns_map.helm.chart.version }}' 48 | url: '{{ externaldns_map.helm.platform.key }}//{{ externaldns_map.helm.repository.name }}/releases/tag' 49 | run_once: true 50 | 51 | - name: Set variables fact 52 | ansible.builtin.set_fact: 53 | externaldns_vars: '{{ externaldns_vars }}' 54 | run_once: true 55 | -------------------------------------------------------------------------------- /roles/external-dns/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: 9 | - inventory_hostname in k3s_map.server.hosts 10 | - externaldns_vars.cloudflare.host.domain | lower != 'disabled' 11 | block: 12 | - name: Validate service state 13 | ansible.builtin.wait_for: 14 | port: '{{ k3s_vars.server.api.port }}' 15 | timeout: 30 16 | any_errors_fatal: true 17 | 18 | - name: Add repository 19 | kubernetes.core.helm_repository: 20 | name: '{{ externaldns_vars.kubernetes.helm.repository.org }}' 21 | repo_url: '{{ externaldns_map.helm.repository.url }}' 22 | force_update: true 23 | 24 | - name: Chart Setup 25 | run_once: true 26 | block: 27 | - name: Create cloudflare api token secret 28 | kubernetes.core.k8s: 29 | definition: "{{ lookup('ansible.builtin.template', 'api_token.j2') | from_yaml }}" 30 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 31 | wait: true 32 | 33 | - name: Set chart postinstall fact 34 | ansible.builtin.set_fact: 35 | externaldns_postinstall: false 36 | 37 | - name: Install chart 38 | kubernetes.core.helm: 39 | chart_ref: '{{ externaldns_map.helm.chart.reference }}' 40 | chart_version: '{{ externaldns_vars.kubernetes.helm.chart.version }}' 41 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 42 | name: '{{ externaldns_vars.kubernetes.helm.chart.name }}' 43 | namespace: '{{ externaldns_vars.kubernetes.namespace }}' 44 | timeout: '{{ externaldns_map.helm.timeout }}' 45 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 46 | create_namespace: true 47 | update_repo_cache: true 48 | wait: true 49 | register: result 50 | delay: 1 51 | retries: 3 52 | until: result is not failed 53 | 54 | - name: Create cluster issuer 55 | kubernetes.core.k8s: 56 | definition: "{{ lookup('ansible.builtin.template', 'cluster_issuer.j2') | from_yaml }}" 57 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 58 | wait: true 59 | -------------------------------------------------------------------------------- /roles/external-dns/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: 4 | - inventory_hostname in k3s_map.server.hosts 5 | - externaldns_map.metrics.service.monitor.enabled is truthy 6 | run_once: true 7 | block: 8 | - name: Update chart postinstall fact 9 | ansible.builtin.set_fact: 10 | externaldns_postinstall: true 11 | 12 | - name: Update chart postinstall values 13 | kubernetes.core.helm: 14 | chart_ref: '{{ externaldns_map.helm.chart.reference }}' 15 | chart_version: '{{ externaldns_vars.kubernetes.helm.chart.version }}' 16 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 17 | name: '{{ externaldns_vars.kubernetes.helm.chart.name }}' 18 | namespace: '{{ externaldns_vars.kubernetes.namespace }}' 19 | timeout: '{{ externaldns_map.helm.timeout }}' 20 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 21 | reset_values: false 22 | reuse_values: true 23 | wait: true 24 | register: result 25 | delay: 1 26 | retries: 3 27 | until: result is not failed 28 | -------------------------------------------------------------------------------- /roles/external-dns/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ externaldns_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | -------------------------------------------------------------------------------- /roles/external-dns/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/external-dns/templates/api_token.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ externaldns_map.cloudflare.api.token.name }} 5 | namespace: {{ externaldns_vars.kubernetes.namespace }} 6 | stringData: 7 | {{ externaldns_map.cloudflare.api.token.key }}: {{ global_map.credentials.externaldns.cloudflare.api.token }} 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /roles/external-dns/templates/cluster_issuer.j2: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: {{ externaldns_project.cloudflare.cluster.issuer }} 5 | spec: 6 | acme: 7 | email: {{ global_map.credentials.cluster.postfix.user.alias }} 8 | privateKeySecretRef: 9 | name: {{ externaldns_vars.cloudflare.prefix }}-private-key 10 | server: {{ externaldns_project.cloudflare.acme.server.url }} 11 | solvers: 12 | - dns01: 13 | cloudflare: 14 | apiTokenSecretRef: 15 | key: {{ externaldns_map.cloudflare.api.token.key }} 16 | name: {{ externaldns_map.cloudflare.api.token.name }} 17 | txtOwnerId: {{ k3s_map.cluster.label }} 18 | -------------------------------------------------------------------------------- /roles/external-dns/templates/values.j2: -------------------------------------------------------------------------------- 1 | domainFilters: 2 | - {{ externaldns_vars.cloudflare.host.domain }} 3 | env: 4 | - name: CF_API_TOKEN 5 | valueFrom: 6 | secretKeyRef: 7 | key: {{ externaldns_map.cloudflare.api.token.key }} 8 | name: {{ externaldns_map.cloudflare.api.token.name }} 9 | logLevel: {{ externaldns_vars.kubernetes.log_level }} 10 | policy: {{ externaldns_vars.kubernetes.policy }} 11 | provider: 12 | name: cloudflare 13 | resources: 14 | limits: 15 | {% if externaldns_vars.kubernetes.resources.limits.cpu is truthy %} 16 | cpu: {{ externaldns_vars.kubernetes.resources.limits.cpu }} 17 | {% endif %} 18 | memory: {{ externaldns_vars.kubernetes.resources.limits.memory }} 19 | requests: 20 | cpu: {{ externaldns_vars.kubernetes.resources.requests.cpu }} 21 | memory: {{ externaldns_vars.kubernetes.resources.requests.memory }} 22 | {% if externaldns_postinstall is truthy and externaldns_map.metrics.service.monitor.enabled is truthy %} 23 | serviceMonitor: 24 | enabled: true 25 | {% if externaldns_map.metrics.service.monitor.scrape.interval is falsy %} 26 | interval: {{ victoriametrics_map.service.monitor.scrape.interval }} 27 | {% else %} 28 | interval: {{ externaldns_map.metrics.service.monitor.scrape.interval }} 29 | {% endif %} 30 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 31 | {% if externaldns_map.metrics.service.monitor.scrape.timeout is falsy %} 32 | scrapeTimeout: {{ victoriametrics_map.service.monitor.scrape.timeout }} 33 | {% else %} 34 | scrapeTimeout: {{ externaldns_map.metrics.service.monitor.scrape.timeout }} 35 | {% endif %} 36 | {% endif %} 37 | sources: 38 | - gateway-grpcroute 39 | - gateway-httproute 40 | - gateway-tcproute 41 | - gateway-tlsroute 42 | - gateway-udproute 43 | - ingress 44 | - service 45 | txtOwnerId: {{ k3s_map.cluster.label }} 46 | txtPrefix: _acme-challenge. 47 | -------------------------------------------------------------------------------- /roles/helm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: helm 3 | description: Documentation generator for helm Ansible role 4 | home: https://helm.baltorepo.com/stable/debian/packages/helm/releases 5 | version: 3.17.2-1 6 | dependencies: 7 | - name: diff 8 | repository: https://github.com/databus23/helm-diff 9 | version: 3.11.0 10 | -------------------------------------------------------------------------------- /roles/helm/README.md: -------------------------------------------------------------------------------- 1 | # helm 2 | 3 | ![Version: 3.17.2-1](https://img.shields.io/badge/Version-3.17.2--1-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `helm` [package](https://helm.baltorepo.com/stable/debian/packages/helm/releases/3.17.2-1) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/helm), for additional details. 6 | 7 | ## Helm Plugins 8 | 9 | See the installed `helm` plugins listed below, defined into [main.yaml](./defaults/main.yaml) `plugins` collection. 10 | 11 | | Repository | Name | Version | 12 | |------------|------|---------| 13 | | https://github.com/databus23/helm-diff | diff | 3.11.0 | 14 | 15 | ## Role Variables 16 | 17 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `helm_map` collection. 18 | 19 | > [!TIP] 20 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 21 | 22 | | Key | Type | Default | Description | 23 | |-----|------|---------|-------------| 24 | | helm_vars.environment.HELM_NAMESPACE | string | `"default"` | | 25 | | helm_vars.plugins[0].enabled | bool | `true` | | 26 | | helm_vars.plugins[0].name | string | `"diff"` | | 27 | | helm_vars.plugins[0].packages[0] | string | `"python3-jsonpatch"` | | 28 | | helm_vars.plugins[0].repository.url | string | `"https://github.com/databus23/helm-diff"` | | 29 | | helm_vars.plugins[0].version | string | `"v3.11.0"` | | 30 | | helm_vars.release.helm.distro.name | string | `"debian"` | | 31 | | helm_vars.release.helm.distro.url | string | `"https://helm.baltorepo.com"` | | 32 | | helm_vars.release.helm.key | string | `"helm-archive-keyring.gpg"` | | 33 | | helm_vars.release.helm.repository.channel | string | `"stable"` | | 34 | | helm_vars.release.helm.repository.key | string | `"signing.asc"` | | 35 | | helm_vars.release.helm.repository.url | string | `"https://baltocdn.com/helm"` | | 36 | | helm_vars.release.helm.version | string | `"v3.17.2-1"` | | 37 | -------------------------------------------------------------------------------- /roles/helm/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/%s" .Home .Version -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [package]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/helm), for additional details. 12 | 13 | ## Helm Plugins 14 | 15 | See the installed `helm` plugins listed below, defined into [main.yaml](./defaults/main.yaml) `plugins` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | 26 | {{ template "chart.valuesTable" . }} 27 | -------------------------------------------------------------------------------- /roles/helm/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | helm_vars: 3 | environment: 4 | HELM_NAMESPACE: default 5 | plugins: 6 | - name: diff 7 | enabled: true 8 | packages: 9 | - python3-jsonpatch 10 | repository: 11 | url: https://github.com/databus23/helm-diff 12 | version: v3.11.0 13 | release: 14 | helm: 15 | distro: 16 | name: debian 17 | url: https://helm.baltorepo.com 18 | key: helm-archive-keyring.gpg 19 | repository: 20 | channel: stable 21 | key: signing.asc 22 | url: https://baltocdn.com/helm 23 | version: v3.17.2-1 24 | -------------------------------------------------------------------------------- /roles/helm/handlers/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Restart service 3 | ansible.builtin.systemd_service: 4 | name: helm-cache.service 5 | state: restarted 6 | daemon_reload: true 7 | enabled: true 8 | 9 | - name: Start service 10 | ansible.builtin.systemd_service: 11 | name: helm-cache.service 12 | state: started 13 | daemon_reload: true 14 | enabled: true 15 | -------------------------------------------------------------------------------- /roles/helm/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | helm_map: 5 | directory: 6 | share: /usr/local/share/helm 7 | release: 8 | channel: '{{ helm_vars.release.helm.repository.url }}/{{ helm_vars.release.helm.repository.channel }}' 9 | key: '{{ helm_vars.release.helm.repository.url }}/{{ helm_vars.release.helm.repository.key }}' 10 | url: '{{ helm_vars.release.helm.distro.url }}/{{ helm_vars.release.helm.repository.channel }}/{{ helm_vars.release.helm.distro.name }}' 11 | version: '{{ helm_vars.release.helm.version[1:] }}' 12 | run_once: true 13 | 14 | - name: Set project fact 15 | ansible.builtin.set_fact: 16 | helm_project: 17 | environment: 18 | HELM_CACHE_HOME: '{{ helm_map.directory.share }}/cache' 19 | HELM_CONFIG_HOME: '{{ helm_map.directory.share }}/config' 20 | HELM_DATA_HOME: '{{ helm_map.directory.share }}' 21 | HELM_PLUGINS: '{{ helm_map.directory.share }}/plugins' 22 | HELM_REGISTRY_CONFIG: '{{ helm_map.directory.share }}/config/registry/config.json' 23 | HELM_REPOSITORY_CACHE: '{{ helm_map.directory.share }}/cache/repository' 24 | HELM_REPOSITORY_CONFIG: '{{ helm_map.directory.share }}/config/repositories.yaml' 25 | release: 26 | package: '{{ helm_map.release.url }}/packages/helm/releases/{{ helm_map.release.version }}' 27 | run_once: true 28 | 29 | - name: Set plugin packages fact 30 | ansible.builtin.set_fact: 31 | helm_plugin_packages: '{{ plugin.packages }}' 32 | loop: '{{ helm_vars.plugins }}' 33 | loop_control: 34 | loop_var: plugin 35 | run_once: true 36 | when: 37 | - plugin.enabled is truthy 38 | - plugin.packages is defined 39 | 40 | - name: Set plugin packages disabled fact 41 | ansible.builtin.set_fact: 42 | helm_plugin_packages_disabled: '{{ plugin.packages }}' 43 | loop: '{{ helm_vars.plugins }}' 44 | loop_control: 45 | loop_var: plugin 46 | run_once: true 47 | when: 48 | - plugin.enabled is falsy 49 | - plugin.packages is defined 50 | -------------------------------------------------------------------------------- /roles/helm/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Validation 8 | ansible.builtin.import_tasks: 9 | file: validation.yaml 10 | 11 | - name: Role Provisioning 12 | when: inventory_hostname in k3s_map.server.hosts 13 | block: 14 | - name: Install packages 15 | ansible.builtin.apt: 16 | name: '{{ item }}' 17 | autoremove: true 18 | update_cache: true 19 | loop: 20 | - apt-transport-https 21 | - python3-kubernetes 22 | 23 | - name: Add variables to environment file 24 | ansible.builtin.lineinfile: 25 | path: /etc/environment 26 | line: '{{ item.key }}={{ item.value }}' 27 | regexp: ^{{ item.key }} 28 | loop: "{{ lookup('ansible.builtin.dict', helm_project.environment | combine(helm_vars.environment)) | sort(attribute='key') }}" 29 | 30 | - name: Initialize variables 31 | ansible.builtin.shell: | 32 | set -eo pipefail 33 | source /etc/environment 34 | args: 35 | executable: /bin/bash 36 | changed_when: false 37 | 38 | - name: Get file status 39 | ansible.builtin.stat: 40 | path: /usr/share/keyrings/{{ helm_vars.release.helm.key }} 41 | changed_when: not gpg_key.stat.exists 42 | register: gpg_key 43 | 44 | - name: Helm Repository 45 | when: not gpg_key.stat.exists 46 | block: 47 | - name: Download key 48 | ansible.builtin.get_url: 49 | url: '{{ helm_map.release.key }}' 50 | dest: /tmp/{{ helm_vars.release.helm.repository.key }} 51 | owner: root 52 | group: root 53 | mode: '644' 54 | register: result 55 | delay: 1 56 | retries: 3 57 | until: result is not failed 58 | 59 | - name: Dearmor key 60 | ansible.builtin.command: 61 | cmd: gpg --dearmor -o /usr/share/keyrings/{{ helm_vars.release.helm.key }} /tmp/{{ helm_vars.release.helm.repository.key }} 62 | changed_when: dearmor_key.rc == 0 63 | register: dearmor_key 64 | 65 | - name: Remove key 66 | ansible.builtin.file: 67 | path: /tmp/{{ helm_vars.release.helm.repository.key }} 68 | state: absent 69 | 70 | - name: Get architecture 71 | ansible.builtin.command: 72 | cmd: dpkg --print-architecture 73 | changed_when: false 74 | register: architecture 75 | 76 | - name: Install repository 77 | ansible.builtin.deb822_repository: 78 | architectures: '{{ architecture.stdout }}' 79 | components: main 80 | name: helm-{{ helm_vars.release.helm.repository.channel }} 81 | signed_by: /usr/share/keyrings/{{ helm_vars.release.helm.key }} 82 | suites: all 83 | uris: '{{ helm_map.release.channel }}/{{ helm_vars.release.helm.distro.name }}/' 84 | enabled: true 85 | trusted: true 86 | 87 | - name: Install helm package 88 | ansible.builtin.apt: 89 | name: helm={{ helm_map.release.version }} 90 | allow_downgrade: true 91 | autoremove: true 92 | update_cache: true 93 | 94 | - name: Helm Cache 95 | notify: Start service 96 | block: 97 | - name: Create service file 98 | ansible.builtin.template: 99 | src: service.j2 100 | dest: /etc/systemd/system/helm-cache.service 101 | owner: root 102 | group: root 103 | mode: '644' 104 | 105 | - name: Create service timer file 106 | ansible.builtin.template: 107 | src: timer.j2 108 | dest: /etc/systemd/system/helm-cache.timer 109 | owner: root 110 | group: root 111 | mode: '644' 112 | 113 | - name: Helm Plugins 114 | ansible.builtin.import_tasks: 115 | file: plugins.yaml 116 | -------------------------------------------------------------------------------- /roles/helm/tasks/plugins.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove Helm Plugins 3 | notify: Restart service 4 | block: 5 | - name: Remove plugins 6 | kubernetes.core.helm_plugin: 7 | plugin_name: '{{ item.name }}' 8 | state: absent 9 | loop: '{{ helm_vars.plugins }}' 10 | 11 | - name: Remove plugin packages 12 | ansible.builtin.apt: 13 | name: '{{ item }}' 14 | state: absent 15 | autoremove: true 16 | clean: true 17 | purge: true 18 | loop: '{{ helm_plugin_packages_disabled | default([]) }}' 19 | 20 | - name: Install Helm Plugins 21 | block: 22 | - name: Install plugin packages 23 | ansible.builtin.apt: 24 | name: '{{ item }}' 25 | autoremove: true 26 | update_cache: true 27 | loop: '{{ helm_plugin_packages | default([]) }}' 28 | 29 | - name: Install plugins 30 | kubernetes.core.helm_plugin: 31 | plugin_path: '{{ item.repository.url }}' 32 | plugin_version: '{{ item.version }}' 33 | loop: '{{ helm_vars.plugins }}' 34 | register: result 35 | delay: 1 36 | retries: 3 37 | until: result is not failed 38 | when: item.enabled is truthy 39 | -------------------------------------------------------------------------------- /roles/helm/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.include_role: 4 | name: '{{ item }}' 5 | tasks_from: facts 6 | loop: 7 | - helm 8 | - k3s 9 | 10 | - name: Role Reset 11 | when: inventory_hostname in k3s_map.server.hosts 12 | block: 13 | - name: Remove plugins 14 | kubernetes.core.helm_plugin: 15 | plugin_name: '{{ item.name }}' 16 | state: absent 17 | loop: '{{ helm_vars.plugins }}' 18 | when: 19 | - "'helm' in ansible_facts.packages" 20 | - "'python3-kubernetes' in ansible_facts.packages" 21 | 22 | - name: Remove Packages 23 | when: prompt_remove_packages in ['y', 'Y'] 24 | block: 25 | - name: Remove plugin packages 26 | ansible.builtin.apt: 27 | name: '{{ item.packages }}' 28 | state: absent 29 | autoremove: true 30 | clean: true 31 | purge: true 32 | loop: '{{ helm_vars.plugins }}' 33 | when: item.packages is defined 34 | 35 | - name: Remove packages 36 | ansible.builtin.apt: 37 | name: '{{ item }}' 38 | state: absent 39 | autoremove: true 40 | clean: true 41 | purge: true 42 | loop: 43 | - apt-transport-https 44 | - helm 45 | - python3-kubernetes 46 | 47 | - name: Remove configuration files 48 | ansible.builtin.file: 49 | path: '{{ item }}' 50 | state: absent 51 | loop: 52 | - '{{ helm_map.directory.share }}' 53 | - /etc/apt/sources.list.d/helm-{{ helm_vars.release.helm.repository.channel }}.sources 54 | - /etc/systemd/system/helm-cache.service 55 | - /etc/systemd/system/helm-cache.timer 56 | - /usr/share/keyrings/{{ helm_vars.release.helm.key }} 57 | 58 | - name: Reset systemd 59 | ansible.builtin.command: 60 | cmd: systemctl '{{ item }}' # noqa command-instead-of-module 61 | changed_when: false 62 | loop: 63 | - daemon-reload 64 | - reset-failed 65 | 66 | - name: Remove variables from environment file 67 | ansible.builtin.lineinfile: 68 | path: /etc/environment 69 | line: '{{ item.key }}={{ item.value }}' 70 | regexp: ^{{ item.key }} 71 | state: absent 72 | loop: "{{ lookup('ansible.builtin.dict', helm_project.environment | combine(helm_vars.environment)) }}" 73 | -------------------------------------------------------------------------------- /roles/helm/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Validation 8 | ansible.builtin.import_tasks: 9 | file: validation.yaml 10 | 11 | - name: Role Upgrade 12 | when: inventory_hostname in k3s_map.server.hosts 13 | block: 14 | - name: Upgrade helm package 15 | ansible.builtin.apt: 16 | name: helm={{ helm_map.release.version }} 17 | allow_downgrade: true 18 | autoremove: true 19 | update_cache: true 20 | 21 | - name: Helm Plugins 22 | ansible.builtin.import_tasks: 23 | file: plugins.yaml 24 | -------------------------------------------------------------------------------- /roles/helm/tasks/validation.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_tasks: 4 | file: facts.yaml 5 | 6 | - name: Role Validation 7 | when: ('validation' in ansible_run_tags) 8 | run_once: true 9 | block: 10 | - name: Validate release key url 11 | ansible.builtin.uri: 12 | url: '{{ helm_map.release.key }}' 13 | timeout: 5 14 | register: result 15 | delay: 1 16 | retries: 3 17 | until: result is not failed 18 | 19 | - name: Validate release package url 20 | ansible.builtin.uri: 21 | url: '{{ helm_project.release.package }}' 22 | timeout: 5 23 | register: result 24 | delay: 1 25 | retries: 3 26 | until: result is not failed 27 | 28 | - name: Validate release plugins url 29 | ansible.builtin.uri: 30 | url: '{{ release.repository.url }}/releases/tag/{{ release.version }}' 31 | timeout: 5 32 | loop: '{{ helm_vars.plugins }}' 33 | loop_control: 34 | loop_var: release 35 | register: result 36 | delay: 1 37 | retries: 3 38 | until: result is not failed 39 | when: release.enabled is truthy 40 | -------------------------------------------------------------------------------- /roles/helm/templates/service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Discard Helm cache files 3 | Documentation=https://helm.sh 4 | 5 | [Service] 6 | Type=oneshot 7 | EnvironmentFile=/etc/environment 8 | ExecStart=/usr/bin/rm -rf $HELM_CACHE_HOME 9 | RemainAfterExit=yes 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /roles/helm/templates/timer.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Discard Helm cache files once a week 3 | Documentation=https://helm.sh 4 | 5 | [Timer] 6 | AccuracySec=1h 7 | OnCalendar=weekly 8 | Persistent=true 9 | RandomizedDelaySec=100m 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /roles/k3s/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: k3s 3 | description: Documentation generator for k3s Ansible role 4 | home: https://github.com/k3s-io/k3s 5 | version: 1.32.3+k3s1 6 | dependencies: 7 | - name: kubepug 8 | repository: https://github.com/kubepug/kubepug 9 | version: 1.7.1 10 | -------------------------------------------------------------------------------- /roles/k3s/README.md: -------------------------------------------------------------------------------- 1 | # k3s 2 | 3 | ![Version: 1.32.3+k3s1](https://img.shields.io/badge/Version-1.32.3+k3s1-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `k3s` [cluster](https://github.com/k3s-io/k3s/releases/tag/v1.32.3+k3s1) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/k3s), for additional details. 6 | 7 | ## Role Dependencies 8 | 9 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 10 | 11 | | Repository | Name | Version | 12 | |------------|------|---------| 13 | | https://github.com/kubepug/kubepug | kubepug | 1.7.1 | 14 | 15 | ## Role Variables 16 | 17 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `k3s_map` collection. 18 | 19 | > [!TIP] 20 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 21 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 22 | 23 | | Key | Type | Default | Description | 24 | |-----|------|---------|-------------| 25 | | k3s_vars.cluster.controlplane.tainted | bool | `true` | | 26 | | k3s_vars.cluster.domain | string | `"cluster.local"` | | 27 | | k3s_vars.cluster.kubeconfig.local | bool | `true` | | 28 | | k3s_vars.cluster.kubeconfig.path | string | `"{{ lookup('ansible.builtin.env', 'HOME') + '/.kube' }}"` | Local `/.kube` directory path | 29 | | k3s_vars.cluster.service.host | string | `"127.0.0.1"` | | 30 | | k3s_vars.cluster.service.port | int | `6444` | | 31 | | k3s_vars.cluster.tls_san | list | `["192.168.4.10"]` | Related to `server.api.host` key | 32 | | k3s_vars.network.interface | string | `"eth0"` | | 33 | | k3s_vars.release.k3s.checksum | string | `"sha256sum-arm64.txt"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details | 34 | | k3s_vars.release.k3s.file | string | `"k3s-arm64"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details | 35 | | k3s_vars.release.k3s.name | string | `"k3s"` | | 36 | | k3s_vars.release.k3s.repository.name | string | `"k3s"` | | 37 | | k3s_vars.release.k3s.repository.org | string | `"k3s-io"` | | 38 | | k3s_vars.release.k3s.version | string | `"v1.32.3+k3s1"` | | 39 | | k3s_vars.release.kubepug.checksum | string | `"checksums.txt"` | | 40 | | k3s_vars.release.kubepug.file | string | `"kubepug_linux_arm64.tar.gz"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details | 41 | | k3s_vars.release.kubepug.name | string | `"kubepug"` | | 42 | | k3s_vars.release.kubepug.repository.name | string | `"kubepug"` | | 43 | | k3s_vars.release.kubepug.repository.org | string | `"kubepug"` | | 44 | | k3s_vars.release.kubepug.version | string | `"v1.7.1"` | | 45 | | k3s_vars.server.api.host | string | `"192.168.4.10"` | Related to `cluster.tls_san` key, used as frontend bind IP for Haproxy loadbalancer and populated into `/.kube/config` file | 46 | | k3s_vars.server.api.port | int | `6443` | | 47 | | k3s_vars.service.debug | bool | `false` | | 48 | -------------------------------------------------------------------------------- /roles/k3s/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/releases/tag/v%s" .Home .Version -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [cluster]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/k3s), for additional details. 12 | 13 | ## Role Dependencies 14 | 15 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 26 | 27 | {{ template "chart.valuesTable" . }} 28 | -------------------------------------------------------------------------------- /roles/k3s/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | k3s_vars: 3 | cluster: 4 | controlplane: 5 | tainted: true 6 | domain: cluster.local 7 | kubeconfig: 8 | local: true 9 | # -- Local `/.kube` directory path 10 | path: "{{ lookup('ansible.builtin.env', 'HOME') + '/.kube' }}" 11 | service: 12 | host: 127.0.0.1 13 | port: 6444 14 | # -- Related to `server.api.host` key 15 | tls_san: 16 | - 192.168.4.10 17 | network: 18 | interface: eth0 19 | release: 20 | k3s: 21 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details 22 | checksum: sha256sum-arm64.txt 23 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details 24 | file: k3s-arm64 25 | name: k3s 26 | repository: 27 | name: k3s 28 | org: k3s-io 29 | version: v1.32.3+k3s1 30 | kubepug: 31 | checksum: checksums.txt 32 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details 33 | file: kubepug_linux_arm64.tar.gz 34 | name: kubepug 35 | repository: 36 | name: kubepug 37 | org: kubepug 38 | version: v1.7.1 39 | server: 40 | api: 41 | # -- Related to `cluster.tls_san` key, 42 | # used as frontend bind IP for Haproxy loadbalancer and populated into `/.kube/config` file 43 | host: 192.168.4.10 44 | port: 6443 45 | service: 46 | debug: false 47 | -------------------------------------------------------------------------------- /roles/k3s/handlers/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reboot 3 | ansible.builtin.reboot: 4 | 5 | - name: Reload sysctl parameters 6 | ansible.builtin.command: 7 | cmd: sysctl --system 8 | changed_when: false 9 | 10 | - name: Restart loadbalancer services 11 | ansible.builtin.systemd_service: 12 | name: '{{ services_item }}.service' 13 | state: restarted 14 | daemon_reload: true 15 | enabled: true 16 | loop: 17 | - haproxy 18 | - keepalived 19 | loop_control: 20 | loop_var: services_item 21 | 22 | - name: Restart service 23 | ansible.builtin.systemd_service: 24 | name: '{{ k3s_map.service.name }}.service' 25 | state: restarted 26 | daemon_reload: true 27 | enabled: true 28 | 29 | - name: Start service 30 | ansible.builtin.systemd_service: 31 | name: '{{ k3s_map.service.name }}.service' 32 | state: started 33 | daemon_reload: true 34 | enabled: true 35 | 36 | - name: Stop service 37 | ansible.builtin.systemd_service: 38 | name: '{{ k3s_map.service.name }}.service' 39 | state: stopped 40 | enabled: false 41 | register: service 42 | failed_when: 43 | - service.failed == true 44 | - service.msg.find('Could not find the requested service') == -1 45 | -------------------------------------------------------------------------------- /roles/k3s/tasks/loadbalancer.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.include_role: 4 | name: '{{ role }}' 5 | tasks_from: facts 6 | loop: 7 | - cluster 8 | - k3s 9 | loop_control: 10 | loop_var: role 11 | 12 | - name: Loadbalancer Setup 13 | notify: Restart loadbalancer services 14 | when: 15 | - k3s_map.server.ha is truthy 16 | - inventory_hostname in k3s_map.loadbalancer.hosts 17 | block: 18 | - name: Set sysctl token value 19 | ansible.posix.sysctl: 20 | name: net.ipv4.ip_nonlocal_bind 21 | value: '1' 22 | sysctl_file: /etc/sysctl.d/90-ip-nonlocal-bind.conf 23 | sysctl_set: true 24 | 25 | - name: Install loadbalancer packages 26 | ansible.builtin.apt: 27 | name: '{{ item }}' 28 | autoremove: true 29 | update_cache: true 30 | loop: 31 | - haproxy 32 | - keepalived 33 | 34 | - name: Update haproxy configuration file 35 | ansible.builtin.blockinfile: 36 | block: "{{ lookup('ansible.builtin.template', 'haproxy.j2') }}" 37 | dest: /etc/haproxy/haproxy.cfg 38 | insertafter: ^\terrorfile\s504\s\/etc\/haproxy\/errors\/504\.http$ 39 | marker: '# {mark} K3s Settings' 40 | prepend_newline: true 41 | 42 | - name: Update keepalived configuration file 43 | ansible.builtin.template: 44 | src: keepalived.j2 45 | dest: /etc/keepalived/keepalived.conf 46 | owner: root 47 | group: root 48 | mode: '644' 49 | 50 | - name: Flush handlers 51 | ansible.builtin.meta: flush_handlers 52 | -------------------------------------------------------------------------------- /roles/k3s/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | notify: Start service 9 | block: 10 | - name: Install k3s binary 11 | ansible.builtin.get_url: 12 | url: '{{ k3s_project.release.k3s.file }}' 13 | checksum: sha256:{{ k3s_project.release.k3s.checksum }} 14 | dest: '{{ k3s_project.node.binary }}' 15 | owner: root 16 | group: root 17 | mode: '755' 18 | register: result 19 | delay: 1 20 | retries: 3 21 | until: result is not failed 22 | 23 | - name: Create configuration directory 24 | ansible.builtin.file: 25 | path: '{{ k3s_map.node.directory.config }}' 26 | state: directory 27 | owner: root 28 | group: root 29 | mode: '755' 30 | 31 | - name: Set role postinstall fact 32 | ansible.builtin.set_fact: 33 | k3s_postinstall: false 34 | 35 | - name: Create configuration file 36 | ansible.builtin.template: 37 | src: config.j2 38 | dest: '{{ k3s_project.cluster.config }}' 39 | owner: root 40 | group: root 41 | mode: '600' 42 | 43 | - name: Create service file 44 | ansible.builtin.template: 45 | src: service.j2 46 | dest: /etc/systemd/system/{{ k3s_map.service.name }}.service 47 | owner: root 48 | group: root 49 | mode: '644' 50 | 51 | - name: Create service environment file 52 | ansible.builtin.file: 53 | path: /etc/systemd/system/{{ k3s_map.service.name }}.service.env 54 | access_time: preserve 55 | modification_time: preserve 56 | state: touch 57 | owner: root 58 | group: root 59 | mode: '600' 60 | 61 | - name: Flush handlers 62 | ansible.builtin.meta: flush_handlers 63 | 64 | - name: Role Configuration 65 | ansible.builtin.import_tasks: 66 | file: configuration.yaml 67 | 68 | - name: Server Configuration 69 | notify: Restart service 70 | when: inventory_hostname in k3s_map.server.hosts 71 | block: 72 | - name: Set role postinstall fact 73 | ansible.builtin.set_fact: 74 | k3s_postinstall: true 75 | 76 | - name: Update server configuration file 77 | ansible.builtin.template: 78 | src: config.j2 79 | dest: '{{ k3s_project.cluster.config }}' 80 | owner: root 81 | group: root 82 | mode: '600' 83 | -------------------------------------------------------------------------------- /roles/k3s/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Cluster Validation 8 | when: inventory_hostname == k3s_map.server.default_host 9 | run_once: true 10 | block: 11 | - name: Get binary status 12 | ansible.builtin.stat: 13 | path: '{{ k3s_project.node.binary }}' 14 | changed_when: not k3s_binary.stat.exists 15 | register: k3s_binary 16 | 17 | - name: Validate deployed cluster 18 | ansible.builtin.assert: 19 | that: k3s_binary.stat.exists 20 | fail_msg: 'ERROR: K3s cluster not deployed.' 21 | quiet: true 22 | 23 | - name: Get deployed cluster version 24 | kubernetes.core.k8s_cluster_info: 25 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 26 | register: k3s_cluster 27 | no_log: true 28 | 29 | - name: Role Upgrade 30 | block: 31 | - name: Install k3s binary 32 | ansible.builtin.get_url: 33 | url: '{{ k3s_project.release.k3s.file }}' 34 | checksum: sha256:{{ k3s_project.release.k3s.checksum }} 35 | dest: '{{ k3s_project.node.binary }}' 36 | owner: root 37 | group: root 38 | mode: '755' 39 | register: result 40 | delay: 1 41 | retries: 3 42 | until: result is not failed 43 | when: k3s_cluster.version.server.kubernetes.gitVersion != k3s_vars.release.k3s.version 44 | 45 | - name: Get configuration file status 46 | ansible.builtin.stat: 47 | checksum: sha256 48 | path: '{{ k3s_project.cluster.config }}' 49 | register: k3s_file 50 | 51 | - name: Set role postinstall fact 52 | ansible.builtin.set_fact: 53 | k3s_postinstall: false 54 | 55 | - name: Update configuration file 56 | ansible.builtin.template: 57 | src: config.j2 58 | dest: '{{ k3s_project.cluster.config }}' 59 | owner: root 60 | group: root 61 | mode: '600' 62 | 63 | - name: Update service file 64 | ansible.builtin.template: 65 | src: service.j2 66 | dest: /etc/systemd/system/{{ k3s_map.service.name }}.service 67 | owner: root 68 | group: root 69 | mode: '644' 70 | 71 | - name: Role Configuration 72 | ansible.builtin.import_tasks: 73 | file: configuration.yaml 74 | 75 | - name: Set role postinstall fact 76 | ansible.builtin.set_fact: 77 | k3s_postinstall: true 78 | 79 | - name: Update configuration file 80 | ansible.builtin.template: 81 | src: config.j2 82 | dest: '{{ k3s_project.cluster.config }}' 83 | owner: root 84 | group: root 85 | mode: '600' 86 | 87 | - name: Get revised configuration file status 88 | ansible.builtin.stat: 89 | checksum: sha256 90 | path: '{{ k3s_project.cluster.config }}' 91 | register: k3s_file_revised 92 | 93 | - name: Schedule reboot 94 | ansible.builtin.file: 95 | path: /var/run/reboot-required 96 | access_time: preserve 97 | modification_time: preserve 98 | state: touch 99 | owner: root 100 | group: root 101 | mode: '644' 102 | when: > 103 | (k3s_file.stat.checksum != k3s_file_revised.stat.checksum) or 104 | (k3s_cluster.version.server.kubernetes.gitVersion != k3s_vars.release.k3s.version) 105 | -------------------------------------------------------------------------------- /roles/k3s/tasks/validation.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_tasks: 4 | file: facts.yaml 5 | 6 | - name: Role Validation 7 | when: ('validation' in ansible_run_tags) 8 | run_once: true 9 | block: 10 | - name: Validate inventory 11 | ansible.builtin.assert: 12 | that: k3s_map.server.ha is truthy or k3s_map.server.non_ha is truthy 13 | fail_msg: |- 14 | ERROR: Invalid number of 'server' type nodes. 15 | - Defined nodes: {{ k3s_map.server.hosts | length }} ({{ k3s_map.server.hosts | join(', ') }}) 16 | - Valid values: 1, higher than 2 17 | FIXES: 18 | - Update the number of 'server' type nodes, into inventory file. 19 | quiet: true 20 | 21 | - name: Validate release checksum url 22 | ansible.builtin.uri: 23 | url: '{{ checksum }}' 24 | timeout: 5 25 | loop: 26 | - '{{ k3s_project.release.k3s.checksum }}' 27 | - '{{ k3s_project.release.kubepug.checksum }}' 28 | loop_control: 29 | loop_var: checksum 30 | register: result 31 | delay: 1 32 | retries: 3 33 | until: result is not failed 34 | 35 | - name: Validate release file url 36 | ansible.builtin.uri: 37 | url: '{{ file }}' 38 | timeout: 5 39 | loop: 40 | - '{{ k3s_project.release.k3s.file }}' 41 | - '{{ k3s_project.release.kubepug.file }}' 42 | loop_control: 43 | loop_var: file 44 | register: result 45 | delay: 1 46 | retries: 3 47 | until: result is not failed 48 | -------------------------------------------------------------------------------- /roles/k3s/templates/config.j2: -------------------------------------------------------------------------------- 1 | data-dir: {{ k3s_map.node.directory.data }} 2 | {% if k3s_map.node.default_registry_endpoint.enabled is falsy %} 3 | disable-default-registry-endpoint: true 4 | {% endif %} 5 | {% if k3s_node.service | lower == 'server' %} 6 | bind-address: {{ k3s_node.ip }} 7 | cluster-domain: {{ k3s_vars.cluster.domain }} 8 | {% if k3s_map.server.ha is truthy and k3s_postinstall is falsy and inventory_hostname == k3s_map.server.default_host %} 9 | cluster-init: true 10 | {% endif %} 11 | disable: 12 | - coredns 13 | - local-storage 14 | - metrics-server 15 | - servicelb 16 | - traefik 17 | disable-cloud-controller: true 18 | disable-kube-proxy: true 19 | disable-network-policy: true 20 | embedded-registry: true 21 | {% if k3s_map.server.ha %} 22 | etcd-expose-metrics: true 23 | {% endif %} 24 | flannel-backend: none 25 | kube-controller-manager-arg: bind-address={{ k3s_node.ip }} 26 | kube-scheduler-arg: bind-address={{ k3s_node.ip }} 27 | {% endif %} 28 | kubelet-arg: 29 | {{ k3s_resources.node.kubelet.args | to_nice_yaml | indent(2) }} 30 | {%- if 31 | (k3s_resources.node.taint.agent | length > 0) or 32 | (k3s_vars.cluster.controlplane.tainted is truthy and k3s_node.service | lower == 'server' and k3s_resources.node.taint.server | length > 0) 33 | %} 34 | node-taint: 35 | {% if k3s_resources.node.taint.agent | length > 0 %} 36 | {{ k3s_resources.node.taint.agent | to_nice_yaml | indent(2) }} 37 | {%- endif %} 38 | {% if k3s_vars.cluster.controlplane.tainted is truthy and k3s_node.service | lower == 'server' and k3s_resources.node.taint.server | length > 0 %} 39 | {{ k3s_resources.node.taint.server | to_nice_yaml | indent(2) }} 40 | {%- endif %} 41 | {% endif %} 42 | {% if k3s_map.server.ha is truthy and (k3s_postinstall is truthy or k3s_node.service | lower == 'agent') %} 43 | server: https://{{ k3s_vars.server.api.host }}:{{ k3s_vars.server.api.port }} 44 | {% elif 45 | (inventory_hostname != k3s_map.server.default_host and k3s_node.service | lower == 'server') or 46 | (k3s_map.server.non_ha is truthy and k3s_node.service | lower == 'agent') 47 | %} 48 | server: https://{{ k3s_map.server.default_host }}:{{ k3s_vars.server.api.port }} 49 | {% endif %} 50 | {% if k3s_map.server.ha is truthy and k3s_node.service | lower == 'server' %} 51 | tls-san: 52 | {{ k3s_vars.cluster.tls_san | to_nice_yaml | indent(2) }} 53 | {%- endif %} 54 | {% if k3s_project.cluster.token | length > 0 %} 55 | token: {{ k3s_project.cluster.token }} 56 | {% endif %} 57 | -------------------------------------------------------------------------------- /roles/k3s/templates/haproxy.j2: -------------------------------------------------------------------------------- 1 | backend k3s-backend 2 | balance roundrobin 3 | mode tcp 4 | option tcplog 5 | option tcp-check 6 | {% for host, ip in k3s_map.server.hosts | zip(k3s_map_server.ips) %} 7 | server {{ host }} {{ ip }}:{{ k3s_vars.server.api.port }} check 8 | {% endfor %} 9 | 10 | frontend k3s-frontend 11 | bind {{ k3s_vars.server.api.host }}:{{ k3s_vars.server.api.port }} 12 | default_backend k3s-backend 13 | mode tcp 14 | option tcplog 15 | -------------------------------------------------------------------------------- /roles/k3s/templates/keepalived.j2: -------------------------------------------------------------------------------- 1 | global_defs { 2 | enable_script_security 3 | max_auto_priority 99 4 | notification_email { 5 | {{ global_map.credentials.cluster.postfix.user.alias }} 6 | } 7 | notification_email_from {{ global_map.credentials.cluster.postfix.user.alias }} 8 | script_user haproxy 9 | smtp_connect_timeout 30 10 | smtp_server 127.0.0.1 11 | vrrp_startup_delay 10 12 | } 13 | 14 | vrrp_script chk_haproxy { 15 | script '/usr/bin/killall -0 haproxy' 16 | } 17 | 18 | vrrp_instance haproxy-vip { 19 | authentication { 20 | auth_type AH 21 | auth_pass {{ k3s_map.loadbalancer.password }} 22 | } 23 | interface {{ k3s_vars.network.interface }} 24 | {% if inventory_hostname == k3s_map.loadbalancer.hosts[0] %} 25 | priority 200 26 | state MASTER 27 | unicast_peer { 28 | {{ k3s_map_loadbalancer.ips[1] }} 29 | } 30 | unicast_src_ip {{ k3s_map_loadbalancer.ips[0] }} 31 | {% else %} 32 | priority 100 33 | state BACKUP 34 | unicast_peer { 35 | {{ k3s_map_loadbalancer.ips[0] }} 36 | } 37 | unicast_src_ip {{ k3s_map_loadbalancer.ips[1] }} 38 | {% endif %} 39 | smtp_alert 40 | track_script { 41 | chk_haproxy 42 | } 43 | virtual_router_id 10 44 | virtual_ipaddress { 45 | {{ k3s_vars.server.api.host }} 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /roles/k3s/templates/registries.j2: -------------------------------------------------------------------------------- 1 | mirrors: 2 | docker.io: 3 | gcr.io: 4 | ghcr.io: 5 | quay.io: 6 | registry.k8s.io: 7 | -------------------------------------------------------------------------------- /roles/k3s/templates/service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Lightweight Kubernetes {{ k3s_node.service | capitalize }} 3 | Documentation=https://k3s.io 4 | Wants=network-online.target 5 | After=network-online.target 6 | 7 | [Service] 8 | Type=notify 9 | Delegate=yes 10 | EnvironmentFile=-/etc/default/%N 11 | EnvironmentFile=-/etc/systemd/system/{{ k3s_map.service.name }}.service.env 12 | ExecStart={{ k3s_project.node.binary }} {{ k3s_node.service }}{{ ' --debug' if k3s_vars.service.debug }} 13 | ExecReload=/bin/kill -s HUP $MAINPID 14 | KillMode=process 15 | LimitCORE=infinity 16 | LimitNOFILE=infinity 17 | LimitNPROC=infinity 18 | TasksMax=infinity 19 | TimeoutStartSec=0 20 | Restart=on-failure 21 | RestartSec=5s 22 | 23 | [Install] 24 | WantedBy=multi-user.target 25 | -------------------------------------------------------------------------------- /roles/kured/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: kured 3 | description: Documentation generator for kured Ansible role 4 | home: https://github.com/kubereboot/charts 5 | version: 5.6.1 6 | -------------------------------------------------------------------------------- /roles/kured/README.md: -------------------------------------------------------------------------------- 1 | # kured 2 | 3 | ![Version: 5.6.1](https://img.shields.io/badge/Version-5.6.1-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `kured` [chart](https://github.com/kubereboot/charts/tree/kured-5.6.1/charts/kured) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/kured), for additional details. 6 | 7 | ## Role Variables 8 | 9 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `kured_map` collection. 10 | 11 | > [!TIP] 12 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 13 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 14 | 15 | | Key | Type | Default | Description | 16 | |-----|------|---------|-------------| 17 | | kured_vars.kubernetes.configuration.concurrency | int | `1` | | 18 | | kured_vars.kubernetes.configuration.period | string | `"15m"` | | 19 | | kured_vars.kubernetes.configuration.reboot_delay | string | `"60s"` | | 20 | | kured_vars.kubernetes.configuration.slack.enabled | bool | `true` | | 21 | | kured_vars.kubernetes.configuration.slack.messages.drain | string | `""` | | 22 | | kured_vars.kubernetes.configuration.slack.messages.enabled | bool | `false` | | 23 | | kured_vars.kubernetes.configuration.slack.messages.reboot | string | `""` | | 24 | | kured_vars.kubernetes.configuration.slack.messages.uncordon | string | `""` | | 25 | | kured_vars.kubernetes.configuration.slack.notify_url | string | Set value into [all.yaml](../../inventory/cluster/group_vars/all.yaml) `credentials` collection | Slack notifications, see [documentation](https://kured.dev/docs/configuration/#notifications) for details | 26 | | kured_vars.kubernetes.configuration.time.end | string | `"08:00"` | | 27 | | kured_vars.kubernetes.configuration.time.start | string | `"04:00"` | | 28 | | kured_vars.kubernetes.configuration.time.zone | string | `"UTC"` | | 29 | | kured_vars.kubernetes.helm.chart.name | string | `"kured"` | | 30 | | kured_vars.kubernetes.helm.chart.version | string | `"v5.6.1"` | | 31 | | kured_vars.kubernetes.helm.repository.name | string | `"charts"` | | 32 | | kured_vars.kubernetes.helm.repository.org | string | `"kubereboot"` | | 33 | | kured_vars.kubernetes.helm.repository.url | string | `"https://kubereboot.github.io"` | | 34 | | kured_vars.kubernetes.namespace | string | `"kube-system"` | | 35 | | kured_vars.kubernetes.resources.limits.cpu | string | `nil` | | 36 | | kured_vars.kubernetes.resources.limits.memory | string | `"128Mi"` | | 37 | | kured_vars.kubernetes.resources.requests.cpu | string | `"10m"` | | 38 | | kured_vars.kubernetes.resources.requests.memory | string | `"128Mi"` | | 39 | -------------------------------------------------------------------------------- /roles/kured/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/kured), for additional details. 12 | 13 | ## Role Variables 14 | 15 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 16 | 17 | > [!TIP] 18 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 19 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 20 | 21 | {{ template "chart.valuesTable" . }} 22 | -------------------------------------------------------------------------------- /roles/kured/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kured_vars: 3 | kubernetes: 4 | configuration: 5 | concurrency: 1 6 | period: 15m 7 | reboot_delay: 60s 8 | slack: 9 | enabled: true 10 | messages: 11 | enabled: false 12 | drain: '' 13 | reboot: '' 14 | uncordon: '' 15 | # -- (string) Slack notifications, see [documentation](https://kured.dev/docs/configuration/#notifications) for details 16 | # @default -- Set value into [all.yaml](../../inventory/cluster/group_vars/all.yaml) `credentials` collection 17 | notify_url: 18 | time: 19 | start: '04:00' 20 | end: '08:00' 21 | zone: UTC 22 | helm: 23 | chart: 24 | name: kured 25 | version: v5.6.1 26 | repository: 27 | name: charts 28 | org: kubereboot 29 | url: https://kubereboot.github.io 30 | namespace: kube-system 31 | resources: 32 | limits: 33 | cpu: null 34 | memory: 128Mi 35 | requests: 36 | cpu: 10m 37 | memory: 128Mi 38 | -------------------------------------------------------------------------------- /roles/kured/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | kured_map: 5 | helm: 6 | chart: 7 | reference: '{{ kured_vars.kubernetes.helm.repository.org }}/{{ kured_vars.kubernetes.helm.chart.name }}' 8 | version: '{{ kured_vars.kubernetes.helm.chart.version[1:] }}' 9 | platform: 10 | key: https://github.com 11 | raw: https://raw.githubusercontent.com 12 | repository: 13 | name: '{{ kured_vars.kubernetes.helm.repository.org }}/{{ kured_vars.kubernetes.helm.repository.name }}' 14 | url: '{{ kured_vars.kubernetes.helm.repository.url }}/{{ kured_vars.kubernetes.helm.repository.name }}' 15 | timeout: 5m0s 16 | metrics: 17 | service: 18 | annotations: 19 | prometheus.io/path: /metrics 20 | prometheus.io/port: 8080 21 | prometheus.io/scrape: 'true' 22 | monitor: 23 | enabled: true 24 | scrape: 25 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 26 | interval: null 27 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 28 | timeout: null 29 | run_once: true 30 | 31 | - name: Set project fact 32 | ansible.builtin.set_fact: 33 | kured_project: 34 | tag: '{{ kured_vars.kubernetes.helm.chart.name }}-{{ kured_map.helm.chart.version }}' 35 | url: '{{ kured_map.helm.platform.key }}/{{ kured_map.helm.repository.name }}/releases/tag' 36 | run_once: true 37 | -------------------------------------------------------------------------------- /roles/kured/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Add repository 17 | kubernetes.core.helm_repository: 18 | name: '{{ kured_vars.kubernetes.helm.repository.org }}' 19 | repo_url: '{{ kured_map.helm.repository.url }}' 20 | force_update: true 21 | 22 | - name: Chart Setup 23 | run_once: true 24 | block: 25 | - name: Set chart postinstall fact 26 | ansible.builtin.set_fact: 27 | kured_postinstall: false 28 | 29 | - name: Install chart 30 | kubernetes.core.helm: 31 | chart_ref: '{{ kured_map.helm.chart.reference }}' 32 | chart_version: '{{ kured_vars.kubernetes.helm.chart.version }}' 33 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 34 | name: '{{ kured_vars.kubernetes.helm.chart.name }}' 35 | namespace: '{{ kured_vars.kubernetes.namespace }}' 36 | timeout: '{{ kured_map.helm.timeout }}' 37 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 38 | create_namespace: true 39 | update_repo_cache: true 40 | wait: true 41 | register: result 42 | delay: 1 43 | retries: 3 44 | until: result is not failed 45 | -------------------------------------------------------------------------------- /roles/kured/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: 4 | - inventory_hostname in k3s_map.server.hosts 5 | - kured_map.metrics.service.monitor.enabled 6 | run_once: true 7 | block: 8 | - name: Update chart postinstall fact 9 | ansible.builtin.set_fact: 10 | kured_postinstall: true 11 | 12 | - name: Update chart postinstall values 13 | kubernetes.core.helm: 14 | chart_ref: '{{ kured_map.helm.chart.reference }}' 15 | chart_version: '{{ kured_vars.kubernetes.helm.chart.version }}' 16 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 17 | name: '{{ kured_vars.kubernetes.helm.chart.name }}' 18 | namespace: '{{ kured_vars.kubernetes.namespace }}' 19 | timeout: '{{ kured_map.helm.timeout }}' 20 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 21 | reset_values: false 22 | reuse_values: true 23 | wait: true 24 | register: result 25 | delay: 1 26 | retries: 3 27 | until: result is not failed 28 | -------------------------------------------------------------------------------- /roles/kured/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ kured_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | -------------------------------------------------------------------------------- /roles/kured/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/kured/templates/values.j2: -------------------------------------------------------------------------------- 1 | configuration: 2 | concurrency: {{ kured_vars.kubernetes.configuration.concurrency }} 3 | period: {{ kured_vars.kubernetes.configuration.period }} 4 | rebootDelay: {{ kured_vars.kubernetes.configuration.reboot_delay }} 5 | {% if kured_vars.kubernetes.configuration.slack.enabled is truthy %} 6 | {% if kured_vars.kubernetes.configuration.slack.messages.enabled is truthy %} 7 | messageTemplateDrain: {{ kured_vars.kubernetes.configuration.slack.messages.drain }} 8 | messageTemplateReboot: {{ kured_vars.kubernetes.configuration.slack.messages.reboot }} 9 | messageTemplateUncordon: {{ kured_vars.kubernetes.configuration.slack.messages.uncordon }} 10 | {% endif %} 11 | notifyUrl: {{ global_map.credentials.kured.slack.notify.url }} 12 | {% endif %} 13 | startTime: {{ kured_vars.kubernetes.configuration.time.start }} 14 | endTime: {{ kured_vars.kubernetes.configuration.time.end }} 15 | timeZone: {{ kured_vars.kubernetes.configuration.time.zone }} 16 | {% if kured_postinstall is truthy and kured_map.metrics.service.monitor.enabled is truthy %} 17 | metrics: 18 | create: true 19 | {% if kured_map.metrics.service.monitor.scrape.interval is falsy %} 20 | interval: {{ victoriametrics_map.service.monitor.scrape.interval }} 21 | {% else %} 22 | interval: {{ kured_map.metrics.service.monitor.scrape.interval }} 23 | {% endif %} 24 | labels: 25 | release: {{ victoriametrics_vars.kubernetes.helm.chart.victoriametrics.alias }} 26 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 27 | {% if kured_map.metrics.service.monitor.scrape.timeout is falsy %} 28 | scrapeTimeout: {{ victoriametrics_map.service.monitor.scrape.timeout }} 29 | {% else %} 30 | scrapeTimeout: {{ kured_map.metrics.service.monitor.scrape.timeout }} 31 | {% endif %} 32 | service: 33 | annotations: 34 | {% for key, value in kured_map.metrics.service.annotations.items() %} 35 | {{ key | indent(4) }}: {{ value }} 36 | {% endfor %} 37 | create: true 38 | name: {{ kured_vars.kubernetes.helm.chart.name }} 39 | {% endif %} 40 | resources: 41 | limits: 42 | {% if kured_vars.kubernetes.resources.limits.cpu is truthy %} 43 | cpu: {{ kured_vars.kubernetes.resources.limits.cpu }} 44 | {% endif %} 45 | memory: {{ kured_vars.kubernetes.resources.limits.memory }} 46 | requests: 47 | cpu: {{ kured_vars.kubernetes.resources.requests.cpu }} 48 | memory: {{ kured_vars.kubernetes.resources.requests.memory }} 49 | {% if k3s_vars.cluster.controlplane.tainted is truthy and k3s_project.cluster.tolerations | length > 0 %} 50 | tolerations: 51 | {{ k3s_project.cluster.tolerations | to_nice_yaml(indent=2) | indent(2) }} 52 | {% endif %} 53 | -------------------------------------------------------------------------------- /roles/longhorn/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: longhorn 3 | description: Documentation generator for longhorn Ansible role 4 | home: https://github.com/longhorn/charts 5 | version: 1.8.1 6 | dependencies: 7 | - name: longhornctl 8 | repository: https://github.com/longhorn/cli 9 | version: 1.8.1 10 | -------------------------------------------------------------------------------- /roles/longhorn/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/longhorn), for additional details. 12 | 13 | ## Role Dependencies 14 | 15 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `release` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 26 | 27 | {{ template "chart.valuesTable" . }} 28 | -------------------------------------------------------------------------------- /roles/longhorn/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | longhorn_vars: 3 | kubernetes: 4 | backup: 5 | enabled: true 6 | poll_interval: 300 7 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/longhorn/#backup), for details 8 | target: cifs://nas.noty.cc/backup 9 | default_settings: 10 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#allow-collecting-longhorn-usage-metrics), for details 11 | collect_usage_metrics: false 12 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#concurrent-automatic-engine-upgrade-per-node-limit), for details 13 | concurrent_automatic_engine_upgrade_limit: 1 14 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#default-data-locality), for details 15 | data_locality: best-effort 16 | log_level: Warn 17 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#node-drain-policy), for details 18 | node_drain_policy: block-for-eviction 19 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#pod-deletion-policy-when-node-is-down), for details 20 | pod_deletion_policy: delete-both-statefulset-and-deployment-pod 21 | volume: 22 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#replica-auto-balance), for details 23 | replica_auto_balance: least-effort 24 | # -- See [documentation](https://longhorn.io/docs/latest/references/settings/#default-replica-count), for details 25 | replicas: 2 26 | frontend: 27 | gateway: 28 | service: longhorn-frontend 29 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/externaldns/#front-ends), for details 30 | subdomain: longhorn 31 | ingress: 32 | # -- If `false`, HTTPRoute is used, otherwise Ingress 33 | enabled: false 34 | helm: 35 | chart: 36 | name: longhorn 37 | version: v1.8.1 38 | repository: 39 | name: longhorn 40 | org: longhorn 41 | url: https://charts.longhorn.io 42 | namespace: kube-system 43 | release: 44 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/server/#hardware), for details 45 | file: longhornctl-linux-arm64 46 | repository: 47 | name: cli 48 | org: longhorn 49 | version: v1.8.1 50 | -------------------------------------------------------------------------------- /roles/longhorn/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | longhorn_map: 5 | credentials: 6 | backup: 7 | secret: '{{ longhorn_vars.kubernetes.helm.chart.name }}-backup-credentials' 8 | directory: 9 | data: /var/lib/longhorn 10 | helm: 11 | chart: 12 | reference: '{{ longhorn_vars.kubernetes.helm.repository.org }}/{{ longhorn_vars.kubernetes.helm.chart.name }}' 13 | version: '{{ longhorn_vars.kubernetes.helm.chart.version[1:] }}' 14 | platform: 15 | key: https://github.com 16 | raw: https://raw.githubusercontent.com 17 | repository: 18 | name: '{{ longhorn_vars.kubernetes.helm.repository.org }}/{{ longhorn_vars.kubernetes.helm.repository.name }}' 19 | timeout: 5m0s 20 | gateway: 21 | frontend: 22 | annotations: 23 | cert-manager.io/cluster-issuer: '{{ externaldns_project.cloudflare.cluster.issuer }}' 24 | hostname: '{{ longhorn_vars.kubernetes.frontend.gateway.subdomain }}.{{ externaldns_vars.cloudflare.host.domain }}' 25 | http_route: 26 | insecure: '{{ longhorn_vars.kubernetes.frontend.gateway.service }}-http' 27 | secure: '{{ longhorn_vars.kubernetes.frontend.gateway.service }}-https' 28 | metrics: 29 | service: 30 | monitor: 31 | enabled: true 32 | scrape: 33 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 34 | interval: null 35 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 36 | timeout: null 37 | run_once: true 38 | 39 | - name: Set project fact 40 | ansible.builtin.set_fact: 41 | longhorn_project: 42 | release: 43 | file: '{{ longhorn_vars.release.version }}/{{ longhorn_vars.release.file }}' 44 | url: "{{ 45 | '/'.join([longhorn_map.helm.platform.key, 46 | longhorn_vars.release.repository.org, 47 | longhorn_vars.release.repository.name, 'releases', 'download']) 48 | }}" 49 | tag: '{{ longhorn_vars.kubernetes.helm.chart.version }}' 50 | url: '{{ longhorn_map.helm.platform.key }}/{{ longhorn_map.helm.repository.name }}/releases/tag' 51 | run_once: true 52 | -------------------------------------------------------------------------------- /roles/longhorn/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: inventory_hostname in k3s_map.server.hosts 4 | run_once: true 5 | block: 6 | - name: Metrics Setup 7 | when: longhorn_map.metrics.service.monitor.enabled is truthy 8 | block: 9 | - name: Update chart postinstall fact 10 | ansible.builtin.set_fact: 11 | longhorn_postinstall: true 12 | 13 | - name: Update chart postinstall values 14 | kubernetes.core.helm: 15 | chart_ref: '{{ longhorn_map.helm.chart.reference }}' 16 | chart_version: '{{ longhorn_vars.kubernetes.helm.chart.version }}' 17 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 18 | name: '{{ longhorn_vars.kubernetes.helm.chart.name }}' 19 | namespace: '{{ longhorn_vars.kubernetes.namespace }}' 20 | timeout: '{{ longhorn_map.helm.timeout }}' 21 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 22 | reset_values: false 23 | reuse_values: true 24 | wait: true 25 | register: result 26 | delay: 1 27 | retries: 3 28 | until: result is not failed 29 | -------------------------------------------------------------------------------- /roles/longhorn/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.include_role: 4 | name: '{{ role }}' 5 | tasks_from: facts 6 | loop: 7 | - external-dns 8 | - longhorn 9 | - k3s 10 | loop_control: 11 | loop_var: role 12 | 13 | - name: Role Reset 14 | block: 15 | - name: Remove repository 16 | kubernetes.core.helm_repository: 17 | name: '{{ longhorn_vars.kubernetes.helm.repository.org }}' 18 | repo_state: absent 19 | when: 20 | - inventory_hostname in k3s_map.server.hosts 21 | - "'helm' in ansible_facts.packages" 22 | 23 | - name: Remove directory 24 | ansible.builtin.file: 25 | path: '{{ longhorn_map.directory.data }}' 26 | state: absent 27 | -------------------------------------------------------------------------------- /roles/longhorn/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/longhorn/templates/credentials.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ longhorn_map.credentials.backup.secret }} 5 | namespace: {{ longhorn_vars.kubernetes.namespace }} 6 | stringData: 7 | CIFS_PASSWORD: {{ global_map.credentials.longhorn.backup.user.password }} 8 | CIFS_USERNAME: {{ global_map.credentials.longhorn.backup.user.name }} 9 | type: Opaque 10 | -------------------------------------------------------------------------------- /roles/longhorn/templates/gateway.j2: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: Gateway 3 | metadata: 4 | annotations: 5 | {% for key, value in longhorn_map.gateway.frontend.annotations.items() %} 6 | {{ key | indent(4) }}: {{ value }} 7 | {% endfor %} 8 | name: {{ longhorn_vars.kubernetes.frontend.gateway.service }} 9 | namespace: {{ longhorn_vars.kubernetes.namespace }} 10 | spec: 11 | gatewayClassName: cilium 12 | listeners: 13 | - allowedRoutes: 14 | kinds: 15 | - group: gateway.networking.k8s.io 16 | kind: HTTPRoute 17 | namespaces: 18 | from: Same 19 | hostname: {{ longhorn_map.gateway.frontend.hostname }} 20 | name: http 21 | port: 80 22 | protocol: HTTP 23 | - allowedRoutes: 24 | kinds: 25 | - group: gateway.networking.k8s.io 26 | kind: HTTPRoute 27 | namespaces: 28 | from: Same 29 | hostname: {{ longhorn_map.gateway.frontend.hostname }} 30 | name: https 31 | port: 443 32 | protocol: HTTPS 33 | tls: 34 | certificateRefs: 35 | - kind: Secret 36 | name: {{ externaldns_vars.cloudflare.prefix }}-{{ longhorn_vars.kubernetes.frontend.gateway.service }} 37 | mode: Terminate 38 | -------------------------------------------------------------------------------- /roles/longhorn/templates/http_route_insecure.j2: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: HTTPRoute 3 | metadata: 4 | name: {{ longhorn_map.gateway.frontend.http_route.insecure }} 5 | namespace: {{ longhorn_vars.kubernetes.namespace }} 6 | spec: 7 | hostnames: 8 | - {{ longhorn_map.gateway.frontend.hostname }} 9 | parentRefs: 10 | - kind: Gateway 11 | name: {{ longhorn_vars.kubernetes.frontend.gateway.service }} 12 | namespace: {{ longhorn_vars.kubernetes.namespace }} 13 | sectionName: http 14 | rules: 15 | - filters: 16 | - requestRedirect: 17 | scheme: https 18 | statusCode: 301 19 | type: RequestRedirect 20 | -------------------------------------------------------------------------------- /roles/longhorn/templates/http_route_secure.j2: -------------------------------------------------------------------------------- 1 | apiVersion: gateway.networking.k8s.io/v1 2 | kind: HTTPRoute 3 | metadata: 4 | name: {{ longhorn_map.gateway.frontend.http_route.secure }} 5 | namespace: {{ longhorn_vars.kubernetes.namespace }} 6 | spec: 7 | hostnames: 8 | - {{ longhorn_map.gateway.frontend.hostname }} 9 | parentRefs: 10 | - kind: Gateway 11 | name: {{ longhorn_vars.kubernetes.frontend.gateway.service }} 12 | namespace: {{ longhorn_vars.kubernetes.namespace }} 13 | sectionName: https 14 | rules: 15 | - backendRefs: 16 | - kind: Service 17 | name: {{ longhorn_vars.kubernetes.frontend.gateway.service }} 18 | port: 80 19 | matches: 20 | - path: 21 | type: PathPrefix 22 | value: / 23 | -------------------------------------------------------------------------------- /roles/longhorn/templates/values.j2: -------------------------------------------------------------------------------- 1 | {% if longhorn_vars.kubernetes.backup.enabled is truthy %} 2 | defaultBackupStore: 3 | backupTarget: {{ longhorn_vars.kubernetes.backup.target }} 4 | {% if longhorn_vars.kubernetes.backup.target[:3] | lower != 'nfs' %} 5 | backupTargetCredentialSecret: {{ longhorn_map.credentials.backup.secret }} 6 | {% endif %} 7 | pollInterval: {{ longhorn_vars.kubernetes.backup.poll_interval }} 8 | {% endif %} 9 | defaultSettings: 10 | allowCollectingLonghornUsageMetrics: {{ longhorn_vars.kubernetes.default_settings.collect_usage_metrics | lower }} 11 | autoCleanupRecurringJobBackupSnapshot: true 12 | autoCleanupSnapshotWhenDeleteBackup: true 13 | autoCleanupSystemGeneratedSnapshot: true 14 | concurrentAutomaticEngineUpgradePerNodeLimit: {{ longhorn_vars.kubernetes.default_settings.concurrent_automatic_engine_upgrade_limit }} 15 | defaultDataLocality: {{ longhorn_vars.kubernetes.default_settings.data_locality }} 16 | defaultDataPath: {{ longhorn_map.directory.data }} 17 | {% if longhorn_vars.kubernetes.default_settings.volume.replicas < 2 %} 18 | defaultReplicaCount: 2 19 | {% else %} 20 | defaultReplicaCount: {{ longhorn_vars.kubernetes.default_settings.volume.replicas }} 21 | {% endif %} 22 | disableSchedulingOnCordonedNode: true 23 | logLevel: {{ longhorn_vars.kubernetes.default_settings.log_level }} 24 | nodeDownPodDeletionPolicy: {{ longhorn_vars.kubernetes.default_settings.pod_deletion_policy }} 25 | nodeDrainPolicy: {{ longhorn_vars.kubernetes.default_settings.node_drain_policy }} 26 | orphanAutoDeletion: true 27 | removeSnapshotsDuringFilesystemTrim: true 28 | replicaAutoBalance: {{ longhorn_vars.kubernetes.default_settings.volume.replica_auto_balance }} 29 | {% if k3s_vars.cluster.controlplane.tainted is truthy %} 30 | {% if k3s_resources.node.taint.server | length > 0 %} 31 | taintToleration: {{ k3s_resources.node.taint.server | join | trim }} 32 | {% endif %} 33 | {% if externaldns_vars.cloudflare.host.domain | lower != 'disabled' and longhorn_vars.kubernetes.frontend.ingress.enabled is truthy %} 34 | ingress: 35 | annotations: 36 | {% for key, value in longhorn_map.gateway.frontend.annotations.items() %} 37 | {{ key | indent(4) }}: {{ value }} 38 | {% endfor %} 39 | enabled: true 40 | host: {{ longhorn_map.gateway.frontend.hostname }} 41 | ingressClassName: cilium 42 | pathType: Prefix 43 | tls: true 44 | tlsSecret: {{ externaldns_vars.cloudflare.prefix }}-{{ longhorn_vars.kubernetes.frontend.gateway.service }} 45 | {% endif %} 46 | {% if k3s_project.cluster.tolerations | length > 0 %} 47 | longhornDriver: 48 | tolerations: 49 | {{ k3s_project.cluster.tolerations | to_nice_yaml(indent=2) | trim | indent(4) }} 50 | longhornManager: 51 | tolerations: 52 | {{ k3s_project.cluster.tolerations | to_nice_yaml(indent=2) | trim | indent(4) }} 53 | {% endif %} 54 | {% endif %} 55 | {% if longhorn_postinstall is truthy and longhorn_map.metrics.service.monitor.enabled is truthy %} 56 | metrics: 57 | serviceMonitor: 58 | enabled: true 59 | {% if longhorn_map.metrics.service.monitor.scrape.interval is falsy %} 60 | interval: {{ victoriametrics_map.service.monitor.scrape.interval }} 61 | {% else %} 62 | interval: {{ longhorn_map.metrics.service.monitor.scrape.interval }} 63 | {% endif %} 64 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 65 | {% if longhorn_map.metrics.service.monitor.scrape.timeout is falsy %} 66 | scrapeTimeout: {{ victoriametrics_map.service.monitor.scrape.timeout }} 67 | {% else %} 68 | scrapeTimeout: {{ longhorn_map.metrics.service.monitor.scrape.timeout }} 69 | {% endif %} 70 | {% endif %} 71 | persistence: 72 | {% if longhorn_vars.kubernetes.default_settings.volume.replicas < 2 %} 73 | defaultClassReplicaCount: 2 74 | {% else %} 75 | defaultClassReplicaCount: {{ longhorn_vars.kubernetes.default_settings.volume.replicas }} 76 | {% endif %} 77 | defaultDataLocality: {{ longhorn_vars.kubernetes.default_settings.data_locality }} 78 | migratable: true 79 | -------------------------------------------------------------------------------- /roles/metrics-server/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: metrics-server 3 | description: Documentation generator for metrics-server Ansible role 4 | home: https://github.com/kubernetes-sigs/metrics-server 5 | version: 3.12.2 6 | -------------------------------------------------------------------------------- /roles/metrics-server/README.md: -------------------------------------------------------------------------------- 1 | # metrics-server 2 | 3 | ![Version: 3.12.2](https://img.shields.io/badge/Version-3.12.2-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `metrics-server` [chart](https://github.com/kubernetes-sigs/metrics-server/tree/metrics-server-helm-chart-3.12.2/charts/metrics-server) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/metricsserver), for additional details. 6 | 7 | ## Role Variables 8 | 9 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `metricsserver_map` collection. 10 | 11 | > [!TIP] 12 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 13 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 14 | 15 | | Key | Type | Default | Description | 16 | |-----|------|---------|-------------| 17 | | metricsserver_vars.kubernetes.helm.chart.name | string | `"metrics-server"` | | 18 | | metricsserver_vars.kubernetes.helm.chart.version | string | `"v3.12.2"` | | 19 | | metricsserver_vars.kubernetes.helm.repository.name | string | `"metrics-server"` | | 20 | | metricsserver_vars.kubernetes.helm.repository.org | string | `"kubernetes-sigs"` | | 21 | | metricsserver_vars.kubernetes.helm.repository.url | string | `"https://kubernetes-sigs.github.io"` | | 22 | | metricsserver_vars.kubernetes.namespace | string | `"kube-system"` | | 23 | | metricsserver_vars.kubernetes.replicas | int | `1` | | 24 | | metricsserver_vars.kubernetes.resources.limits.cpu | string | `nil` | | 25 | | metricsserver_vars.kubernetes.resources.limits.memory | string | `"128Mi"` | | 26 | | metricsserver_vars.kubernetes.resources.requests.cpu | string | `"10m"` | | 27 | | metricsserver_vars.kubernetes.resources.requests.memory | string | `"128Mi"` | | 28 | | metricsserver_vars.kubernetes.server.args | list | `["--v=1"]` | Additional server arguments, set log level [verbosity](https://google.github.io/glog/stable/logging/#verbose-logging) | 29 | | metricsserver_vars.kubernetes.server.tls.type | string | `"cert-manager"` | Available options are `cert-manager`, `helm` and `metrics-server` | 30 | -------------------------------------------------------------------------------- /roles/metrics-server/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-helm-chart-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name | replace "-" "" -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/metricsserver), for additional details. 12 | 13 | ## Role Variables 14 | 15 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 16 | 17 | > [!TIP] 18 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 19 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 20 | 21 | {{ template "chart.valuesTable" . }} 22 | -------------------------------------------------------------------------------- /roles/metrics-server/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | metricsserver_vars: 3 | kubernetes: 4 | helm: 5 | chart: 6 | name: metrics-server 7 | version: v3.12.2 8 | repository: 9 | name: metrics-server 10 | org: kubernetes-sigs 11 | url: https://kubernetes-sigs.github.io 12 | namespace: kube-system 13 | replicas: 1 14 | resources: 15 | limits: 16 | cpu: null 17 | memory: 128Mi 18 | requests: 19 | cpu: 10m 20 | memory: 128Mi 21 | server: 22 | # -- Additional server arguments, 23 | # set log level [verbosity](https://google.github.io/glog/stable/logging/#verbose-logging) 24 | args: 25 | - --v=1 26 | tls: 27 | # -- Available options are `cert-manager`, `helm` and `metrics-server` 28 | type: cert-manager 29 | -------------------------------------------------------------------------------- /roles/metrics-server/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | metricsserver_map: 5 | helm: 6 | chart: 7 | reference: '{{ metricsserver_vars.kubernetes.helm.repository.name }}/{{ metricsserver_vars.kubernetes.helm.chart.name }}' 8 | version: '{{ metricsserver_vars.kubernetes.helm.chart.version[1:] }}' 9 | platform: 10 | key: https://github.com 11 | raw: https://raw.githubusercontent.com 12 | repository: 13 | name: '{{ metricsserver_vars.kubernetes.helm.repository.org }}/{{ metricsserver_vars.kubernetes.helm.repository.name }}' 14 | url: '{{ metricsserver_vars.kubernetes.helm.repository.url }}/{{ metricsserver_vars.kubernetes.helm.repository.name }}' 15 | timeout: 5m0s 16 | metrics: 17 | service: 18 | monitor: 19 | enabled: true 20 | scrape: 21 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 22 | interval: null 23 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 24 | timeout: null 25 | server: 26 | default_args: 27 | - --cert-dir=/tmp 28 | - --kubelet-preferred-address-types=InternalDNS,InternalIP,Hostname,ExternalDNS,ExternalIP 29 | - --kubelet-request-timeout=5s 30 | - --kubelet-use-node-status-port 31 | - --metric-resolution=15s 32 | run_once: true 33 | 34 | - name: Set project fact 35 | ansible.builtin.set_fact: 36 | metricsserver_project: 37 | tag: '{{ metricsserver_vars.kubernetes.helm.chart.name }}-helm-chart-{{ metricsserver_map.helm.chart.version }}' 38 | url: '{{ metricsserver_map.helm.platform.key }}/{{ metricsserver_map.helm.repository.name }}/releases/tag' 39 | run_once: true 40 | -------------------------------------------------------------------------------- /roles/metrics-server/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Add repository 17 | kubernetes.core.helm_repository: 18 | name: '{{ metricsserver_vars.kubernetes.helm.repository.name }}' 19 | repo_url: '{{ metricsserver_map.helm.repository.url }}' 20 | force_update: true 21 | 22 | - name: Chart Setup 23 | run_once: true 24 | block: 25 | - name: Set chart postinstall fact 26 | ansible.builtin.set_fact: 27 | metricsserver_postinstall: false 28 | 29 | - name: Install chart 30 | kubernetes.core.helm: 31 | chart_ref: '{{ metricsserver_map.helm.chart.reference }}' 32 | chart_version: '{{ metricsserver_vars.kubernetes.helm.chart.version }}' 33 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 34 | name: '{{ metricsserver_vars.kubernetes.helm.chart.name }}' 35 | namespace: '{{ metricsserver_vars.kubernetes.namespace }}' 36 | timeout: '{{ metricsserver_map.helm.timeout }}' 37 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 38 | create_namespace: true 39 | update_repo_cache: true 40 | wait: true 41 | register: result 42 | delay: 1 43 | retries: 3 44 | until: result is not failed 45 | -------------------------------------------------------------------------------- /roles/metrics-server/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: 4 | - inventory_hostname in k3s_map.server.hosts 5 | - metricsserver_map.metrics.service.monitor.enabled 6 | run_once: true 7 | block: 8 | - name: Update chart postinstall fact 9 | ansible.builtin.set_fact: 10 | metricsserver_postinstall: true 11 | 12 | - name: Update chart postinstall values 13 | kubernetes.core.helm: 14 | chart_ref: '{{ metricsserver_map.helm.chart.reference }}' 15 | chart_version: '{{ metricsserver_vars.kubernetes.helm.chart.version }}' 16 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 17 | name: '{{ metricsserver_vars.kubernetes.helm.chart.name }}' 18 | namespace: '{{ metricsserver_vars.kubernetes.namespace }}' 19 | timeout: '{{ metricsserver_map.helm.timeout }}' 20 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 21 | reset_values: false 22 | reuse_values: true 23 | wait: true 24 | register: result 25 | delay: 1 26 | retries: 3 27 | until: result is not failed 28 | -------------------------------------------------------------------------------- /roles/metrics-server/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ metricsserver_vars.kubernetes.helm.repository.name }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | -------------------------------------------------------------------------------- /roles/metrics-server/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/metrics-server/templates/values.j2: -------------------------------------------------------------------------------- 1 | {% if metricsserver_vars.kubernetes.server.args is iterable and metricsserver_vars.kubernetes.server.args | length > 0 %} 2 | args: 3 | {{ metricsserver_vars.kubernetes.server.args | to_nice_yaml | trim | indent(2) }} 4 | {% endif %} 5 | {% if metricsserver_map.server.default_args is iterable and metricsserver_map.server.default_args | length > 0 %} 6 | defaultArgs: 7 | {{ metricsserver_map.server.default_args | to_nice_yaml | trim | indent(2) }} 8 | {% endif %} 9 | podDisruptionBudget: 10 | enabled: true 11 | maxUnavailable: 1 12 | replicas: {{ metricsserver_vars.kubernetes.replicas }} 13 | resources: 14 | limits: 15 | {% if metricsserver_vars.kubernetes.resources.limits.cpu is truthy %} 16 | cpu: {{ metricsserver_vars.kubernetes.resources.limits.cpu }} 17 | {% endif %} 18 | memory: {{ metricsserver_vars.kubernetes.resources.limits.memory }} 19 | requests: 20 | cpu: {{ metricsserver_vars.kubernetes.resources.requests.cpu }} 21 | memory: {{ metricsserver_vars.kubernetes.resources.requests.memory }} 22 | service: 23 | labels: 24 | kubernetes.io/cluster-service: 'true' 25 | kubernetes.io/name: {{ metricsserver_vars.kubernetes.helm.chart.name }} 26 | {% if metricsserver_postinstall is truthy and metricsserver_map.metrics.service.monitor.enabled is truthy %} 27 | metrics: 28 | enabled: true 29 | serviceMonitor: 30 | enabled: true 31 | {% if metricsserver_map.metrics.service.monitor.scrape.interval is falsy %} 32 | interval: {{ victoriametrics_map.service.monitor.scrape.interval }} 33 | {% else %} 34 | interval: {{ metricsserver_map.metrics.service.monitor.scrape.interval }} 35 | {% endif %} 36 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 37 | {% if metricsserver_map.metrics.service.monitor.scrape.timeout is falsy %} 38 | scrapeTimeout: {{ victoriametrics_map.service.monitor.scrape.timeout }} 39 | {% else %} 40 | scrapeTimeout: {{ metricsserver_map.metrics.service.monitor.scrape.timeout }} 41 | {% endif %} 42 | {% endif %} 43 | tls: 44 | {% if externaldns_vars.cloudflare.host.domain | lower != 'disabled' and metricsserver_vars.kubernetes.server.tls.type | lower == 'cert-manager' %} 45 | certManager: 46 | existingIssuer: 47 | enabled: true 48 | kind: ClusterIssuer 49 | name: {{ certmanager_map.ca.cluster.issuer.name }} 50 | {% endif %} 51 | clusterDomain: {{ k3s_vars.cluster.domain }} 52 | type: {{ metricsserver_vars.kubernetes.server.tls.type }} 53 | updateStrategy: 54 | rollingUpdate: 55 | maxSurge: 1 56 | maxUnavailable: 0 57 | type: RollingUpdate 58 | -------------------------------------------------------------------------------- /roles/victoria-logs/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: victoria-logs-single 3 | description: Documentation generator for victoria-logs Ansible role 4 | home: https://github.com/VictoriaMetrics/helm-charts 5 | version: 0.9.7 6 | -------------------------------------------------------------------------------- /roles/victoria-logs/README.md: -------------------------------------------------------------------------------- 1 | # victoria-logs-single 2 | 3 | ![Version: 0.9.7](https://img.shields.io/badge/Version-0.9.7-informational?style=flat-square) 4 | 5 | The role performs various tasks related to `victoria-logs-single` [chart](https://github.com/VictoriaMetrics/helm-charts/tree/victoria-logs-single-0.9.7/charts/victoria-logs-single) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/victorialogs), for additional details. 6 | 7 | ## Role Variables 8 | 9 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `victorialogs_map` collection. 10 | 11 | > [!TIP] 12 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 13 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 14 | 15 | | Key | Type | Default | Description | 16 | |-----|------|---------|-------------| 17 | | victorialogs_vars.kubernetes.helm.chart.alias | string | `"vls"` | | 18 | | victorialogs_vars.kubernetes.helm.chart.name | string | `"victoria-logs-single"` | | 19 | | victorialogs_vars.kubernetes.helm.chart.version | string | `"v0.9.7"` | | 20 | | victorialogs_vars.kubernetes.helm.repository.name | string | `"helm-charts"` | | 21 | | victorialogs_vars.kubernetes.helm.repository.org | string | `"VictoriaMetrics"` | | 22 | | victorialogs_vars.kubernetes.helm.repository.url | string | `"https://victoriametrics.github.io"` | | 23 | | victorialogs_vars.kubernetes.namespace | string | `"kube-system"` | | 24 | | victorialogs_vars.kubernetes.server.ingress.enabled | bool | `true` | | 25 | | victorialogs_vars.kubernetes.server.ingress.subdomain | string | `"logs"` | See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/externaldns/#front-ends), for details | 26 | | victorialogs_vars.kubernetes.server.log_level | string | `"WARN"` | | 27 | | victorialogs_vars.kubernetes.server.replicas | int | `1` | | 28 | | victorialogs_vars.kubernetes.server.resources.limits.cpu | string | `nil` | | 29 | | victorialogs_vars.kubernetes.server.resources.limits.memory | string | `"256Mi"` | | 30 | | victorialogs_vars.kubernetes.server.resources.requests.cpu | string | `"10m"` | | 31 | | victorialogs_vars.kubernetes.server.resources.requests.memory | string | `"256Mi"` | | 32 | | victorialogs_vars.kubernetes.server.retention_period | string | `"7d"` | | 33 | | victorialogs_vars.kubernetes.server.storage.access_modes[0] | string | `"ReadWriteOnce"` | | 34 | | victorialogs_vars.kubernetes.server.storage.class | string | `"longhorn"` | | 35 | | victorialogs_vars.kubernetes.server.storage.enabled | bool | `true` | | 36 | | victorialogs_vars.kubernetes.server.storage.size | string | `"5Gi"` | | 37 | | victorialogs_vars.kubernetes.vector.autoscaling.enabled | bool | `true` | If `false`, `replicas` value is set from `min_replicas` value | 38 | | victorialogs_vars.kubernetes.vector.autoscaling.max_replicas | int | `3` | | 39 | | victorialogs_vars.kubernetes.vector.autoscaling.min_replicas | int | `1` | | 40 | | victorialogs_vars.kubernetes.vector.autoscaling.target.utilization_percentage.cpu | string | `nil` | | 41 | | victorialogs_vars.kubernetes.vector.autoscaling.target.utilization_percentage.memory | int | `80` | | 42 | | victorialogs_vars.kubernetes.vector.enabled | bool | `true` | | 43 | | victorialogs_vars.kubernetes.vector.log_level | string | `"warn"` | | 44 | | victorialogs_vars.kubernetes.vector.resources.limits.cpu | string | `nil` | | 45 | | victorialogs_vars.kubernetes.vector.resources.limits.memory | string | `"128Mi"` | | 46 | | victorialogs_vars.kubernetes.vector.resources.requests.cpu | string | `"10m"` | | 47 | | victorialogs_vars.kubernetes.vector.resources.requests.memory | string | `"128Mi"` | | 48 | -------------------------------------------------------------------------------- /roles/victoria-logs/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name | replace "-" "" | replace "single" "" -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/victorialogs), for additional details. 12 | 13 | ## Role Variables 14 | 15 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 16 | 17 | > [!TIP] 18 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 19 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 20 | 21 | {{ template "chart.valuesTable" . }} 22 | -------------------------------------------------------------------------------- /roles/victoria-logs/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | victorialogs_vars: 3 | kubernetes: 4 | helm: 5 | chart: 6 | alias: vls 7 | name: victoria-logs-single 8 | version: v0.9.7 9 | repository: 10 | name: helm-charts 11 | org: VictoriaMetrics 12 | url: https://victoriametrics.github.io 13 | namespace: kube-system 14 | server: 15 | ingress: 16 | enabled: true 17 | # -- See [documentation](https://axivo.com/k3s-cluster/tutorials/handbook/externaldns/#front-ends), for details 18 | subdomain: logs 19 | log_level: WARN 20 | resources: 21 | limits: 22 | cpu: null 23 | memory: 256Mi 24 | requests: 25 | cpu: 10m 26 | memory: 256Mi 27 | storage: 28 | enabled: true 29 | access_modes: 30 | - ReadWriteOnce 31 | class: longhorn 32 | size: 5Gi 33 | replicas: 1 34 | retention_period: 7d 35 | vector: 36 | enabled: true 37 | autoscaling: 38 | # -- If `false`, `replicas` value is set from `min_replicas` value 39 | enabled: true 40 | min_replicas: 1 41 | max_replicas: 3 42 | target: 43 | utilization_percentage: 44 | cpu: null 45 | memory: 80 46 | log_level: warn 47 | resources: 48 | limits: 49 | cpu: null 50 | memory: 128Mi 51 | requests: 52 | cpu: 10m 53 | memory: 128Mi 54 | -------------------------------------------------------------------------------- /roles/victoria-logs/tasks/facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set map fact 3 | ansible.builtin.set_fact: 4 | victorialogs_map: 5 | helm: 6 | chart: 7 | reference: '{{ victorialogs_vars.kubernetes.helm.repository.org }}/{{ victorialogs_vars.kubernetes.helm.chart.name }}' 8 | version: '{{ victorialogs_vars.kubernetes.helm.chart.version[1:] }}' 9 | platform: 10 | key: https://github.com 11 | raw: https://raw.githubusercontent.com 12 | repository: 13 | name: '{{ victorialogs_vars.kubernetes.helm.repository.org }}/{{ victorialogs_vars.kubernetes.helm.repository.name }}' 14 | url: '{{ victorialogs_vars.kubernetes.helm.repository.url }}/{{ victorialogs_vars.kubernetes.helm.repository.name }}' 15 | timeout: 5m0s 16 | ingress: 17 | class: 18 | name: cilium 19 | server: 20 | annotations: 21 | cert-manager.io/cluster-issuer: '{{ externaldns_project.cloudflare.cluster.issuer }}' 22 | hostname: '{{ victorialogs_vars.kubernetes.server.ingress.subdomain }}.{{ externaldns_vars.cloudflare.host.domain }}' 23 | name: '{{ victorialogs_vars.kubernetes.helm.chart.alias }}-{{ victorialogs_vars.kubernetes.helm.chart.name }}-server' 24 | metrics: 25 | service: 26 | monitor: 27 | enabled: true 28 | scrape: 29 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.interval` 30 | interval: null 31 | # If `null`, default value is `victoriametrics_map.service.monitor.scrape.timeout` 32 | timeout: null 33 | run_once: true 34 | 35 | - name: Set project fact 36 | ansible.builtin.set_fact: 37 | victorialogs_project: 38 | tag: '{{ victorialogs_vars.kubernetes.helm.chart.name }}-{{ victorialogs_map.helm.chart.version }}' 39 | url: '{{ victorialogs_map.helm.platform.key }}/{{ victorialogs_map.helm.repository.name }}/releases/tag' 40 | run_once: true 41 | -------------------------------------------------------------------------------- /roles/victoria-logs/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Add repository 17 | kubernetes.core.helm_repository: 18 | name: '{{ victorialogs_vars.kubernetes.helm.repository.org }}' 19 | repo_url: '{{ victorialogs_map.helm.repository.url }}' 20 | force_update: true 21 | 22 | - name: Chart Setup 23 | run_once: true 24 | block: 25 | - name: Set chart postinstall fact 26 | ansible.builtin.set_fact: 27 | victorialogs_postinstall: false 28 | 29 | - name: Install chart 30 | kubernetes.core.helm: 31 | chart_ref: '{{ victorialogs_map.helm.chart.reference }}' 32 | chart_version: '{{ victorialogs_vars.kubernetes.helm.chart.version }}' 33 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 34 | name: '{{ victorialogs_vars.kubernetes.helm.chart.alias }}' 35 | namespace: '{{ victorialogs_vars.kubernetes.namespace }}' 36 | timeout: '{{ victorialogs_map.helm.timeout }}' 37 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 38 | create_namespace: true 39 | update_repo_cache: true 40 | wait: true 41 | register: result 42 | delay: 1 43 | retries: 3 44 | until: result is not failed 45 | -------------------------------------------------------------------------------- /roles/victoria-logs/tasks/postinstall.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Post-Install 3 | when: 4 | - inventory_hostname in k3s_map.server.hosts 5 | - victorialogs_map.metrics.service.monitor.enabled is truthy 6 | run_once: true 7 | block: 8 | - name: Update chart postinstall fact 9 | ansible.builtin.set_fact: 10 | victorialogs_postinstall: true 11 | 12 | - name: Update chart postinstall values 13 | kubernetes.core.helm: 14 | chart_ref: '{{ victorialogs_map.helm.chart.reference }}' 15 | chart_version: '{{ victorialogs_vars.kubernetes.helm.chart.version }}' 16 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 17 | name: '{{ victorialogs_vars.kubernetes.helm.chart.alias }}' 18 | namespace: '{{ victorialogs_vars.kubernetes.namespace }}' 19 | timeout: '{{ victorialogs_map.helm.timeout }}' 20 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 21 | reset_values: false 22 | reuse_values: true 23 | wait: true 24 | register: result 25 | delay: 1 26 | retries: 3 27 | until: result is not failed 28 | -------------------------------------------------------------------------------- /roles/victoria-logs/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ victorialogs_vars.kubernetes.helm.repository.org }}' 13 | repo_state: absent 14 | when: "'helm' in ansible_facts.packages" 15 | -------------------------------------------------------------------------------- /roles/victoria-logs/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.include_tasks: 4 | file: '{{ file }}.yaml' 5 | loop: 6 | - main 7 | - postinstall 8 | loop_control: 9 | loop_var: file 10 | -------------------------------------------------------------------------------- /roles/victoria-metrics/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: victoria-metrics-k8s-stack 3 | description: Documentation generator for victoria-metrics Ansible role 4 | home: https://github.com/VictoriaMetrics/helm-charts 5 | version: 0.44.0 6 | dependencies: 7 | - name: prometheus-operator-crds 8 | repository: https://prometheus-community.github.io/helm-charts 9 | version: 19.1.0 10 | -------------------------------------------------------------------------------- /roles/victoria-metrics/README.md.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "chart.url" -}} 2 | {{- printf "%s/tree/%s-%s/charts/%s" .Home .Name .Version .Name -}} 3 | {{- end -}} 4 | {{- define "role.map" -}} 5 | {{- printf "%s_map" .Name | replace "-" "" -}} 6 | {{- end -}} 7 | # {{ template "chart.name" . }} 8 | 9 | {{ template "chart.versionBadge" . }} 10 | 11 | The role performs various tasks related to `{{ template "chart.name" . }}` [chart]({{ template "chart.url" . }}) deployment, reset and validation. Review the [documentation](https://axivo.com/k3s-cluster/wiki/guide/configuration/roles/victoriametrics), for additional details. 12 | 13 | ## Role Dependencies 14 | 15 | See the installed role dependencies listed below, defined into [main.yaml](./defaults/main.yaml) `kubernetes.helm.chart` collection. 16 | 17 | {{ template "chart.requirementsTable" . }} 18 | 19 | ## Role Variables 20 | 21 | See the related role variables listed below, defined into [main.yaml](./defaults/main.yaml) defaults file. Advanced user role variables are defined into [facts.yaml](./tasks/facts.yaml) `{{ template "role.map" . }}` collection. 22 | 23 | > [!TIP] 24 | > - Use [Renovate](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#renovate), to automate the release pull requests and keep dependencies up-to-date 25 | > - Use [Robusta KRR](https://axivo.com/k3s-cluster/tutorials/handbook/tools/#robusta-krr), to optimize the cluster resources allocation 26 | 27 | {{ template "chart.valuesTable" . }} 28 | -------------------------------------------------------------------------------- /roles/victoria-metrics/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Validation 3 | ansible.builtin.import_tasks: 4 | file: validation.yaml 5 | any_errors_fatal: true 6 | 7 | - name: Role Provisioning 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Validate service state 11 | ansible.builtin.wait_for: 12 | port: '{{ k3s_vars.server.api.port }}' 13 | timeout: 30 14 | any_errors_fatal: true 15 | 16 | - name: Add repository 17 | kubernetes.core.helm_repository: 18 | name: '{{ item.org }}' 19 | repo_url: '{{ item.url }}/{{ item.name }}' 20 | force_update: true 21 | loop: '{{ victoriametrics_map.helm.repository }}' 22 | 23 | - name: Chart Setup 24 | run_once: true 25 | block: 26 | - name: Create grafana user credentials secret 27 | kubernetes.core.k8s: 28 | definition: "{{ lookup('ansible.builtin.template', 'credentials.j2') | from_yaml }}" 29 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 30 | wait: true 31 | no_log: true 32 | 33 | - name: Install dependency chart 34 | kubernetes.core.helm: 35 | chart_ref: '{{ victoriametrics_project.helm.chart.prometheus.reference }}' 36 | chart_version: '{{ victoriametrics_vars.kubernetes.helm.chart.prometheus.version }}' 37 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 38 | name: '{{ victoriametrics_vars.kubernetes.helm.chart.prometheus.name }}' 39 | namespace: '{{ victoriametrics_vars.kubernetes.namespace }}' 40 | timeout: '{{ victoriametrics_map.helm.timeout }}' 41 | create_namespace: true 42 | update_repo_cache: true 43 | wait: true 44 | register: result 45 | delay: 1 46 | retries: 3 47 | until: result is not failed 48 | 49 | - name: Install chart 50 | kubernetes.core.helm: 51 | chart_ref: '{{ victoriametrics_project.helm.chart.victoriametrics.reference }}' 52 | chart_version: '{{ victoriametrics_vars.kubernetes.helm.chart.victoriametrics.version }}' 53 | kubeconfig: '{{ k3s_project.cluster.kubeconfig }}' 54 | name: '{{ victoriametrics_vars.kubernetes.helm.chart.victoriametrics.alias }}' 55 | namespace: '{{ victoriametrics_vars.kubernetes.namespace }}' 56 | timeout: '{{ victoriametrics_map.helm.timeout }}' 57 | values: "{{ lookup('ansible.builtin.template', 'values.j2') | from_yaml }}" 58 | update_repo_cache: true 59 | wait: true 60 | register: result 61 | delay: 1 62 | retries: 3 63 | until: result is not failed 64 | -------------------------------------------------------------------------------- /roles/victoria-metrics/tasks/reset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Facts 3 | ansible.builtin.import_role: 4 | name: k3s 5 | tasks_from: facts 6 | 7 | - name: Role Reset 8 | when: inventory_hostname in k3s_map.server.hosts 9 | block: 10 | - name: Remove repository 11 | kubernetes.core.helm_repository: 12 | name: '{{ item }}' 13 | repo_state: absent 14 | loop: 15 | - '{{ victoriametrics_vars.kubernetes.helm.repository.grafana.org }}' 16 | - '{{ victoriametrics_vars.kubernetes.helm.repository.prometheus.org }}' 17 | - '{{ victoriametrics_vars.kubernetes.helm.repository.victoriametrics.org }}' 18 | when: "'helm' in ansible_facts.packages" 19 | -------------------------------------------------------------------------------- /roles/victoria-metrics/tasks/upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role Upgrade 3 | ansible.builtin.import_tasks: 4 | file: main.yaml 5 | -------------------------------------------------------------------------------- /roles/victoria-metrics/templates/config_alertmanager.j2: -------------------------------------------------------------------------------- 1 | inhibit_rules: 2 | - target_matchers: 3 | - severity=~"info|warning" 4 | source_matchers: 5 | - severity="critical" 6 | equal: 7 | - alertname 8 | - cluster 9 | - namespace 10 | - target_matchers: 11 | - severity="info" 12 | source_matchers: 13 | - severity="warning" 14 | equal: 15 | - alertname 16 | - cluster 17 | - namespace 18 | - target_matchers: 19 | - severity="info" 20 | source_matchers: 21 | - alertname="InfoInhibitor" 22 | equal: 23 | - cluster 24 | - namespace 25 | route: 26 | group_by: 27 | - alertgroup 28 | - job 29 | group_interval: {{ victoriametrics_vars.kubernetes.alertmanager.config.route.group_interval }} 30 | group_wait: {{ victoriametrics_vars.kubernetes.alertmanager.config.route.group_wait }} 31 | repeat_interval: {{ victoriametrics_vars.kubernetes.alertmanager.config.route.repeat_interval }} 32 | -------------------------------------------------------------------------------- /roles/victoria-metrics/templates/credentials.j2: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ victoriametrics_map.credentials.grafana.secret }} 5 | namespace: {{ victoriametrics_vars.kubernetes.namespace }} 6 | stringData: 7 | admin-password: {{ global_map.credentials.victoriametrics.grafana.user.password }} 8 | admin-user: {{ global_map.credentials.victoriametrics.grafana.user.name }} 9 | smtp-password: {{ global_map.credentials.cluster.postfix.user.password }} 10 | smtp-user: {{ global_map.credentials.cluster.postfix.user.name }} 11 | type: Opaque 12 | -------------------------------------------------------------------------------- /upgrade.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Tags Validation 3 | hosts: localhost 4 | become: false 5 | gather_facts: false 6 | tasks: 7 | - name: Validate tags 8 | ansible.builtin.fail: 9 | msg: | 10 | Improper usage of '--tags' flag: 11 | {% set invalid_tags = ansible_run_tags | difference(global_map.tags.role) %} 12 | {% if invalid_tags | length > 0 %} 13 | - invalid tag{% if invalid_tags | length > 1 %}s{% endif %}: {{ invalid_tags | join(', ') }} 14 | {% endif %} 15 | - valid tags: {{ global_map.tags.role | join(', ') }} 16 | tags: always 17 | when: 18 | - ansible_run_tags not in [[], ['all']] 19 | - ansible_run_tags | difference(global_map.tags.role) | length > 0 20 | 21 | - name: Cluster Upgrade 22 | hosts: cluster 23 | become: true 24 | gather_facts: true 25 | tasks: 26 | - name: Role Upgrade 27 | ansible.builtin.include_role: 28 | apply: 29 | tags: '{{ upgrade }}' 30 | name: '{{ upgrade }}' 31 | tasks_from: upgrade 32 | loop: '{{ global_map.tags.role }}' 33 | loop_control: 34 | loop_var: upgrade 35 | tags: always 36 | when: (upgrade in ansible_run_tags) 37 | -------------------------------------------------------------------------------- /validation.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Tags Validation 3 | hosts: localhost 4 | become: false 5 | gather_facts: false 6 | tasks: 7 | - name: Validate tags 8 | ansible.builtin.fail: 9 | msg: | 10 | Improper usage of '--tags' flag: 11 | {% set invalid_tags = ansible_run_tags | difference(global_map.tags.role | union(['validation'])) %} 12 | {% if invalid_tags | length > 0 %} 13 | - invalid tag{% if invalid_tags | length > 1 %}s{% endif %}: {{ invalid_tags | join(', ') }} 14 | {% endif %} 15 | {% if 'validation' not in ansible_run_tags %} 16 | - required tag: validation 17 | {% endif %} 18 | - valid tags: {{ global_map.tags.role | join(', ') }} 19 | tags: always 20 | when: 21 | - ansible_run_tags not in [[], ['all']] 22 | - >- 23 | ('validation' not in ansible_run_tags) or 24 | (ansible_run_tags | difference(global_map.tags.role | union(['validation'])) | length > 0) 25 | 26 | - name: Cluster Validation 27 | hosts: cluster 28 | become: true 29 | gather_facts: true 30 | tasks: 31 | - name: Validate global settings 32 | ansible.builtin.include_role: 33 | apply: 34 | tags: '{{ validation }}' 35 | name: '{{ validation }}' 36 | tasks_from: validation 37 | loop: '{{ global_map.tags.role }}' 38 | loop_control: 39 | loop_var: validation 40 | tags: always 41 | when: (ansible_run_tags == ['all']) or (validation in ansible_run_tags) 42 | --------------------------------------------------------------------------------