diff options
77 files changed, 747 insertions, 1365 deletions
diff --git a/ansible.cfg b/ansible.cfg index 65e74eb..6975f69 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -12,8 +12,9 @@ default_fact_path = /etc/ansible/facts.d/:facts.d/ stdout_callback = yaml stderr_callback = yaml -timeout = 4 -command_warnings=False +timeout = 20 +system_warnings = True +deprecation_warnings = True [ssh_connection] pipelining = True diff --git a/group_vars/all.yml b/group_vars/all.yml index e5b47b0..729f89a 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -9,6 +9,9 @@ ansible_become_method: "su" path_prometheusconfig: "/etc/prometheus/prometheus.yml" +#nfsclient_server: "stack0" +#nfsclient_server_dir: "/data/nfs" + global: dcontroller: "dc0" diff --git a/host_vars/st0cld0.yml b/host_vars/st0cld0.yml index bb85530..b2812e7 100644 --- a/host_vars/st0cld0.yml +++ b/host_vars/st0cld0.yml @@ -1,27 +1,23 @@ _groups: openbsd ip: - in: 10.10.0.61 - out: 192.168.5.61 + in: 10.10.0.62 + out: 192.168.5.62 virtual: true services: - - name: "ssh" - proto: "tcp" - port: "22" + - name: ssh + proto: tcp + port: 22 - - name: "grafana" - proto: "tcp" - port: "3000" + - name: nextcloud + proto: tcp + port: 8080 + domain: cloud - - name: "nextcloud" - proto: "tcp" - port: "8080" - domain: "cloud" - - - name: "miniflux" - proto: "tcp" - port: "8010" - domain: "miniflux" + - name: miniflux + proto: tcp + port: 8010 + domain: miniflux diff --git a/host_vars/st0dc1.yml b/host_vars/st0dc1.yml new file mode 100644 index 0000000..ad9ad6b --- /dev/null +++ b/host_vars/st0dc1.yml @@ -0,0 +1,20 @@ +_groups: openbsd + +virtual: true + +ip: + in: 10.10.0.60 + out: 192.168.5.60 + +services: + - name: ssh + proto: tcp + port: 22 + + - name: grafana + proto: tcp + port: 3000 + domain: status + +cgit_config_root_desc: private - development hub +cgit_authenticate: true diff --git a/host_vars/st0dev0.yml b/host_vars/st0dev0.yml index b15794b..86731bf 100644 --- a/host_vars/st0dev0.yml +++ b/host_vars/st0dev0.yml @@ -1,17 +1,17 @@ _groups: openbsd + ip: - in: 10.10.0.60 - out: 192.168.5.60 + in: 10.10.0.61 + out: 192.168.5.61 virtual: true services: + - name: ssh + proto: tcp + port: 22 - - name: "ssh" - proto: "tcp" - port: "22" - - - name: "cgit" - proto: "tcp" - port: "1235" - domain: "git" + - name: git + proto: tcp + port: 1235 + domain: git diff --git a/host_vars/st0dev1.yml b/host_vars/st0dev1.yml deleted file mode 100644 index fd92220..0000000 --- a/host_vars/st0dev1.yml +++ /dev/null @@ -1,13 +0,0 @@ -_groups: openbsd -ip: - in: 10.10.0.63 - out: 192.168.5.63 - -virtual: true - -services: - - - name: "ssh" - proto: "tcp" - port: "22" - diff --git a/host_vars/st0gme0.yml b/host_vars/st0gme0.yml index f193f2a..4f25d74 100644 --- a/host_vars/st0gme0.yml +++ b/host_vars/st0gme0.yml @@ -1,12 +1,12 @@ _groups: alpine + ip: - in: 10.10.0.62 - out: 192.168.5.62 + in: 10.10.0.63 + out: 192.168.5.63 virtual: true services: - - name: "ssh" proto: "tcp" port: "22" diff --git a/host_vars/stack0.yml b/host_vars/stack0.yml index 5a6e27d..1fe5d47 100644 --- a/host_vars/stack0.yml +++ b/host_vars/stack0.yml @@ -7,31 +7,29 @@ ip: virtual: false services: - - name: "ssh" proto: "tcp" port: "22" vms: - - - name: st0dev0 + - name: st0dc1 image: openbsd memory: 4G - cpu: 4 + cpu: 2 disks: - { id: 0, size: "8G" } - - name: st0dev1 + - name: st0dev0 image: openbsd - memory: 4G + memory: 2G cpu: 2 disks: - { id: 0, size: "8G" } - name: st0cld0 image: openbsd - memory: 8G - cpu: 4 + memory: 4G + cpu: 2 disks: - { id: 0, size: "8G" } diff --git a/playbooks/dc0.rgoncalves.se.yml b/playbooks/dc0.rgoncalves.se.yml index 53ba6aa..d54df56 100644 --- a/playbooks/dc0.rgoncalves.se.yml +++ b/playbooks/dc0.rgoncalves.se.yml @@ -6,10 +6,15 @@ - hosts: dc0 roles: - - - { role: znc, tags: "role_znc" } - - { role: website, tags: "role_website" } - - { role: httpd, tags: "role_httpd" } - - { role: acme, tags: "role_acme" } - - { role: relayd, tags: "role_relayd" } - - { role: pf, tags: "role_pf" } + - role: znc + tags: role_znc + - role: website + tags: role_website + - role: httpd + tags: role_httpd + - role: acme + tags: role_acme + - role: relayd + tags: role_relayd + - role: pf + tags: role_pf diff --git a/playbooks/extra/prerequisites.yml b/playbooks/extra/prerequisites.yml index a80d85e..eddb418 100644 --- a/playbooks/extra/prerequisites.yml +++ b/playbooks/extra/prerequisites.yml @@ -10,10 +10,10 @@ tasks: - name: bruteforce python installation with all packages possiblity - raw: "{{ item }}" + raw: | + pkg_add python3 + pkg install python3 + apk add python ignore_errors: true - loop: - - pkg_add python3 - - pkg install python3 - - apk add python + failed_when: false poll: 0 diff --git a/playbooks/network/grafana.yml b/playbooks/network/grafana.yml index 30bc0f4..4c039bd 100644 --- a/playbooks/network/grafana.yml +++ b/playbooks/network/grafana.yml @@ -6,8 +6,12 @@ - hosts: servers roles: - - { role: prometheus } + - role: loki + tags: role_loki + - role: prometheus + tags: role_prometheus -- hosts: st0cld0 +- hosts: st0dc1 roles: - - { role: grafana } + - role: grafana + tags: role_grafana diff --git a/playbooks/network/nfs.yml b/playbooks/network/nfs.yml index 1b8717e..9d1f73b 100644 --- a/playbooks/network/nfs.yml +++ b/playbooks/network/nfs.yml @@ -1,17 +1,3 @@ - -# network/nfs ~~ playbooks/nfs/network.yml -# nfs network playbook - ---- - -- name: ensure installation and configuration on server side - hosts: stack0 - roles: - - role: nfsd - vars: - nfsd_dirs: "{% for vm in vms %}{{ vm.name }} {% endfor %}" - tags: play_network_nfsserver - - name: ensure installation and configuration on client side hosts: ~st[0-9].* roles: diff --git a/playbooks/network/templates b/playbooks/network/templates new file mode 120000 index 0000000..07531b7 --- /dev/null +++ b/playbooks/network/templates @@ -0,0 +1 @@ +../../templates
\ No newline at end of file diff --git a/playbooks/st0cld0.rgoncalves.se.yml b/playbooks/st0cld0.rgoncalves.se.yml index 2286395..2870e3a 100644 --- a/playbooks/st0cld0.rgoncalves.se.yml +++ b/playbooks/st0cld0.rgoncalves.se.yml @@ -6,7 +6,9 @@ - hosts: st0cld0 roles: - - { role: nextcloud, tags: "role_nextcloud" } - - { role: miniflux, tags: "role_miniflux" } - - { role: syncthing, tags: "role_syncthing" } - - { role: httpd, tags: "role_httpd" } + - role: miniflux + tags: role_miniflux + - role: syncthing + tags: role_syncthing + - role: httpd + tags: role_httpd diff --git a/playbooks/st0dc1.rgoncalves.se.yml b/playbooks/st0dc1.rgoncalves.se.yml new file mode 100644 index 0000000..e99768f --- /dev/null +++ b/playbooks/st0dc1.rgoncalves.se.yml @@ -0,0 +1,12 @@ +- hosts: st0dc1 + roles: + - role: ldapd + tags: role_ldapd + - role: postgres + tags: role_postgres + - role: grafana + tags: role_grafana + - role: cgit + tags: role_cgit + - role: httpd + tags: role_httpd diff --git a/playbooks/st0dev0.rgoncalves.se.yml b/playbooks/st0dev0.rgoncalves.se.yml index fbee649..5fd98aa 100644 --- a/playbooks/st0dev0.rgoncalves.se.yml +++ b/playbooks/st0dev0.rgoncalves.se.yml @@ -6,8 +6,7 @@ - hosts: st0dev0 roles: - - { role: gitdaemon } - - { role: cgit } - - { role: jenkins } - - { role: httpd } - - { role: sshd } + - role: cgit + tags: role_cgit + - role: httpd + tags_role: httpd diff --git a/playbooks/st0dev1.rgoncalves.se.yml b/playbooks/st0dev1.rgoncalves.se.yml deleted file mode 100644 index 5d568d5..0000000 --- a/playbooks/st0dev1.rgoncalves.se.yml +++ /dev/null @@ -1,14 +0,0 @@ - -# st0dev1 ~~ playbooks/st0dev0.rgoncalves.se.yml -# openbsd based development system -- private operations - ---- - -- hosts: st0dev1 - vars: - cgit_config_root_desc: "private - development hub" - cgit_authenticate: true - - roles: - - { role: cgit } - - { role: httpd } diff --git a/playbooks/stack0.rgoncalves.se.yml b/playbooks/stack0.rgoncalves.se.yml index 2fcf803..e8af5d1 100644 --- a/playbooks/stack0.rgoncalves.se.yml +++ b/playbooks/stack0.rgoncalves.se.yml @@ -6,5 +6,6 @@ - hosts: stack0 roles: - - { role: bhyve } + - role: nfsd + nfsd_dirs: "{{ vms | flatten | map(attribute='name') | flatten }}" diff --git a/playbooks/utils/nfsd-hypervisor.yml b/playbooks/utils/nfsd-hypervisor.yml new file mode 100644 index 0000000..df59645 --- /dev/null +++ b/playbooks/utils/nfsd-hypervisor.yml @@ -0,0 +1,6 @@ +--- + +- roles: + - role: nfsd + vars: + nfsd_dirs: "{% for vm in vms %}{{ vm.name }} {% endfor %}" diff --git a/playbooks/workstation.yml b/playbooks/workstation.yml index 2a3534e..1b1acc3 100644 --- a/playbooks/workstation.yml +++ b/playbooks/workstation.yml @@ -5,11 +5,6 @@ --- - hosts: localhost - pre_tasks: - - fail: - msg: must be run as root! - when: lookup('env', 'USER') != "root" - roles: - role: _workstation/env tags: env, always @@ -22,6 +17,3 @@ - role: _workstation/sysconf tags: sysconf - - - role: update - tags: update diff --git a/roles/_workstation/env/tasks/main.yml b/roles/_workstation/env/tasks/main.yml index 261170e..ff9acd2 100644 --- a/roles/_workstation/env/tasks/main.yml +++ b/roles/_workstation/env/tasks/main.yml @@ -12,6 +12,13 @@ shell: cat /etc/passwd | cut -d ":" -f 1 register: result +- name: retrieve current user + shell: whoami + register: result_ + +- set_fact: + _ws_user: "{{ result_.stdout_lines[0] }}" + - name: check if target user exists fail: msg: _ws_user is not a valid user diff --git a/roles/_workstation/sshdns/tasks/main.yml b/roles/_workstation/sshdns/tasks/main.yml deleted file mode 100644 index daf8f61..0000000 --- a/roles/_workstation/sshdns/tasks/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- - -- name: create config directory - file: - path: '/home/{{ _ws_user }}/.ssh/config.d' - state: directory - group: '{{ _ws_user }}' - owner: '{{ _ws_user }}' - mode: '0700' - -- name: generate template to localhost - template: - src: templates/sshdns.j2 - dest: '/home/{{ _ws_user }}//.ssh/config.d/ssh_dns' - owner: '{{ _ws_user }}' - group: '{{ _ws_user }}' - mode: '0600' diff --git a/roles/acme/vars/main.yml b/roles/acme/defaults/main.yml index a67c5c6..a67c5c6 100644 --- a/roles/acme/vars/main.yml +++ b/roles/acme/defaults/main.yml diff --git a/roles/acme/tasks/main.yml b/roles/acme/tasks/main.yml index 9d413b0..e7eb9bf 100644 --- a/roles/acme/tasks/main.yml +++ b/roles/acme/tasks/main.yml @@ -1,15 +1,3 @@ - -# acme ~~ roles/acme/tasks/main.yml -# acme-client initialization -# OPENBSD-ONLY - ---- - -- name: ensure acme-client is installed - package: - name: acme-client - state: present - - name: generate acme-client configuration template: src: acme-client.conf.j2 @@ -26,7 +14,7 @@ shell: acme-client -v {{ item }} loop: "{{ subdomains.stdout_lines }}" register: result - failed_when: result.rc not in [ 0, 2 ] + failed_when: result.rc not in [0, 2] - name: show acme-client output debug: diff --git a/roles/bhyve/templates/openbsd.conf.j2 b/roles/bhyve/templates/openbsd.conf.j2 index c791c6c..de67cdb 100644 --- a/roles/bhyve/templates/openbsd.conf.j2 +++ b/roles/bhyve/templates/openbsd.conf.j2 @@ -8,7 +8,7 @@ network0_switch="{{ guest_switch }}" disk0_type="virtio-blk" disk0_name="disk0.img" -grub_install0="kopenbsd -h com0 /6.8/amd64/bsd.rd" +grub_install0="kopenbsd -h com0 /6.9/amd64/bsd.rd" grub_run0="kopenbsd -h com0 -r sd0a /bsd" bhyve_options="-w" diff --git a/roles/cgit/defaults/main.yml b/roles/cgit/defaults/main.yml index ffbca1d..9fe8961 100644 --- a/roles/cgit/defaults/main.yml +++ b/roles/cgit/defaults/main.yml @@ -6,8 +6,12 @@ cgit_user: "git" cgit_group: "git" +cgit_instance: "cgit" + cgit_git_dir: "/data/git" -cgit_git_dir_chroot: "/htdocs/cgit" +cgit_chroot_dir: "/var/www" + +cgit_ip: 0.0.0.0 cgit_port: 1235 cgit_authenticate: false @@ -16,3 +20,4 @@ cgit__logo: "http://rgoncalves.se/logo.png" cgit__css: "http://rgoncalves.se/style/cgit.css" cgit__root_desc: "development hub" cgit__root_readme: "http://rgoncalves.se" +cgit__footer: "/conf/footer.html" diff --git a/roles/cgit/meta/main.yml b/roles/cgit/meta/main.yml index 02b67be..a25f289 100644 --- a/roles/cgit/meta/main.yml +++ b/roles/cgit/meta/main.yml @@ -1,9 +1,5 @@ - -# cgit ~~ roles/cgit/meta/main.yml -# Meta parameters - ---- - dependencies: - - { role: git, tags: "dependency" } - - { role: httpd_pre, tags: "dependency" } + - role: git + tags: dependency + - role: httpd_pre + tags: dependency diff --git a/roles/cgit/tasks/main.yml b/roles/cgit/tasks/main.yml index 6b52bd7..fa68415 100644 --- a/roles/cgit/tasks/main.yml +++ b/roles/cgit/tasks/main.yml @@ -1,21 +1,22 @@ - -# cgit ~~ roles/cgit/tasks/main.yml -# cgit web interface - ---- - - name: ensure cgit is installed package: name: cgit state: present -- name: generate cgit configuration file +- name: generate cgit configuration files template: - src: var-www-conf-cgitrc.j2 - dest: /var/www/conf/cgitrc + src: "{{ item.template }}" + dest: "{{ item.file }}" owner: "0" group: "0" mode: "0644" + loop: + - template: conf-cgitrc.j2 + file: "{{ cgit_chroot_dir }}/conf/cgitrc" + - template: conf-footer.html.j2 + file: "{{ cgit_chroot_dir }}/conf/footer.html" + - template: etc-httpd.d-cgit.conf.j2 + file: /etc/httpd.d/cgit.conf - name: generate cgit configuration for httpd template: @@ -28,7 +29,7 @@ - name: copy utility in httpd chroot copy: src: "/bin/{{ item }}" - dest: /var/www/bin + dest: "{{ cgit_chroot_dir }}/bin" mode: preserve remote_src: true loop: @@ -38,34 +39,11 @@ - name: copy about-filter generator copy: src: about-filter.sh - dest: /var/www/bin/about-filter.sh + dest: "{{ cgit_chroot_dir }}/bin/about-filter.sh" owner: "0" group: "0" mode: "0755" -- name: ensure cgit web directory exists - file: - path: /var/www/{{ cgit_git_dir_chroot }} - owner: "{{ cgit_user }}" - group: daemon - state: directory - mode: "0755" - -- name: include nfsclient for remote dir - include_role: - name: nfsclient - vars: - nfsclient_dir: "/var/www/{{ cgit_git_dir_chroot }}" - nfsclient_server_dir: "{{ global.nfs_server_dir }}/{{ ansible_host }}/git" - #nfsclient_server: "{{ global.nfs_server }}" - -- name: chown git directory to git - file: - path: /data/git - owner: "{{ cgit_user }}" - group: "{{ cgit_group }}" - state: directory - - name: start and enable slowcgi service service: name: slowcgi @@ -76,5 +54,5 @@ debug: msg: | Please provide a password using htpasswd, - in /htpasswd/cgit + in "{{ cgit_chroot_dir }}/htpasswd/cgit" when: cgit_authenticate diff --git a/roles/cgit/templates/var-www-conf-cgitrc.j2 b/roles/cgit/templates/conf-cgitrc.j2 index 8be36ce..1fc283f 100644 --- a/roles/cgit/templates/var-www-conf-cgitrc.j2 +++ b/roles/cgit/templates/conf-cgitrc.j2 @@ -6,6 +6,7 @@ css={{ cgit__css }} logo={{ cgit__logo }} favicon={{ cgit__favicon }} +footer={{ cgit__footer }} # readme readme=:README.md @@ -21,6 +22,7 @@ enable-http-clone=1 enable-index-links=1 max-stats=quarter robots=noindex, nofollow +localtime=1 # git clone-url=git://git.{{ global.domain_name }}/$CGIT_REPO_URL ssh://git@git.{{ global.domain_name }}/$CGIT_REPO_URL http://git.{{ global.domain_name }}/$CGIT_REPO_URL @@ -36,4 +38,4 @@ snapshots=tar.gz # sections section-from-path=1 section-sort=1 -scan-path={{ cgit_git_dir_chroot }} +scan-path={{ cgit_git_dir }} diff --git a/roles/cgit/templates/conf-footer.html.j2 b/roles/cgit/templates/conf-footer.html.j2 new file mode 100644 index 0000000..66ca627 --- /dev/null +++ b/roles/cgit/templates/conf-footer.html.j2 @@ -0,0 +1,3 @@ +<span style="background-color:yellow"> +remember that computers suck. +</span> diff --git a/roles/cgit/templates/etc-httpd.d-cgit.conf.j2 b/roles/cgit/templates/etc-httpd.d-cgit.conf.j2 index 6fb8e98..b77ca35 100644 --- a/roles/cgit/templates/etc-httpd.d-cgit.conf.j2 +++ b/roles/cgit/templates/etc-httpd.d-cgit.conf.j2 @@ -2,19 +2,19 @@ # httpd ~~ /etc/httpd.d/cgit.conf" # managed by Ansible -ext_ip="0.0.0.0" server "cgit" { - listen on $ext_ip port {{ cgit_port }} + listen on "{{ cgit_ip }}" port {{ cgit_port }} {% if cgit_authenticate %} authenticate "realm" with "/htpasswd/cgit" {% endif %} - # serve cgit static files directly: cgit.css and cgit.png + # cgit location "/cgit.*" { root "/cgit" - no fastcgi + no fastcgi } - # cgit CGI + + # fastcgi root "/cgi-bin/cgit.cgi" fastcgi socket "/run/slowcgi.sock" } diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index b562e88..1558f02 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -46,4 +46,3 @@ - name: synchronize host hostname with config hostname hostname: name="{{ inventory_hostname }}" - diff --git a/roles/git/vars/main.yml b/roles/git/defaults/main.yml index 6f7ffb8..2128abb 100644 --- a/roles/git/vars/main.yml +++ b/roles/git/defaults/main.yml @@ -9,3 +9,4 @@ git_group: "git" git_dir: "/data/git" git_shell: "/bin/sh" +git_default_branch: "trunk" diff --git a/roles/git/tasks/main.yml b/roles/git/tasks/main.yml index 5600e2d..a421ad0 100644 --- a/roles/git/tasks/main.yml +++ b/roles/git/tasks/main.yml @@ -5,7 +5,9 @@ --- - name: ensure git package is present - package: name=git state=present + package: + name: git + state: present - name: ensure git group exists group: @@ -17,43 +19,38 @@ name: "{{ git_user }}" group: "{{ git_group }}" shell: "{{ git_shell }}" - home: "/home/{{ git_user }}" + home: "{{ git_dir }}" create_home: false -- name: ensure git home directory is not created - file: path="/home/{{ git_user }}" state=absent - -- name: ensure git-only directory exists - file: - path: "{{ git_dir }}" - owner: "{{ git_user }}" - group: "{{ git_group }}" - state: directory - mode: 0755 - -- name: link git user home directory with git root repository - file: - src: "{{ git_dir }}" - dest: "/home/{{ git_user }}" - owner: "{{ git_user }}" - group: "{{ git_group }}" - mode: 0750 - force: true - state: link - -- name: ensure git-shell-commands directory exists +- name: ensure git directories exist file: - path: "/home/{{ git_user }}/git-shell-commands" + path: "{{ item }}" owner: "{{ git_user }}" group: "{{ git_group }}" state: directory - mode: 0755 + mode: "0755" + loop: + - "{{ git_dir }}" + - "{{ git_dir }}/git-shell-commands" - name: generate git-shell no-login prompt template: src: no-interactive-login.j2 - dest: "/home/{{ git_user }}/git-shell-commands/no-interactive-login" + dest: "{{ git_dir }}/git-shell-commands/no-interactive-login" owner: "{{ git_user }}" group: "{{ git_group }}" - mode: 0744 + mode: "0744" when: git_nologin is defined and git_nologin + +- name: generate gitconfig + template: + src: gitconfig.j2 + dest: "{{ git_dir }}/.gitconfig" + owner: "{{ git_user }}" + group: "{{ git_group }}" + mode: "0644" + +- name: synchronize ssh key + include_role: + name: sshd + tasks_from: sync_keys diff --git a/roles/git/templates/gitconfig.j2 b/roles/git/templates/gitconfig.j2 new file mode 100644 index 0000000..b9923a2 --- /dev/null +++ b/roles/git/templates/gitconfig.j2 @@ -0,0 +1,2 @@ +[init] + defaultBranch = {{ git_default_branch }} diff --git a/roles/grafana/vars/main.yml b/roles/grafana/defaults/main.yml index 9e15d9c..f415110 100644 --- a/roles/grafana/vars/main.yml +++ b/roles/grafana/defaults/main.yml @@ -1,9 +1,3 @@ - -# grafana ~~ roles/grafana/tasks/main.yml -# grafana variables - ---- - grafana_dir: /data/grafana grafana_port: 3001 grafana_port_out: 3000 diff --git a/roles/grafana/tasks/main.yml b/roles/grafana/tasks/main.yml index 919f15e..d002b51 100644 --- a/roles/grafana/tasks/main.yml +++ b/roles/grafana/tasks/main.yml @@ -1,36 +1,39 @@ - -# grafana ~~ roles/grafana/tasks/main.yml -# grafana setup - ---- - - name: install grafana - package: name=grafana state=present + package: + name: grafana + state: present -- name: ensure grafana dir exists +- name: ensure grafana directories exists file: - path: "{{ grafana_dir }}" + path: "{{ grafana_dir }}/{{ item }}" owner: "{{ grafana_user }}" group: "{{ grafana_group }}" - mode: 0640 + mode: "0640" state: directory + loop: + - "" + - "data" + - "logs" + - "plugins" - name: generate grafana configuration template: - src: grafana.ini.j2 + src: etc-grafana.ini.j2 dest: /etc/grafana.ini - owner: "{{ user_root }}" - group: "{{ group_root }}" - mode: 0644 + owner: "0" + group: "0" + mode: "0644" -- name: generate reverse proxy configuration for nginx +- name: generate grafana data sources template: - src: grafana.conf.nginx.j2 - dest: /etc/nginx/conf.d/grafana.conf - owner: "{{ user_root }}" - group: "{{ group_root }}" - mode: 0644 - when: ansible_distribution != "OpenBSD" + src: datasources-default.yml.j2 + dest: /etc/grafana/provisioning/datasources/default.yml + owner: "{{ grafana_user }}" + group: "{{ grafana_group }}" + mode: "0640" - name: start and enable grafana service - service: name=grafana state=restarted enabled=true + service: + name: grafana + state: restarted + enabled: true diff --git a/roles/grafana/templates/datasources-default.yml.j2 b/roles/grafana/templates/datasources-default.yml.j2 new file mode 100644 index 0000000..690487f --- /dev/null +++ b/roles/grafana/templates/datasources-default.yml.j2 @@ -0,0 +1,16 @@ +{% import 'macros.j2' as macros with context %} + +# datasources for grafana +# managed by Ansible + +apiVersion: 1 + +datasources: +{% call(h) macros.loop_valid_hosts("servers") %} + - name: {{ h.ansible_host }}-prometheus + type: prometheus + url: http://{{ h.ip.in }}:9090 + - name: {{ h.ansible_host }}-loki + type: prometheus + +{% endcall %} diff --git a/roles/grafana/templates/etc-grafana.ini.j2 b/roles/grafana/templates/etc-grafana.ini.j2 new file mode 100644 index 0000000..8bcad25 --- /dev/null +++ b/roles/grafana/templates/etc-grafana.ini.j2 @@ -0,0 +1,246 @@ + +# grafana configuration +# managed by Ansible + +app_mode = production +instance_name = <rgoncalves.se monitoring> + +[paths] +data = {{ grafana_dir }}/data +logs = {{ grafana_dir }}/logs +plugins = {{ grafana_dir }}/plugins +provisioning = provisioning +temp_data_lifetime = 24h + +[server] +protocol = http +http_addr = +http_port = {{ grafana_port }} +;domain = 0.0.0.0 + +# The full public facing url you use in browser, used for redirects and emails +# If you use reverse proxy and sub path specify full url (with sub path) +;root_url = %(protocol)s://%(domain)s:%(http_port)s/ + +# Log web requests +router_logging = true +enable_gzip = true + +[database] + +;type = sqlite3 +;host = 127.0.0.1:3306 +;name = grafana +;user = root +# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" +;password = + +path = grafana.db +max_idle_conn = 2 +log_queries = true +cache_mode = shared + +[remote_cache] +type = database + +[dataproxy] + +[analytics] + +[security] +disable_initial_admin_creation = true +disable_gravatar = true +allow_embedding = true + +strict_transport_security = false + +[snapshots] +# snapshot sharing options +external_enabled = true +;external_snapshot_url = https://snapshots-origin.raintank.io +;external_snapshot_name = Publish to snapshot.raintank.io + +public_mode = false + +[dashboards] +versions_to_keep = 20 +min_refresh_interval = 5s +default_home_dashboard_path = + +[users] +allow_sign_up = false +allow_org_create = false +auto_assign_org = false +auto_assign_org_role = Viewer +verify_email_enabled = false +login_hint = email or username +password_hint = password +viewers_can_edit = true +editors_can_admin = false +user_invite_max_lifetime_duration = 24h + +default_theme = dark + +[auth] +login_cookie_name = grafana_session + +[auth.anonymous] +enabled = false + +[auth.github] +enabled = false + +[auth.gitlab] +enabled = false + +[auth.google] +enabled = false + +[auth.grafana_com] +enabled = false + +[auth.azuread] +enabled = false + +[auth.okta] +enabled = false + +[auth.generic_oauth] +enabled = false + +[auth.basic] +enabled = true + +[auth.proxy] +enabled = false + +[auth.ldap] +enabled = false +config_file = /etc/grafana/ldap.toml +allow_sign_up = true + +[smtp] +enabled = false + +[emails] +welcome_email_on_sign_up = false +templates_pattern = emails/*.html + +[log] +mode = console file +level = info +filters = + +[log.console] +level = +format = console + +[log.file] +level = +format = text + +log_rotate = true +max_lines = 1000000 +max_size_shift = 28 + +daily_rotate = true +max_days = 7 + +[log.syslog] +level = +format = text +network = +address = + +facility = +tag = + +[quota] +enabled = false + +[alerting] +enabled = true +execute_alerts = true +error_or_timeout = alerting +nodata_or_nullvalues = no_data + +concurrent_render_limit = 5 + +;evaluation_timeout_seconds = 30 +;notification_timeout_seconds = 30 +;max_attempts = 3 +;min_interval_seconds = 1 + +[annotations.dashboard] + +[explore] +enabled = true + +# Metrics available at HTTP API Url /metrics +[metrics] +enabled = true +interval_seconds = 10 +disable_total_stats = false + +; basic_auth_username = +; basic_auth_password = + +[metrics.environment_info] + +[metrics.graphite] +;address = +;prefix = prod.grafana.%(instance_name)s. + +[grafana_com] +;url = https://grafana.com + +[tracing.jaeger] + +[external_image_storage] +;provider = + +[external_image_storage.s3] +;endpoint = +;path_style_access = +;bucket = +;region = +;path = +;access_key = +;secret_key = + +[external_image_storage.webdav] +;url = +;public_url = +;username = +;password = + +[external_image_storage.gcs] +;key_file = +;bucket = +;path = + +[external_image_storage.azure_blob] +;account_name = +;account_key = +;container_name = + +[external_image_storage.local] + +[rendering] + +[panels] +disable_sanitize_html = false + +[plugins] +enable_alpha = true + +[plugin.grafana-image-renderer] + +[enterprise] +;license_path = + +[feature_toggles] +;enable = + +[date_formats] +default_timezone = browser diff --git a/roles/grafana/templates/grafana.conf.nginx.j2 b/roles/grafana/templates/grafana.conf.nginx.j2 deleted file mode 100644 index c0f926c..0000000 --- a/roles/grafana/templates/grafana.conf.nginx.j2 +++ /dev/null @@ -1,9 +0,0 @@ -server { - listen {{ grafana_port_out }}; - root /usr/share/nginx/html; - index index.html index.htm; - - location / { - proxy_pass http://127.0.0.1:{{ grafana_port }}/; - } -} diff --git a/roles/grafana/templates/grafana.ini.j2 b/roles/grafana/templates/grafana.ini.j2 deleted file mode 100644 index 75de264..0000000 --- a/roles/grafana/templates/grafana.ini.j2 +++ /dev/null @@ -1,852 +0,0 @@ - -# grafana configuration ~~ /etc/grafana.ini - -##################### Grafana Configuration Example ##################### -# -# Everything has defaults so you only need to uncomment things you want to -# change - -# possible values : production, development -;app_mode = production - -# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty -instance_name = <rgoncalves.se monitoring> - -#################################### Paths #################################### -[paths] -# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) -data = {{ grafana_dir }} - -# Temporary files in `data` directory older than given duration will be removed -;temp_data_lifetime = 24h - -# Directory where grafana can store logs -;logs = /var/log/grafana - -# Directory where grafana will automatically scan and look for plugins -;plugins = {{ grafana_dir }}/plugins - -# folder that contains provisioning config files that grafana will apply on startup and while running. -;provisioning = conf/provisioning - -#################################### Server #################################### -[server] -# Protocol (http, https, h2, socket) -;protocol = http - -# The ip address to bind to, empty will bind to all interfaces -http_addr = - -# The http port to use -http_port = {{ grafana_port }} - -# The public facing domain name used to access grafana from a browser -;domain = 0.0.0.0 - -# Redirect to correct domain if host header does not match domain -# Prevents DNS rebinding attacks -;enforce_domain = false - -# The full public facing url you use in browser, used for redirects and emails -# If you use reverse proxy and sub path specify full url (with sub path) -;root_url = %(protocol)s://%(domain)s:%(http_port)s/ - -# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. -;serve_from_sub_path = false - -# Log web requests -;router_logging = false - -# the path relative working path -;static_root_path = public - -# enable gzip -;enable_gzip = false - -# https certs & key file -;cert_file = -;cert_key = - -# Unix socket path -;socket = - -#################################### Database #################################### -[database] -# You can configure the database connection by specifying type, host, name, user and password -# as separate properties or as on string using the url properties. - -# Either "mysql", "postgres" or "sqlite3", it's your choice -;type = sqlite3 -;host = 127.0.0.1:3306 -;name = grafana -;user = root -# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" -;password = - -# Use either URL or the previous fields to configure the database -# Example: mysql://user:secret@host:port/database -;url = - -# For "postgres" only, either "disable", "require" or "verify-full" -;ssl_mode = disable - -;ca_cert_path = -;client_key_path = -;client_cert_path = -;server_cert_name = - -# For "sqlite3" only, path relative to data_path setting -;path = grafana.db - -# Max idle conn setting default is 2 -;max_idle_conn = 2 - -# Max conn setting default is 0 (mean not set) -;max_open_conn = - -# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours) -;conn_max_lifetime = 14400 - -# Set to true to log the sql calls and execution times. -;log_queries = - -# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared) -;cache_mode = private - -#################################### Cache server ############################# -[remote_cache] -# Either "redis", "memcached" or "database" default is "database" -;type = database - -# cache connectionstring options -# database: will use Grafana primary database. -# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'. -# memcache: 127.0.0.1:11211 -;connstr = - -#################################### Data proxy ########################### -[dataproxy] - -# This enables data proxy logging, default is false -;logging = false - -# How long the data proxy waits before timing out, default is 30 seconds. -# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set. -;timeout = 30 - -# How many seconds the data proxy waits before sending a keepalive probe request. -;keep_alive_seconds = 30 - -# How many seconds the data proxy waits for a successful TLS Handshake before timing out. -;tls_handshake_timeout_seconds = 10 - -# How many seconds the data proxy will wait for a server's first response headers after -# fully writing the request headers if the request has an "Expect: 100-continue" -# header. A value of 0 will result in the body being sent immediately, without -# waiting for the server to approve. -;expect_continue_timeout_seconds = 1 - -# The maximum number of idle connections that Grafana will keep alive. -;max_idle_connections = 100 - -# How many seconds the data proxy keeps an idle connection open before timing out. -;idle_conn_timeout_seconds = 90 - -# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false. -;send_user_header = false - -#################################### Analytics #################################### -[analytics] -# Server reporting, sends usage counters to stats.grafana.org every 24 hours. -# No ip addresses are being tracked, only simple counters to track -# running instances, dashboard and error counts. It is very helpful to us. -# Change this option to false to disable reporting. -;reporting_enabled = true - -# Set to false to disable all checks to https://grafana.net -# for new versions (grafana itself and plugins), check is used -# in some UI views to notify that grafana or plugin update exists -# This option does not cause any auto updates, nor send any information -# only a GET request to http://grafana.com to get latest versions -;check_for_updates = true - -# Google Analytics universal tracking code, only enabled if you specify an id here -;google_analytics_ua_id = - -# Google Tag Manager ID, only enabled if you specify an id here -;google_tag_manager_id = - -#################################### Security #################################### -[security] -# disable creation of admin user on first start of grafana -;disable_initial_admin_creation = false - -# default admin user, created on startup -;admin_user = admin - -# default admin password, can be changed before first start of grafana, or in profile settings -;admin_password = admin - -# used for signing -;secret_key = SW2YcwTIb9zpOOhoPsMm - -# disable gravatar profile images -;disable_gravatar = false - -# data source proxy whitelist (ip_or_domain:port separated by spaces) -;data_source_proxy_whitelist = - -# disable protection against brute force login attempts -;disable_brute_force_login_protection = false - -# set to true if you host Grafana behind HTTPS. default is false. -;cookie_secure = false - -# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled" -;cookie_samesite = lax - -# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false. -;allow_embedding = false - -# Set to true if you want to enable http strict transport security (HSTS) response header. -# This is only sent when HTTPS is enabled in this configuration. -# HSTS tells browsers that the site should only be accessed using HTTPS. -;strict_transport_security = false - -# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled. -;strict_transport_security_max_age_seconds = 86400 - -# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled. -;strict_transport_security_preload = false - -# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled. -;strict_transport_security_subdomains = false - -# Set to true to enable the X-Content-Type-Options response header. -# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised -# in the Content-Type headers should not be changed and be followed. -;x_content_type_options = true - -# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading -# when they detect reflected cross-site scripting (XSS) attacks. -;x_xss_protection = true - -#################################### Snapshots ########################### -[snapshots] -# snapshot sharing options -;external_enabled = true -;external_snapshot_url = https://snapshots-origin.raintank.io -;external_snapshot_name = Publish to snapshot.raintank.io - -# Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for -# creating and deleting snapshots. -;public_mode = false - -# remove expired snapshot -;snapshot_remove_expired = true - -#################################### Dashboards History ################## -[dashboards] -# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1 -;versions_to_keep = 20 - -# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds. -# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. -;min_refresh_interval = 5s - -# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json" -;default_home_dashboard_path = - -#################################### Users ############################### -[users] -# disable user signup / registration -;allow_sign_up = true - -# Allow non admin users to create organizations -;allow_org_create = true - -# Set to true to automatically assign new users to the default organization (id 1) -;auto_assign_org = true - -# Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true) -;auto_assign_org_id = 1 - -# Default role new users will be automatically assigned (if disabled above is set to true) -;auto_assign_org_role = Viewer - -# Require email validation before sign up completes -;verify_email_enabled = false - -# Background text for the user field on the login page -;login_hint = email or username -;password_hint = password - -# Default UI theme ("dark" or "light") -;default_theme = dark - -# External user management, these options affect the organization users view -;external_manage_link_url = -;external_manage_link_name = -;external_manage_info = - -# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard. -;viewers_can_edit = false - -# Editors can administrate dashboard, folders and teams they create -;editors_can_admin = false - -# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes). -;user_invite_max_lifetime_duration = 24h - -[auth] -# Login cookie name -;login_cookie_name = grafana_session - -# The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation. -;login_maximum_inactive_lifetime_duration = - -# The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). -;login_maximum_lifetime_duration = - -# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes. -;token_rotation_interval_minutes = 10 - -# Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false -;disable_login_form = false - -# Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false -;disable_signout_menu = false - -# URL to redirect the user to after sign out -;signout_redirect_url = - -# Set to true to attempt login with OAuth automatically, skipping the login screen. -# This setting is ignored if multiple OAuth providers are configured. -;oauth_auto_login = false - -# OAuth state max age cookie duration in seconds. Defaults to 600 seconds. -;oauth_state_cookie_max_age = 600 - -# limit of api_key seconds to live before expiration -;api_key_max_seconds_to_live = -1 - -# Set to true to enable SigV4 authentication option for HTTP-based datasources. -;sigv4_auth_enabled = false - -#################################### Anonymous Auth ###################### -[auth.anonymous] -# enable anonymous access -;enabled = false - -# specify organization name that should be used for unauthenticated users -;org_name = Main Org. - -# specify role for unauthenticated users -;org_role = Viewer - -# mask the Grafana version number for unauthenticated users -;hide_version = false - -#################################### GitHub Auth ########################## -[auth.github] -;enabled = false -;allow_sign_up = true -;client_id = some_id -;client_secret = some_secret -;scopes = user:email,read:org -;auth_url = https://github.com/login/oauth/authorize -;token_url = https://github.com/login/oauth/access_token -;api_url = https://api.github.com/user -;allowed_domains = -;team_ids = -;allowed_organizations = - -#################################### GitLab Auth ######################### -[auth.gitlab] -;enabled = false -;allow_sign_up = true -;client_id = some_id -;client_secret = some_secret -;scopes = api -;auth_url = https://gitlab.com/oauth/authorize -;token_url = https://gitlab.com/oauth/token -;api_url = https://gitlab.com/api/v4 -;allowed_domains = -;allowed_groups = - -#################################### Google Auth ########################## -[auth.google] -;enabled = false -;allow_sign_up = true -;client_id = some_client_id -;client_secret = some_client_secret -;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email -;auth_url = https://accounts.google.com/o/oauth2/auth -;token_url = https://accounts.google.com/o/oauth2/token -;api_url = https://www.googleapis.com/oauth2/v1/userinfo -;allowed_domains = -;hosted_domain = - -#################################### Grafana.com Auth #################### -[auth.grafana_com] -;enabled = false -;allow_sign_up = true -;client_id = some_id -;client_secret = some_secret -;scopes = user:email -;allowed_organizations = - -#################################### Azure AD OAuth ####################### -[auth.azuread] -;name = Azure AD -;enabled = false -;allow_sign_up = true -;client_id = some_client_id -;client_secret = some_client_secret -;scopes = openid email profile -;auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize -;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token -;allowed_domains = -;allowed_groups = - -#################################### Okta OAuth ####################### -[auth.okta] -;name = Okta -;enabled = false -;allow_sign_up = true -;client_id = some_id -;client_secret = some_secret -;scopes = openid profile email groups -;auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize -;token_url = https://<tenant-id>.okta.com/oauth2/v1/token -;api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo -;allowed_domains = -;allowed_groups = -;role_attribute_path = - -#################################### Generic OAuth ########################## -[auth.generic_oauth] -;enabled = false -;name = OAuth -;allow_sign_up = true -;client_id = some_id -;client_secret = some_secret -;scopes = user:email,read:org -;email_attribute_name = email:primary -;email_attribute_path = -;login_attribute_path = -;id_token_attribute_name = -;auth_url = https://foo.bar/login/oauth/authorize -;token_url = https://foo.bar/login/oauth/access_token -;api_url = https://foo.bar/user -;allowed_domains = -;team_ids = -;allowed_organizations = -;role_attribute_path = -;tls_skip_verify_insecure = false -;tls_client_cert = -;tls_client_key = -;tls_client_ca = - -#################################### Basic Auth ########################## -[auth.basic] -;enabled = true - -#################################### Auth Proxy ########################## -[auth.proxy] -;enabled = false -;header_name = X-WEBAUTH-USER -;header_property = username -;auto_sign_up = true -;sync_ttl = 60 -;whitelist = 192.168.1.1, 192.168.2.1 -;headers = Email:X-User-Email, Name:X-User-Name -# Read the auth proxy docs for details on what the setting below enables -;enable_login_token = false - -#################################### Auth LDAP ########################## -[auth.ldap] -;enabled = false -;config_file = /etc/grafana/ldap.toml -;allow_sign_up = true - -# LDAP backround sync (Enterprise only) -# At 1 am every day -;sync_cron = "0 0 1 * * *" -;active_sync_enabled = true - -#################################### SMTP / Emailing ########################## -[smtp] -;enabled = false -;host = localhost:25 -;user = -# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" -;password = -;cert_file = -;key_file = -;skip_verify = false -;from_address = admin@grafana.localhost -;from_name = Grafana -# EHLO identity in SMTP dialog (defaults to instance_name) -;ehlo_identity = dashboard.example.com -# SMTP startTLS policy (defaults to 'OpportunisticStartTLS') -;startTLS_policy = NoStartTLS - -[emails] -;welcome_email_on_sign_up = false -;templates_pattern = emails/*.html - -#################################### Logging ########################## -[log] -# Either "console", "file", "syslog". Default is console and file -# Use space to separate multiple modes, e.g. "console file" -;mode = console file - -# Either "debug", "info", "warn", "error", "critical", default is "info" -;level = info - -# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug -;filters = - -# For "console" mode only -[log.console] -;level = - -# log line format, valid options are text, console and json -;format = console - -# For "file" mode only -[log.file] -;level = - -# log line format, valid options are text, console and json -;format = text - -# This enables automated log rotate(switch of following options), default is true -;log_rotate = true - -# Max line number of single file, default is 1000000 -;max_lines = 1000000 - -# Max size shift of single file, default is 28 means 1 << 28, 256MB -;max_size_shift = 28 - -# Segment log daily, default is true -;daily_rotate = true - -# Expired days of log file(delete after max days), default is 7 -;max_days = 7 - -[log.syslog] -;level = - -# log line format, valid options are text, console and json -;format = text - -# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used. -;network = -;address = - -# Syslog facility. user, daemon and local0 through local7 are valid. -;facility = - -# Syslog tag. By default, the process' argv[0] is used. -;tag = - -#################################### Usage Quotas ######################## -[quota] -; enabled = false - -#### set quotas to -1 to make unlimited. #### -# limit number of users per Org. -; org_user = 10 - -# limit number of dashboards per Org. -; org_dashboard = 100 - -# limit number of data_sources per Org. -; org_data_source = 10 - -# limit number of api_keys per Org. -; org_api_key = 10 - -# limit number of orgs a user can create. -; user_org = 10 - -# Global limit of users. -; global_user = -1 - -# global limit of orgs. -; global_org = -1 - -# global limit of dashboards -; global_dashboard = -1 - -# global limit of api_keys -; global_api_key = -1 - -# global limit on number of logged in users. -; global_session = -1 - -#################################### Alerting ############################ -[alerting] -# Disable alerting engine & UI features -;enabled = true -# Makes it possible to turn off alert rule execution but alerting UI is visible -;execute_alerts = true - -# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state) -;error_or_timeout = alerting - -# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok) -;nodata_or_nullvalues = no_data - -# Alert notifications can include images, but rendering many images at the same time can overload the server -# This limit will protect the server from render overloading and make sure notifications are sent out quickly -;concurrent_render_limit = 5 - - -# Default setting for alert calculation timeout. Default value is 30 -;evaluation_timeout_seconds = 30 - -# Default setting for alert notification timeout. Default value is 30 -;notification_timeout_seconds = 30 - -# Default setting for max attempts to sending alert notifications. Default value is 3 -;max_attempts = 3 - -# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend -;min_interval_seconds = 1 - -# Configures for how long alert annotations are stored. Default is 0, which keeps them forever. -# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month). -;max_annotation_age = - -# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations. -;max_annotations_to_keep = - -#################################### Annotations ######################### - -[annotations.dashboard] -# Dashboard annotations means that annotations are associated with the dashboard they are created on. - -# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever. -# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month). -;max_age = - -# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations. -;max_annotations_to_keep = - -[annotations.api] -# API annotations means that the annotations have been created using the API without any -# association with a dashboard. - -# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever. -# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month). -;max_age = - -# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations. -;max_annotations_to_keep = - -#################################### Explore ############################# -[explore] -# Enable the Explore section -;enabled = true - -#################################### Internal Grafana Metrics ########################## -# Metrics available at HTTP API Url /metrics -[metrics] -# Disable / Enable internal metrics -;enabled = true -# Graphite Publish interval -;interval_seconds = 10 -# Disable total stats (stat_totals_*) metrics to be generated -;disable_total_stats = false - -#If both are set, basic auth will be required for the metrics endpoint. -; basic_auth_username = -; basic_auth_password = - -# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which -# can expose more information about the Grafana instance. -[metrics.environment_info] -#exampleLabel1 = exampleValue1 -#exampleLabel2 = exampleValue2 - -# Send internal metrics to Graphite -[metrics.graphite] -# Enable by setting the address setting (ex localhost:2003) -;address = -;prefix = prod.grafana.%(instance_name)s. - -#################################### Grafana.com integration ########################## -# Url used to import dashboards directly from Grafana.com -[grafana_com] -;url = https://grafana.com - -#################################### Distributed tracing ############ -[tracing.jaeger] -# Enable by setting the address sending traces to jaeger (ex localhost:6831) -;address = localhost:6831 -# Tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2) -;always_included_tag = tag1:value1 -# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote -;sampler_type = const -# jaeger samplerconfig param -# for "const" sampler, 0 or 1 for always false/true respectively -# for "probabilistic" sampler, a probability between 0 and 1 -# for "rateLimiting" sampler, the number of spans per second -# for "remote" sampler, param is the same as for "probabilistic" -# and indicates the initial sampling rate before the actual one -# is received from the mothership -;sampler_param = 1 -# sampling_server_url is the URL of a sampling manager providing a sampling strategy. -;sampling_server_url = -# Whether or not to use Zipkin propagation (x-b3- HTTP headers). -;zipkin_propagation = false -# Setting this to true disables shared RPC spans. -# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure. -;disable_shared_zipkin_spans = false - -#################################### External image storage ########################## -[external_image_storage] -# Used for uploading images to public servers so they can be included in slack/email messages. -# you can choose between (s3, webdav, gcs, azure_blob, local) -;provider = - -[external_image_storage.s3] -;endpoint = -;path_style_access = -;bucket = -;region = -;path = -;access_key = -;secret_key = - -[external_image_storage.webdav] -;url = -;public_url = -;username = -;password = - -[external_image_storage.gcs] -;key_file = -;bucket = -;path = - -[external_image_storage.azure_blob] -;account_name = -;account_key = -;container_name = - -[external_image_storage.local] -# does not require any configuration - -[rendering] -# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer. -# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service. -;server_url = -# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/. -;callback_url = -# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server, -# which this setting can help protect against by only allowing a certain amount of concurrent requests. -;concurrent_render_request_limit = 30 - -[panels] -# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities. -;disable_sanitize_html = false - -[plugins] -;enable_alpha = false -;app_tls_skip_verify_insecure = false -# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature. -;allow_loading_unsigned_plugins = -;marketplace_url = https://grafana.com/grafana/plugins/ - -#################################### Grafana Image Renderer Plugin ########################## -[plugin.grafana-image-renderer] -# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert. -# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported -# timezone IDs. Fallbacks to TZ environment variable if not set. -;rendering_timezone = - -# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert. -# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'. -;rendering_language = - -# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert. -# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image. -;rendering_viewport_device_scale_factor = - -# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to -# the security risk it's not recommended to ignore HTTPS errors. -;rendering_ignore_https_errors = - -# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will -# only capture and log error messages. When enabled, debug messages are captured and logged as well. -# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure -# [log].filter = rendering:debug. -;rendering_verbose_logging = - -# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service. -# Default is false. This can be useful to enable (true) when troubleshooting. -;rendering_dumpio = - -# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found -# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character. -;rendering_args = - -# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium. -# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not -# compatible with the plugin. -;rendering_chrome_bin = - -# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request. -# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently. -# Mode 'reusable' will have one browser instance and will create a new incognito page on each request. -;rendering_mode = - -# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser' -# and will cluster using browser instances. -# Mode 'context' will cluster using incognito pages. -;rendering_clustering_mode = -# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently.. -;rendering_clustering_max_concurrency = - -# Limit the maximum viewport width, height and device scale factor that can be requested. -;rendering_viewport_max_width = -;rendering_viewport_max_height = -;rendering_viewport_max_device_scale_factor = - -# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign -# a port not in use. -;grpc_host = -;grpc_port = - -[enterprise] -# Path to a valid Grafana Enterprise license.jwt file -;license_path = - -[feature_toggles] -# enable features, separated by spaces -;enable = - -[date_formats] -# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/ - -# Default system date format used in time range picker and other places where full time is displayed -;full_date = YYYY-MM-DD HH:mm:ss - -# Used by graph and other places where we only show small intervals -;interval_second = HH:mm:ss -;interval_minute = HH:mm -;interval_hour = MM/DD HH:mm -;interval_day = MM/DD -;interval_month = YYYY-MM -;interval_year = YYYY - -# Experimental feature -;use_browser_locale = false - -# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc. -;default_timezone = browser diff --git a/roles/htpasswd/defaults/main.yml b/roles/htpasswd/defaults/main.yml new file mode 100644 index 0000000..458b9c1 --- /dev/null +++ b/roles/htpasswd/defaults/main.yml @@ -0,0 +1,4 @@ +htpasswd_user: "www" +htpasswd_password: "" +htpasswd_dir: "/htpasswd" +htpasswd_service: "" diff --git a/roles/htpasswd/tasks/main.yml b/roles/htpasswd/tasks/main.yml new file mode 100644 index 0000000..9586c82 --- /dev/null +++ b/roles/htpasswd/tasks/main.yml @@ -0,0 +1,11 @@ +- name: ensure htpasswd service is specified + fail: + when: + +- name: set variable for realm generation + set_facts: + htpasswd_credentials_: "{{ htpasswd_user }}:{{ htpasswd_password }}" + htpasswd_file_: "{{ htpasswd_dir }}/{{ htpasswd_service }}" + +- name: generate realm file + shell: echo "{{ htpasswd_credentials_ }}" | htpasswd -I "{{ htpasswd_file_ }}" diff --git a/roles/httpd/defaults/main.yml b/roles/httpd/defaults/main.yml new file mode 100644 index 0000000..3226407 --- /dev/null +++ b/roles/httpd/defaults/main.yml @@ -0,0 +1,3 @@ +httpd_chroot: "/var/www" +httpd_chroot_default: "" +httpd_use_nfs: false diff --git a/roles/httpd/tasks/main.yml b/roles/httpd/tasks/main.yml index 6c91aac..c188eda 100644 --- a/roles/httpd/tasks/main.yml +++ b/roles/httpd/tasks/main.yml @@ -23,4 +23,3 @@ name: httpd state: restarted enabled: true - diff --git a/roles/httpd/templates/httpd.conf.j2 b/roles/httpd/templates/httpd.conf.j2 index a39f46f..8a772e9 100644 --- a/roles/httpd/templates/httpd.conf.j2 +++ b/roles/httpd/templates/httpd.conf.j2 @@ -23,7 +23,7 @@ server "default" { } location * { - block return 302 "https://\$HTTP_HOST\$REQUEST_URI" + block return 302 "https://$HTTP_HOST$REQUEST_URI" } } {% endif %} diff --git a/roles/httpd_pre/tasks/main.yml b/roles/httpd_pre/tasks/main.yml index eb0af76..025b9d7 100644 --- a/roles/httpd_pre/tasks/main.yml +++ b/roles/httpd_pre/tasks/main.yml @@ -1,8 +1,5 @@ - -# httpd ~~ roles/httpd_pre/main.yml -# prerequisites for `httpd` role - ---- +- name: include httpd role vars + include_vars: "{{ inventory_dir }}/roles/httpd/defaults/main.yml" - name: ensure httpd.d directory exists file: @@ -19,3 +16,12 @@ owner: "www" group: "www" mode: 0700 + +- name: ensure data volume is mounted in chroot + include_role: + name: nfsclient + vars: + nfsclient_dir: "/var/www/data" + nfsclient_server: "{{ global.nfs_server }}" + nfsclient_server_dir: "{{ global.nfs_server_dir }}/{{ ansible_host }}" + when: httpd_use_nfs is defined and httpd_use_nfs diff --git a/roles/ldapd/defaults/main.yml b/roles/ldapd/defaults/main.yml new file mode 100644 index 0000000..3e86bfc --- /dev/null +++ b/roles/ldapd/defaults/main.yml @@ -0,0 +1,3 @@ +ldapd_user: _ldapd +ldapd_group: _ldapd +ldapd_dir: /data/ldap diff --git a/roles/ldapd/tasks/main.yml b/roles/ldapd/tasks/main.yml new file mode 100644 index 0000000..2866ba8 --- /dev/null +++ b/roles/ldapd/tasks/main.yml @@ -0,0 +1,22 @@ +- name: ensure ldapd db dir exists + file: + path: "{{ ldapd_dir }}" + owner: "{{ ldapd_user }}" + group: "{{ ldapd_group }}" + state: directory + mode: "0700" + +- name: generate ldapd configuration + template: + src: etc-ldapd.conf.j2 + dest: /etc/ldapd.conf + owner: "0" + group: "0" + mode: "0600" + +- name: enable and start ldapd + service: + name: ldapd + state: restarted + enabled: true + args: -r "{{ ldapd_dir }}" diff --git a/roles/ldapd/templates/etc-ldapd.conf.j2 b/roles/ldapd/templates/etc-ldapd.conf.j2 new file mode 100644 index 0000000..e08fa9c --- /dev/null +++ b/roles/ldapd/templates/etc-ldapd.conf.j2 @@ -0,0 +1,23 @@ + +# ldapd configuration +# manage by Ansible + +schema "/etc/ldap/core.schema" +schema "/etc/ldap/inetorgperson.schema" +schema "/etc/ldap/nis.schema" +schema "/etc/ldap/bsd.schema" + +{% for interface in ansible_interfaces %} +{% if "pflog" not in interface %} +listen on {{ interface }} +{% endif %} +{% endfor %} +listen on "/var/run/ldapi" + +namespace "dc=domain" { + rootdn "cn=admin,dc=domain" + + deny read,write access to subtree root by any + allow read,write access to subtree root by self + +} diff --git a/roles/loki/tasks/main.yml b/roles/loki/tasks/main.yml new file mode 100644 index 0000000..456cd83 --- /dev/null +++ b/roles/loki/tasks/main.yml @@ -0,0 +1,10 @@ +- name: ensure loki is installed + package: + name: loki + state: present + +- name: ensure loki service is enabled and restarted + service: + name: loki + state: restarted + enabled: true diff --git a/roles/miniflux/meta/main.yml b/roles/miniflux/meta/main.yml index ca4e7dd..3ffef7b 100644 --- a/roles/miniflux/meta/main.yml +++ b/roles/miniflux/meta/main.yml @@ -1,8 +1,3 @@ - -# miniflux ~~ roles/miniflux/meta/main.yml -# Meta parameters - ---- - dependencies: - - { role: postgres, tags: "dependency" } + - role: postgres + tags: dependency diff --git a/roles/miniflux/tasks/main.yml b/roles/miniflux/tasks/main.yml index 95c5d92..ba90164 100644 --- a/roles/miniflux/tasks/main.yml +++ b/roles/miniflux/tasks/main.yml @@ -9,22 +9,26 @@ name: miniflux state: present -- name: ensure miniflux db user exists - shell: | - createuser -U postgres miniflux - register: result - failed_when: result.rc != 0 and "already exists" not in result.stderr - -- name: ensure miniflux database exists - shell: | - createdb -U postgres -O miniflux miniflux - createdb -U postgres -O miniflux miniflux2 - register: result - failed_when: result.rc != 0 and "already exists" not in result.stderr - -- name: ensure miniflux db user exists - shell: | - psql -U postgres miniflux -c "create extension hstore" +- name: include postgres user + include_role: + name: postgres + tasks_from: create_user + vars: + postgres_db_user: "{{ miniflux_db_user }}" + +- name: include postgres db + include_role: + name: postgres + tasks_from: create_db + vars: + postgres_db_user: "{{ miniflux_db_user }}" + postgres_db_name: "{{ miniflux_db_name}}{{ item }}" + loop: + - "" + - 2 + +- name: ensure hstore extension for db + shell: psql -U postgres miniflux -c "create extension hstore" register: result failed_when: result.rc != 0 and "already exists" not in result.stderr diff --git a/roles/miniflux/vars/main.yml b/roles/miniflux/vars/main.yml index 13e634c..37f2a45 100644 --- a/roles/miniflux/vars/main.yml +++ b/roles/miniflux/vars/main.yml @@ -6,6 +6,8 @@ miniflux_user: "_miniflux" miniflux_group: "_miniflux" +miniflux_db_user: "miniflux" +miniflux_db_name: "miniflux" miniflux_listenaddr: "0.0.0.0" miniflux_port: "8010" diff --git a/roles/nfsclient/defaults/main.yml b/roles/nfsclient/defaults/main.yml index c1a8e13..2c019c9 100644 --- a/roles/nfsclient/defaults/main.yml +++ b/roles/nfsclient/defaults/main.yml @@ -5,3 +5,6 @@ nfsclient_dir: "/data" nfsclient_test_dir: "/tmp/nfsd-test" + +nfsclient_server: "{{ global.nfs_server }}" +nfsclient_server_dir: "{{ global.nfs_server_dir }}" diff --git a/roles/nfsclient/tasks/main.yml b/roles/nfsclient/tasks/main.yml index 879ed9e..79caf84 100644 --- a/roles/nfsclient/tasks/main.yml +++ b/roles/nfsclient/tasks/main.yml @@ -4,19 +4,9 @@ --- -- name: fallback to default nfs server +- name: translate server string to server dict set_fact: - nfsclient_server: "{{ global.nfs_server }}" - when: nfsclient_server is not defined - -- name: fallback default nfs server directory - set_fact: - nfsclient_server_dir: "{{ global.nfs_server_dir }}" - when: nfsclient_server_dir is not defined - -- name: translate server string to server dict if not - set_fact: - nfsclient_server: "{{ hostvars[nfsclient_server] }}" + nfsclient_server_: "{{ hostvars[nfsclient_server] }}" - name: include distribution specific prerequisites include_tasks: "_{{ ansible_distribution | lower }}.yml" @@ -29,9 +19,9 @@ group: "0" mode: "755" state: directory - delegate_to: "{{ nfsclient_server.ansible_host }}" + delegate_to: "{{ nfsclient_server_.ansible_host }}" -- name: ensure directory exists on local machine +- name: ensure directory exists on client file: path: "{{ nfsclient_dir }}" owner: "0" @@ -43,45 +33,25 @@ - result.failed - '"Errno 17" not in result.msg' -- name: ensure tmp directory exists for testing nfsd - file: - path: "{{ nfsclient_test_dir }}" - owner: "0" - group: "0" - mode: "0700" - state: directory - -- name: test nfs setup - shell: mount -t nfs "{{ nfsclient_server.ip.out }}:{{ nfsclient_server_dir }}" /tmp/nfsd-test - - name: cleanup fstab with previous nfs setup lineinfile: path: /etc/fstab regexp: ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:/.* {{ nfsclient_dir }} nfs state: absent + register: result - name: complete fstab with nfs lineinfile: path: /etc/fstab - line: "{{ nfsclient_server.ip.out }}:{{ nfsclient_server_dir }} {{ nfsclient_dir }} nfs rw,nodev,nosuid 0 0" + line: "{{ nfsclient_server_.ip.out }}:{{ nfsclient_server_dir }} {{ nfsclient_dir }} nfs rw,nodev,nosuid 0 0" - name: reload fstab - shell: | - umount -af -t nfs - mount -a + shell: mount -a ignore_errors: true -- name: remove nfs test directory - file: - path: "{{ nfsclient_test_dir }}" - state: absent - -- name: register mounted volumes - shell: df -P | grep nfs - register: out +- name: reload facts + setup: - name: display mounted volumes debug: - msg: | - {{ out.stdout_lines }} - {{ out.stderr_lines }} + var: ansible_mounts diff --git a/roles/nfsd/defaults/main.yml b/roles/nfsd/defaults/main.yml index d116b22..618b721 100644 --- a/roles/nfsd/defaults/main.yml +++ b/roles/nfsd/defaults/main.yml @@ -4,11 +4,6 @@ --- nfsd_dir: "/data/nfs" -nfsd_dirs: "undefined" +nfsd_dirs: null nfsd_config: "/etc/exports" nfsd_nb_process: 10 - -nfsd_user: nfsu -nfsd_user_id: 2000 -nfsd_group: nfsu -nfsd_group_id: 2000 diff --git a/roles/nfsd/tasks/main.yml b/roles/nfsd/tasks/main.yml index 7da9240..71e9b55 100644 --- a/roles/nfsd/tasks/main.yml +++ b/roles/nfsd/tasks/main.yml @@ -4,29 +4,9 @@ --- -- debug: - var: nfsd_dirs - - name: ensure nfsd required variables are set fail: - when: item == "undefined" - loop: - - "{{ nfsd_dirs }}" - -- name: ensure nfs shared group exists - group: - name: "{{ nfsd_group }}" - gid: "{{ nfsd_group_id }}" - system: true - state: absent - -- name: ensure nfs shared user exists - user: - name: "{{ nfsd_user }}" - uid: "{{ nfsd_user_id }}" - group: "{{ nfsd_group }}" - system: true - state: absent + when: nsfd_dirs is none - name: ensure nfsd directory exists file: diff --git a/roles/nfsd/templates/etc-exports.j2 b/roles/nfsd/templates/etc-exports.j2 index 2fdbf21..545846f 100644 --- a/roles/nfsd/templates/etc-exports.j2 +++ b/roles/nfsd/templates/etc-exports.j2 @@ -4,5 +4,5 @@ {% for host in groups["servers"] %} {% set host = dict(hostvars[host]) %} -/data/nfs/{{ host.ansible_host }} -maproot=0:0 -alldirs {{ host.ip.in if host.ip.in is defined }} {{ host.ip.out if host.ip.out is defined }} +/data/nfs/{{ host.ansible_host }} -maproot=root {{ host.ip.in if host.ip.in is defined }} {{ host.ip.out if host.ip.out is defined }} {% endfor %} diff --git a/roles/pf/templates/pf.conf.j2 b/roles/pf/templates/pf.conf.j2 index 154098e..199d9ca 100644 --- a/roles/pf/templates/pf.conf.j2 +++ b/roles/pf/templates/pf.conf.j2 @@ -6,7 +6,7 @@ # common configuration set block-policy drop set loginterface egress -set skip on { lo tun0 } +set skip on { lo wg0 } block all # host services @@ -34,7 +34,7 @@ set skip on tap{{ i }} # wireguard pass in on egress inet proto udp from any to any port 50000 -pass out quick on egress inet from (tun0:network) nat-to (egress:0) +pass out quick on egress inet from (wg0:network) nat-to (egress:0) # output network pass out quick inet diff --git a/roles/postgres/defaults/main.yml b/roles/postgres/defaults/main.yml new file mode 100644 index 0000000..b0c52df --- /dev/null +++ b/roles/postgres/defaults/main.yml @@ -0,0 +1,5 @@ +postgres_dir: /data/postgresql +postgres_default_dir: /var/postgresql +postgres_user: _postgresql +postgres_group: _postgresql +postgres_dbuser: postgres diff --git a/roles/postgres/tasks/create_db.yml b/roles/postgres/tasks/create_db.yml new file mode 100644 index 0000000..9adb6ee --- /dev/null +++ b/roles/postgres/tasks/create_db.yml @@ -0,0 +1,4 @@ +- name: ensure miniflux database exists + shell: createdb -U postgres -O "{{ postgres_db_user }}" "{{ postgres_db_name }}" + register: result + failed_when: result.rc != 0 and "already exists" not in result.stderr diff --git a/roles/postgres/tasks/create_user.yml b/roles/postgres/tasks/create_user.yml new file mode 100644 index 0000000..123070d --- /dev/null +++ b/roles/postgres/tasks/create_user.yml @@ -0,0 +1,4 @@ +- name: ensure miniflux db user exists + shell: createuser -U postgres "{{ postgres_db_user }}" + register: result + failed_when: result.rc != 0 and "already exists" not in result.stderr diff --git a/roles/postgres/tasks/main.yml b/roles/postgres/tasks/main.yml index 16fce30..80d7aad 100644 --- a/roles/postgres/tasks/main.yml +++ b/roles/postgres/tasks/main.yml @@ -4,34 +4,14 @@ --- -- name: ensure postgres is installed for OpenBSD +- name: ensure postgres is installed package: name: "{{ item }}" state: present - when: ansible_distribution == "OpenBSD" loop: - "postgresql-server" - "postgresql-contrib" -- name: ensure postgres is installed - package: name=postgresql state=present - ignore_errors: true - when: ansible_distribution != "OpenBSD" - -- name: ensure postgres group exists - group: name="{{ postgres_group }}" state=present - -- name: ensure postgres user exists - user: - name: "{{ postgres_user }}" - group: "{{ postgres_group }}" - system: true - state: present - -- name: delete default data dir if exists - file: path=/var/postgresql state=absent - when: postgres_dir != "/var/postgresql" - - name: ensure postgres directories exists file: path: "{{ postgres_dir }}/{{ item }}" @@ -43,10 +23,16 @@ - "" - "data" +- name: delete default data dir if exists + file: + path: "{{ postgres_default_dir }}" + state: absent + when: postgres_dir != "/var/postgresql" + - name: link postgres directory to default one file: src: "{{ postgres_dir }}" - dest: "/var/postgresql" + dest: "{{ postgres_default_dir }}" owner: "{{ postgres_user }}" group: "{{ postgres_group }}" state: link @@ -57,7 +43,6 @@ # NOTE: this tasks needs `pipelining` set to `false` to work correctly - name: init postgres database shell: | - initdb -D "{{ postgres_dir }}/data/" -U "{{ postgres_dbuser }}" --encoding=UTF-8 --locale=en_US.UTF-8 {# --auth=scram-sha-256 --pwprompt #} su - _postgresql -c \ 'initdb -D "{{ postgres_dir }}/data/" -U "{{ postgres_dbuser }}" \ --encoding=UTF-8 \ diff --git a/roles/postgres/vars/main.yml b/roles/postgres/vars/main.yml deleted file mode 100644 index 55d977b..0000000 --- a/roles/postgres/vars/main.yml +++ /dev/null @@ -1,10 +0,0 @@ - -# postgres ~~ roles/postgres/tasks/main.yml -# postgres variables - ---- - -postgres_dir: /data/postgres -postgres_user: _postgresql -postgres_group: _postgresql -postgres_dbuser: postgres diff --git a/roles/repositories/vars/main.yml b/roles/repositories/defaults/main.yml index 8218b7d..8218b7d 100644 --- a/roles/repositories/vars/main.yml +++ b/roles/repositories/defaults/main.yml diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml index 61bbcb7..b34d783 100644 --- a/roles/sshd/tasks/main.yml +++ b/roles/sshd/tasks/main.yml @@ -12,74 +12,8 @@ group: "0" mode: "0644" -- name: retrieve all existing users - shell: cut -d ":" -f 1 /etc/passwd - register: sshd_users - changed_when: false - -- name: bind retrieved users output lines to list - set_fact: - sshd_users: "{{ sshd_users.stdout_lines }}" - -- name: get ssh keys for all user - find: - paths: "{{ inventory_dir }}/files/pubkeys" - pattern: "*.pub" - recurse: true - file_type: link - register: keys - delegate_to: localhost - -- name: show pubkeys - debug: - msg: | - {% for key in keys.files %} - {{ key.path }} - {% endfor %} - run_once: true - delegate_to: localhost - -- name: synchronize ssh keys - authorized_key: - user: "{{ item.path | dirname | basename }}" - state: present - key: "{{ lookup('file', item.path) }}" - when: item.path | dirname | basename in sshd_users - loop: "{{ keys.files }}" - loop_control: - label: "{{ item.path }}" - -- name: get users homedir - shell: echo $(getent passwd "{{ item.path | dirname | basename }}" | cut -d ":" -f 6) "{{ item.path | dirname | basename }}" - register: sshd_homedirs - when: item.path | dirname | basename in sshd_users - loop: "{{ keys.files }}" - changed_when: false - loop_control: - label: "{{ item.path | dirname | basename }}" - -- name: clean users homedir result - set_fact: - sshd_homedirs: "[{% for dir in sshd_homedirs.results if dir.stdout is defined %}\"{{ dir.stdout }}\", {% endfor %}]" - -- name: make users homedir unique - set_fact: - sshd_homedirs: "{{ sshd_homedirs | unique }}" - -- name: show sshd homedirs for users - debug: - var: sshd_homedirs - -- name: chown ssh file to correct user - file: - path: "{{ item.split(' ')[0] }}/.ssh/authorized_keys" - owner: "{{ item.split(' ')[1] }}" - mode: "0600" - ignore_errors: true - when: item.split(" ")[1] in sshd_users - loop: "{{ sshd_homedirs }}" - loop_control: - label: "{{ item }}" +- name: synchronize keys + include_tasks: sync_keys.yml - name: restart sshd service: diff --git a/roles/sshd/tasks/sync_keys.yml b/roles/sshd/tasks/sync_keys.yml new file mode 100644 index 0000000..73aa741 --- /dev/null +++ b/roles/sshd/tasks/sync_keys.yml @@ -0,0 +1,68 @@ +- name: retrieve all existing users + shell: cut -d ":" -f 1 /etc/passwd + register: sshd_users + changed_when: false + +- name: bind retrieved users output lines to list + set_fact: + sshd_users: "{{ sshd_users.stdout_lines }}" + +- name: get ssh keys for all user + find: + paths: "{{ inventory_dir }}/files/pubkeys" + pattern: "*.pub" + recurse: true + file_type: link + register: keys + delegate_to: localhost + +- name: show pubkeys + debug: + msg: | + {% for key in keys.files %} + {{ key.path }} + {% endfor %} + run_once: true + delegate_to: localhost + +- name: synchronize ssh keys + authorized_key: + user: "{{ item.path | dirname | basename }}" + state: present + key: "{{ lookup('file', item.path) }}" + when: item.path | dirname | basename in sshd_users + loop: "{{ keys.files }}" + loop_control: + label: "{{ item.path }}" + +- name: get users homedir + shell: echo $(getent passwd "{{ item.path | dirname | basename }}" | cut -d ":" -f 6) "{{ item.path | dirname | basename }}" + register: sshd_homedirs + when: item.path | dirname | basename in sshd_users + loop: "{{ keys.files }}" + changed_when: false + loop_control: + label: "{{ item.path | dirname | basename }}" + +- name: clean users homedir result + set_fact: + sshd_homedirs: "[{% for dir in sshd_homedirs.results if dir.stdout is defined %}\"{{ dir.stdout }}\", {% endfor %}]" + +- name: make users homedir unique + set_fact: + sshd_homedirs: "{{ sshd_homedirs | unique }}" + +- name: show sshd homedirs for users + debug: + var: sshd_homedirs + +- name: chown ssh file to correct user + file: + path: "{{ item.split(' ')[0] }}/.ssh/authorized_keys" + owner: "{{ item.split(' ')[1] }}" + mode: "0600" + ignore_errors: true + when: item.split(" ")[1] in sshd_users + loop: "{{ sshd_homedirs }}" + loop_control: + label: "{{ item }}" diff --git a/roles/_workstation/sshdns/defaults/main.yml b/roles/sshdns/defaults/main.yml index 9427f1d..9120a10 100644 --- a/roles/_workstation/sshdns/defaults/main.yml +++ b/roles/sshdns/defaults/main.yml @@ -1,3 +1 @@ ---- - sshdns_waittime: 2 diff --git a/roles/sshdns/tasks/main.yml b/roles/sshdns/tasks/main.yml new file mode 100644 index 0000000..f62c706 --- /dev/null +++ b/roles/sshdns/tasks/main.yml @@ -0,0 +1,25 @@ +--- + +- name: get current user + shell: whoami + register: result + +- name: set current user + set_fact: + sshdns_user: '{{ result.stdout_lines[0] }}' + +- name: create config directory + file: + path: '/home/{{ sshdns_user }}/.ssh/config.d' + state: directory + group: '{{ sshdns_user }}' + owner: '{{ sshdns_user }}' + mode: '0700' + +- name: generate template to localhost + template: + src: templates/sshdns.j2 + dest: '/home/{{ sshdns_user }}//.ssh/config.d/ssh_dns' + owner: '{{ sshdns_user }}' + group: '{{ sshdns_user }}' + mode: '0600' diff --git a/roles/_workstation/sshdns/templates/sshdns.j2 b/roles/sshdns/templates/sshdns.j2 index 1778215..1778215 100644 --- a/roles/_workstation/sshdns/templates/sshdns.j2 +++ b/roles/sshdns/templates/sshdns.j2 diff --git a/roles/tools/vars/main.yml b/roles/tools/defaults/main.yml index 8eca476..8eca476 100644 --- a/roles/tools/vars/main.yml +++ b/roles/tools/defaults/main.yml diff --git a/roles/wireguard/tasks/main.yml b/roles/wireguard/tasks/main.yml index 5b48998..3b8f8ae 100644 --- a/roles/wireguard/tasks/main.yml +++ b/roles/wireguard/tasks/main.yml @@ -15,35 +15,14 @@ wg_host_conf: "{{ wg_dir }}/{{ ansible_host }}.conf" wg_host_keys: "{{ wg_dir }}/{{ ansible_host }}.keys" -- name: include configuration generation +- name: include generation configuratin include_tasks: generate.yml -- name: include configuration synchronization +- name: include synchronization configuration include_tasks: synchronize.yml -- name: enable wireguard for freebsd - lineinfile: - path: /etc/rc.conf - regexp: "^wireguard_enable" - line: wireguard_enable="YES" - when: ansible_distribution == "FreeBSD" - -- name: enable interface for freebsd - lineinfile: - path: /etc/rc.conf - regexp: "^wireguard_interfaces" - line: wireguard_interfaces="{{ global.dcontroller }}" - when: ansible_distribution == "FreeBSd" - -- name: generate and enable init script - include_role: name=rc - vars: - rc_cmd: "{{ path_wgquick }}" - rc_args: "up {{ global.dcontroller }}" - rc_name: wireguard - rc_user: "{{ user_root }}" - ignore_errors: true - when: ansible_distribution != "FreeBSD" +- name: include service configuration + include_tasks: service.yml - name: include server setup include_tasks: server.yml diff --git a/roles/wireguard/tasks/server.yml b/roles/wireguard/tasks/server.yml index 32d52fc..9a8d67c 100644 --- a/roles/wireguard/tasks/server.yml +++ b/roles/wireguard/tasks/server.yml @@ -12,27 +12,13 @@ when: ansible_host == global.dcontroller delegate_to: localhost -- name: generate server interface - template: - src: templates/hostname.j2 - dest: /etc/hostname.tun0 +- name: enable wireguard interface + lineinfile: + path: /etc/rc.local + regexp: "^wg-quick up {{ ansible_host }}$" + line: "wg-quick up {{ ansible_host }}" -# NOTE: interface destruction and creation exists in the same tasks, -# to avoid being kicked out of the ssh sessions if this one exists -# within the current VPN. - name: restart wireguard interface shell: | - ifconfig tun0 destroy - sleep 2 - sh /etc/netstart tun0 - register: result - -- name: show debug output - debug: - msg: | - {% for line in result.stdout_lines %} - "{{ line }}" - {% endfor %} - {% for line in result.stderr_lines %} - "{{ line }}" - {% endfor %} + wg-quick down "{{ ansible_host }}" + wg-quick up "{{ ansible_host }}" diff --git a/roles/wireguard/tasks/service.yml b/roles/wireguard/tasks/service.yml new file mode 100644 index 0000000..86d6420 --- /dev/null +++ b/roles/wireguard/tasks/service.yml @@ -0,0 +1,17 @@ +- name: enable wireguard for FreeBSD + service: + name: wireguard + state: restarted + enabled: true + args: "{{ global.dcontroller }}" + when: ansible_distribution == "FreeBSD" + +- name: generate and enable init script + include_role: name=rc + vars: + rc_cmd: "{{ path_wgquick }}" + rc_args: "up {{ global.dcontroller }}" + rc_name: wireguard + rc_user: "{{ user_root }}" + ignore_errors: true + when: ansible_distribution != "FreeBSD" diff --git a/roles/wireguard/templates/dcontroller.conf.j2 b/roles/wireguard/templates/dcontroller.conf.j2 index a8e6292..75da219 100644 --- a/roles/wireguard/templates/dcontroller.conf.j2 +++ b/roles/wireguard/templates/dcontroller.conf.j2 @@ -4,7 +4,7 @@ {% set dcontroller_keys = lookup("file", wg_dcontroller_keys).splitlines() %} [Interface] -#Address = {{ ip.in }}, fd00::1/128 +Address = {{ ip.in }}/24, fd00::1/128 ListenPort = 53 PrivateKey = {{ dcontroller_keys[0] }} diff --git a/roles/wireguard/templates/hostname.j2 b/roles/wireguard/templates/hostname.j2 index 8938320..aca3b03 100644 --- a/roles/wireguard/templates/hostname.j2 +++ b/roles/wireguard/templates/hostname.j2 @@ -1,7 +1,6 @@ inet 10.10.0.1 255.255.255.0 inet6 fd00:10:10::1 -!/usr/local/bin/wireguard-go -f tun0 & -!/bin/sleep 2 +#!/usr/local/bin/wireguard-go -f tun0 & !/usr/local/bin/wg setconf tun0 /etc/wireguard/{{ global.dcontroller }}.conf !/bin/sleep 2 !/sbin/route add -inet 10.10.0.0/24 10.10.0.1 |