diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..9b9b52a --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,23 @@ +--- + +exclude_paths: + - ".gitlab/*" + - ".gitlab-ci.yml" + - "defaults/main.yaml" + - "meta/main.yaml" + - "vars/*" + +kinds: + - playbook: "**/*.{yml,yaml}" + +skip_list: + - "command-shell" + - "experimental" + - "git-latest" + - "no-changed-when" + - "no-handler" + - "name[casing]" + - "name[template]" + - "risky-file-permissions" + - "schema[playbook]" + - "var-naming[no-role-prefix]" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..904cae8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.ansible diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..54a4cb4 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,22 @@ +--- + +# gitLab ci stages +stages: + + # deployment + - "gitleaks" + - "linting" + - "deployment" + + +# include jobs +include: + + # deployment + - local: ".gitlab/gitleaks.yaml" + - local: ".gitlab/deployment.yaml" + + # linting + - component: "$CI_SERVER_FQDN/components/ansible/linting@v3.0.3" + - component: "$CI_SERVER_FQDN/components/markdownlint/markdownlint@1.0.0" + - component: "$CI_SERVER_FQDN/components/yamllint/yamllint@1.0.2" diff --git a/.gitlab/gitleaks.yaml b/.gitlab/gitleaks.yaml new file mode 100644 index 0000000..b369d97 --- /dev/null +++ b/.gitlab/gitleaks.yaml @@ -0,0 +1,18 @@ +--- + +# gitleaks +gitleaks: + stage: "gitleaks" + image: + name: "ghcr.io/gitleaks/gitleaks:latest" + variables: + GIT_DEPTH: 1 + rules: + + # run only on push to default branch + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + - when: "never" + + # start linting + script: + - "gitleaks detect --source . --verbose --redact" diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..56cd87c --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,12 @@ +{ + // files to lint + "globs": [ + "readme.md" + ], + // linting rules + "config": { + "MD013": { + "line_length": 120 + } + } +} diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..f11bd84 --- /dev/null +++ b/.yamllint @@ -0,0 +1,30 @@ +--- +extends: 'default' + +rules: + braces: + max-spaces-inside: 1 + forbid: true + comments: + min-spaces-from-content: 1 + comments-indentation: false + empty-lines: + max: 2 + indentation: + spaces: 2 + check-multi-line-strings: true + line-length: + max: 120 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + new-line-at-end-of-file: 'enable' + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + truthy: + allowed-values: + - 'true' + - 'false' + quoted-strings: + quote-type: 'any' + required: true diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..cc7e9df --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,4 @@ +--- + +# grafana +grafana_admin_password: "development" diff --git a/handlers/main.yaml b/handlers/main.yaml new file mode 100644 index 0000000..742635d --- /dev/null +++ b/handlers/main.yaml @@ -0,0 +1,13 @@ +--- + +# restart grafana +- name: "restart grafana" + community.docker.docker_container: + name: "grafana" + restart: true + +# restart prometheus +- name: "restart prometheus" + community.docker.docker_container: + name: "prometheus" + restart: true diff --git a/meta/main.yaml b/meta/main.yaml new file mode 100644 index 0000000..f3205ea --- /dev/null +++ b/meta/main.yaml @@ -0,0 +1,10 @@ +--- + +galaxy_info: + author: "siempie" + description: "install grafana and prometheus" + license: "MIT" + role_name: "grafana" +dependencies: + - role: "docker" + - role: "traefik" diff --git a/playbook.yaml b/playbook.yaml new file mode 100644 index 0000000..19f5e04 --- /dev/null +++ b/playbook.yaml @@ -0,0 +1,21 @@ +--- + +# execute this role +- name: "install Jellyfin" + hosts: "all" + become: true + pre_tasks: + + # due to semaphore bug we need to do this ourselves + - name: "force-update requirements" + ansible.builtin.command: + cmd: "ansible-galaxy install -f -r roles/requirements.yml" + become: false + delegate_to: "localhost" + changed_when: false + failed_when: false + + roles: + - role: "docker" + - role: "jellyfin" + - role: "traefik" diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..29f1df6 --- /dev/null +++ b/readme.md @@ -0,0 +1,13 @@ +# Overview + +This role configures [Jellyfin]() server, for reasons. + +## Supported Operating Systems + +| Operating System | Version | +| --- | ----- | +| Debian | 13 | + +## Tags + +This role has no tags. diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..91260cb --- /dev/null +++ b/renovate.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ "local>cicd/renovate:ansible" ] +} diff --git a/roles/requirements.yml b/roles/requirements.yml new file mode 100644 index 0000000..58c0315 --- /dev/null +++ b/roles/requirements.yml @@ -0,0 +1,12 @@ +--- + +roles: + - name: "docker" + src: "https://gitlab.simoncor.net/ansible/ans-docker.git" + scm: "git" + - name: "grafana" + src: "https://gitlab.simoncor.net/ansible/ans-grafana.git" + scm: "git" + - name: "traefik" + src: "https://gitlab.simoncor.net/ansible/ans-traefik.git" + scm: "git" diff --git a/tasks/cleanup.yaml b/tasks/cleanup.yaml new file mode 100644 index 0000000..d2d89f5 --- /dev/null +++ b/tasks/cleanup.yaml @@ -0,0 +1,14 @@ +--- + +# cleanup +- name: "docker - prune all" + community.docker.docker_prune: + containers: true + images: true + networks: true + volumes: true + builder_cache: true + +- name: "docker - force prune" + ansible.builtin.command: "docker system prune --all --force --volumes" + changed_when: false diff --git a/tasks/grafana.yaml b/tasks/grafana.yaml new file mode 100644 index 0000000..9d2f540 --- /dev/null +++ b/tasks/grafana.yaml @@ -0,0 +1,48 @@ +--- + +# create directories +- name: "create grafana data directory" + ansible.builtin.file: + path: "/mnt/grafana" + state: "directory" + mode: "0775" + +# run grafana +- name: "run grafana" + community.docker.docker_container: + + # docker defaults + auto_remove: "no" + container_default_behavior: "no_defaults" + detach: "yes" + init: "no" + interactive: "no" + log_driver: "json-file" + log_options: + max-size: "5m" + max-file: "3" + memory: "0" + paused: "no" + privileged: "no" + pull: "always" + read_only: "no" + state: "started" + tty: "no" + + # run grafana + name: "grafana" + image: "docker.io/grafana/grafana-oss:12.2.1" + image_name_mismatch: "recreate" + restart_policy: "unless-stopped" + network_mode: "host" + + volumes: + - "/mnt/grafana:/var/lib/grafana" + + env: + + # grafana + GF_SECURITY_ADMIN_PASSWORD: "{{ grafana_admin_password }}" + + # global + TZ: "{{ timezone }}" diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..42a5954 --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,13 @@ +--- + +# install prometheus +- name: "install prometheus" + ansible.builtin.import_tasks: "prometheus.yaml" + +# install grafana +- name: "install grafana" + ansible.builtin.import_tasks: "grafana.yaml" + +# cleanup docker +- name: "cleanup docker" + ansible.builtin.import_tasks: "cleanup.yaml" diff --git a/tasks/prometheus.yaml b/tasks/prometheus.yaml new file mode 100644 index 0000000..3f4f780 --- /dev/null +++ b/tasks/prometheus.yaml @@ -0,0 +1,66 @@ +--- + +# create directories +- name: "create prometheus directory" + ansible.builtin.file: + path: "/mnt/prometheus" + state: "directory" + mode: "0775" + +- name: "create prometheus data directory" + ansible.builtin.file: + path: "/mnt/prometheus/data" + state: "directory" + mode: "0775" + +# create prometheus config +- name: "create prometheus config" + ansible.builtin.copy: + dest: "/mnt/prometheus/prometheus.yml" + mode: "0644" + content: | + global: + scrape_interval: 15s + scrape_configs: + - job_name: 'unbound' + static_configs: + - targets: ['dns01.siempie.internal:9167'] + - targets: ['dns02.siempie.internal:9167'] + notify: "restart prometheus" + +# run prometheus +- name: "run prometheus" + community.docker.docker_container: + + # docker defaults + auto_remove: "no" + container_default_behavior: "no_defaults" + detach: "yes" + init: "no" + interactive: "no" + log_driver: "json-file" + log_options: + max-size: "5m" + max-file: "3" + memory: "0" + paused: "no" + privileged: "no" + pull: "always" + read_only: "no" + state: "started" + tty: "no" + + # run prometheus + name: "prometheus" + image: "docker.io/prom/prometheus:3.7.2" + image_name_mismatch: "recreate" + restart_policy: "unless-stopped" + network_mode: "host" + + volumes: + - "/mnt/prometheus/data:/prometheus" + - "/mnt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro" + + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus"