diff options
Diffstat (limited to 'ansible/roles')
26 files changed, 528 insertions, 0 deletions
diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml new file mode 100644 index 0000000..ecf3e88 --- /dev/null +++ b/ansible/roles/common/tasks/main.yml @@ -0,0 +1,44 @@ +- name: "Check that host runs Debian buster/sid on armv7l or x86_64" + assert: + that: + - "ansible_architecture == 'aarch64' or ansible_architecture == 'armv7l' or ansible_architecture == 'x86_64'" + - "ansible_os_family == 'Debian'" + - "ansible_distribution_version == 'buster/sid'" + +- name: "Upgrade system" + apt: + upgrade: dist # Should we do a full uprade instead of a dist one? + update_cache: yes + cache_valid_time: 3600 + autoclean: yes + autoremove: yes + +- name: "Install base tools" + apt: + name: + - vim + - htop + - screen + - iptables + - iptables-persistent + - nftables + - iproute2 + - curl + - iputils-ping + - dnsutils + - bmon + - iftop + - iotop + - docker.io + - unzip + - tar + - tcpdump + - less + - parted + - btrfs-tools + - systemd-timesyncd + - systemd-resolved + - libnss-resolve + - net-tools + - strace + state: present diff --git a/ansible/roles/consul/files/consul.service b/ansible/roles/consul/files/consul.service new file mode 100644 index 0000000..3993567 --- /dev/null +++ b/ansible/roles/consul/files/consul.service @@ -0,0 +1,8 @@ +[Unit] +Description=Consul + +[Service] +ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/consul/handlers/main.yml b/ansible/roles/consul/handlers/main.yml new file mode 100644 index 0000000..e8cd4a4 --- /dev/null +++ b/ansible/roles/consul/handlers/main.yml @@ -0,0 +1,4 @@ +--- + +- name: restart consul + service: name=consul state=restarted diff --git a/ansible/roles/consul/tasks/main.yml b/ansible/roles/consul/tasks/main.yml new file mode 100644 index 0000000..a943022 --- /dev/null +++ b/ansible/roles/consul/tasks/main.yml @@ -0,0 +1,49 @@ +- name: "Set consul version" + set_fact: + consul_version: 1.4.0 + +- name: "Download and install Consul for armv7l" + unarchive: + src: "https://releases.hashicorp.com/consul/{{ consul_version }}/consul_{{ consul_version }}_linux_arm.zip" + dest: /usr/local/bin + remote_src: yes + when: + - "ansible_architecture == 'armv7l'" + notify: + - restart consul + +- name: "Download and install Consul for x86_64" + unarchive: + src: "https://releases.hashicorp.com/consul/{{ consul_version }}/consul_{{ consul_version }}_linux_amd64.zip" + dest: /usr/local/bin + remote_src: yes + when: + - "ansible_architecture == 'x86_64'" + notify: + - restart consul + +- name: "Download and install Consul for arm64" + unarchive: + src: "https://releases.hashicorp.com/consul/{{ consul_version }}/consul_{{ consul_version }}_linux_arm64.zip" + dest: /usr/local/bin + remote_src: yes + when: + - "ansible_architecture == 'aarch64'" + notify: + - restart consul + +- name: "Create consul configuration directory" + file: path=/etc/consul/ state=directory + +- name: "Deploy consul configuration" + template: src=consul.json.j2 dest=/etc/consul/consul.json + notify: + - restart consul + +- name: "Deploy consul systemd service" + copy: src=consul.service dest=/etc/systemd/system/consul.service + notify: + - restart consul + +- name: "Enable consul systemd service at boot" + service: name=consul state=started enabled=yes daemon_reload=yes diff --git a/ansible/roles/consul/templates/consul.json.j2 b/ansible/roles/consul/templates/consul.json.j2 new file mode 100644 index 0000000..d1bd2d8 --- /dev/null +++ b/ansible/roles/consul/templates/consul.json.j2 @@ -0,0 +1,27 @@ +{ + "data_dir": "/var/lib/consul", + "bind_addr": "0.0.0.0", + "advertise_addr": "{{ public_ip }}", + "addresses": { + "dns": "0.0.0.0", + "http": "0.0.0.0" + }, + "retry_join": [ + {% for selected_host in groups['cluster_nodes']|reject("sameas", ansible_fqdn) %}{# @FIXME: Reject doesn't work #} + "{{ hostvars[selected_host]['private_ip'] }}" {{ "," if not loop.last else "" }} + {% endfor %} + ], + "bootstrap_expect": 3, + "server": true, + "ui": true, + "ports": { + "dns": 53 + }, + "encrypt": "{{ consul_gossip_encrypt }}", + "domain": "2.cluster.deuxfleurs.fr", + "performance": { + "raft_multiplier": 10, + "rpc_hold_timeout": "30s", + "leave_drain_time": "30s" + } +} diff --git a/ansible/roles/consul/vars/.gitignore b/ansible/roles/consul/vars/.gitignore new file mode 100644 index 0000000..ff5c0bd --- /dev/null +++ b/ansible/roles/consul/vars/.gitignore @@ -0,0 +1 @@ +main.yml diff --git a/ansible/roles/consul/vars/main.yml.sample b/ansible/roles/consul/vars/main.yml.sample new file mode 100644 index 0000000..9c44126 --- /dev/null +++ b/ansible/roles/consul/vars/main.yml.sample @@ -0,0 +1,2 @@ +--- +consul_gossip_encrypt: "<secret>" diff --git a/ansible/roles/network/files/nsswitch.conf b/ansible/roles/network/files/nsswitch.conf new file mode 100644 index 0000000..f4c3149 --- /dev/null +++ b/ansible/roles/network/files/nsswitch.conf @@ -0,0 +1,22 @@ +# /etc/nsswitch.conf +# +# Example configuration of GNU Name Service Switch functionality. +# If you have the `glibc-doc-reference' and `info' packages installed, try: +# `info libc "Name Service Switch"' for information about this file. + +passwd: files systemd +group: files systemd +shadow: files +gshadow: files + +#hosts: files dns +hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname +networks: files + +protocols: db files +services: db files +ethers: db files +rpc: db files + +netgroup: nis + diff --git a/ansible/roles/network/files/rules.v6 b/ansible/roles/network/files/rules.v6 new file mode 100644 index 0000000..0f402bd --- /dev/null +++ b/ansible/roles/network/files/rules.v6 @@ -0,0 +1,6 @@ +*filter +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +:OUTPUT ACCEPT [0:0] +COMMIT + diff --git a/ansible/roles/network/files/systemd-resolve-no-listen.conf b/ansible/roles/network/files/systemd-resolve-no-listen.conf new file mode 100644 index 0000000..6e95967 --- /dev/null +++ b/ansible/roles/network/files/systemd-resolve-no-listen.conf @@ -0,0 +1,2 @@ +[Resolve] +DNSStubListener=no diff --git a/ansible/roles/network/handlers/main.yml b/ansible/roles/network/handlers/main.yml new file mode 100644 index 0000000..3454894 --- /dev/null +++ b/ansible/roles/network/handlers/main.yml @@ -0,0 +1,12 @@ +--- +- name: reload iptables + shell: iptables-restore < /etc/iptables/rules.v4 && systemctl restart docker && ifdown nomad1 || true && ifup nomad1 || true + +- name: reload ip6tables + shell: ip6tables-restore < /etc/iptables/rules.v6 + +- name: reload nomad interface + shell: ifdown nomad1 || true ; ifup nomad1 + +- name: reload systemd-resolved + service: name=systemd-resolved state=restarted diff --git a/ansible/roles/network/tasks/main.yml b/ansible/roles/network/tasks/main.yml new file mode 100644 index 0000000..7f95b0f --- /dev/null +++ b/ansible/roles/network/tasks/main.yml @@ -0,0 +1,42 @@ +- name: "Add dummy interface to handle Nomad NAT restriction nomad#2770" + template: src=nomad-interface.j2 dest=/etc/network/interfaces.d/nomad.cfg + when: public_ip != private_ip + notify: + - reload nomad interface + +- name: "Deploy iptablesv4 configuration" + template: src=rules.v4.j2 dest=/etc/iptables/rules.v4 + notify: + - reload iptables + +- name: "Deploy iptablesv6 configuration" + copy: src=rules.v6 dest=/etc/iptables/rules.v6 + notify: + - reload ip6tables + +- name: "Activate IP forwarding" + sysctl: + name: net.ipv4.ip_forward + value: 1 + sysctl_set: yes + +- name: "Create systemd-resolved override directory" + file: path=/etc/systemd/resolved.conf.d/ state=directory + +- name: "Prevent systemd-resolved from listening on port 53 (DNS)" + copy: src=systemd-resolve-no-listen.conf dest=/etc/systemd/resolved.conf.d/systemd-resolve-no-listen.conf + notify: reload systemd-resolved + +- name: "Use systemd-resolved as a source for /etc/resolv.conf" + file: + src: "/run/systemd/resolve/resolv.conf" + dest: "/etc/resolv.conf" + state: link + force: yes + notify: reload systemd-resolved + +- name: "Update nsswitch.conf to use systemd-resolved" + copy: src=nsswitch.conf dest=/etc/nsswitch.conf + +- name: "Flush handlers" + meta: flush_handlers diff --git a/ansible/roles/network/templates/nomad-interface.j2 b/ansible/roles/network/templates/nomad-interface.j2 new file mode 100644 index 0000000..74e9cd4 --- /dev/null +++ b/ansible/roles/network/templates/nomad-interface.j2 @@ -0,0 +1,8 @@ +auto nomad1 +iface nomad1 inet manual + pre-up /sbin/ip link add nomad1 type dummy + up /sbin/ip addr add {{ public_ip }} dev nomad1 + up /sbin/iptables -t nat -A PREROUTING -d {{ private_ip }}/32 -j NETMAP --to {{ public_ip }}/32 + down /sbin/iptables -t nat -D PREROUTING -d {{ private_ip }}/32 -j NETMAP --to {{ public_ip }}/32 + post-down /sbin/ip link del nomad1 + diff --git a/ansible/roles/network/templates/rules.v4.j2 b/ansible/roles/network/templates/rules.v4.j2 new file mode 100644 index 0000000..a77852f --- /dev/null +++ b/ansible/roles/network/templates/rules.v4.j2 @@ -0,0 +1,72 @@ + +*filter +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +:OUTPUT ACCEPT [0:0] + +# DNS +-A INPUT -p udp --dport 53 -j ACCEPT +-A INPUT -p tcp --dport 53 -j ACCEPT + +# Email +-A INPUT -p tcp --dport 993 -j ACCEPT +-A INPUT -p tcp --dport 25 -j ACCEPT +-A INPUT -p tcp --dport 465 -j ACCEPT +-A INPUT -p tcp --dport 587 -j ACCEPT + +# Old SSH configuration +-A INPUT -p tcp --dport 110 -j ACCEPT + +# New SSH configuration +-A INPUT -p tcp --dport 22 -j ACCEPT + +# LDAP +-A INPUT -p tcp --dport 389 -j ACCEPT + +# Web +-A INPUT -p tcp --dport 80 -j ACCEPT +-A INPUT -p tcp --dport 443 -j ACCEPT + +# Coturn +-A INPUT -p tcp --dport 3478 -j ACCEPT +-A INPUT -p udp --dport 3478 -j ACCEPT +-A INPUT -p tcp --dport 3479 -j ACCEPT +-A INPUT -p udp --dport 3479 -j ACCEPT + +# Cluster +{% for selected_host in groups['cluster_nodes'] %} +-A INPUT -s {{ hostvars[selected_host]['public_ip'] }} -j ACCEPT +-A INPUT -s {{ hostvars[selected_host]['private_ip'] }} -j ACCEPT +{% endfor %} + +# Rennes +-A INPUT -s 82.253.205.190 -j ACCEPT + +-A INPUT -i docker0 -j ACCEPT + +-A INPUT -s 127.0.0.1/8 -j ACCEPT + +-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + +COMMIT + + +*nat +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] + +COMMIT + + +*mangle +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] + +COMMIT + + diff --git a/ansible/roles/nomad/files/nomad.service b/ansible/roles/nomad/files/nomad.service new file mode 100644 index 0000000..cabfafc --- /dev/null +++ b/ansible/roles/nomad/files/nomad.service @@ -0,0 +1,9 @@ +[Unit] +Description=Nomad + +[Service] +ExecStart=/usr/local/bin/nomad agent -config /etc/nomad + +[Install] +WantedBy=multi-user.target + diff --git a/ansible/roles/nomad/handlers/main.yml b/ansible/roles/nomad/handlers/main.yml new file mode 100644 index 0000000..0274673 --- /dev/null +++ b/ansible/roles/nomad/handlers/main.yml @@ -0,0 +1,5 @@ +--- + +- name: restart nomad + service: name=nomad state=restarted + diff --git a/ansible/roles/nomad/tasks/main.yml b/ansible/roles/nomad/tasks/main.yml new file mode 100644 index 0000000..e6e6e10 --- /dev/null +++ b/ansible/roles/nomad/tasks/main.yml @@ -0,0 +1,49 @@ +- name: "Set nomad version" + set_fact: + nomad_version: 0.8.6 + +- name: "Download and install Nomad for armv7l" + unarchive: + src: "https://releases.hashicorp.com/nomad/{{ nomad_version }}/nomad_{{ nomad_version }}_linux_arm.zip" + dest: /usr/local/bin + remote_src: yes + when: + - "ansible_architecture == 'armv7l'" + notify: + - restart nomad + +- name: "Download and install Nomad for x86_64" + unarchive: + src: "https://releases.hashicorp.com/nomad/{{ nomad_version }}/nomad_{{ nomad_version }}_linux_amd64.zip" + dest: /usr/local/bin + remote_src: yes + when: + - "ansible_architecture == 'x86_64'" + notify: + - restart nomad + +- name: "Download and install Nomad for arm64" + unarchive: + src: "https://releases.hashicorp.com/nomad/{{ nomad_version }}/nomad_{{ nomad_version }}_linux_arm64.zip" + dest: /usr/local/bin + remote_src: yes + when: + - "ansible_architecture == 'aarch64'" + notify: + - restart nomad + +- name: "Create Nomad configuration directory" + file: path=/etc/nomad/ state=directory + +- name: "Deploy Nomad configuration" + template: src=nomad.hcl.j2 dest=/etc/nomad/nomad.hcl + notify: + - restart nomad + +- name: "Deploy Nomad systemd service" + copy: src=nomad.service dest=/etc/systemd/system/nomad.service + notify: + - restart nomad + +- name: "Enable Nomad systemd service at boot" + service: name=nomad state=started enabled=yes daemon_reload=yes diff --git a/ansible/roles/nomad/templates/nomad.hcl.j2 b/ansible/roles/nomad/templates/nomad.hcl.j2 new file mode 100644 index 0000000..8107410 --- /dev/null +++ b/ansible/roles/nomad/templates/nomad.hcl.j2 @@ -0,0 +1,30 @@ +addresses { + http = "0.0.0.0" + rpc = "0.0.0.0" + serf = "0.0.0.0" +} + +advertise { + http = "{{ public_ip }}" + rpc = "{{ public_ip }}" + serf = "{{ public_ip }}" +} + +data_dir = "/var/lib/nomad" + +server { + enabled = true + bootstrap_expect = 3 +} + +consul { + address="127.0.0.1:8500" +} + +client { + enabled = true + #cpu_total_compute = 4000 + servers = ["127.0.0.1:4648"] + network_interface = "{{ interface }}" +} + diff --git a/ansible/roles/storage/handlers/main.yml b/ansible/roles/storage/handlers/main.yml new file mode 100644 index 0000000..a395c93 --- /dev/null +++ b/ansible/roles/storage/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: umount gluster + shell: umount --force --lazy /mnt/glusterfs ; true diff --git a/ansible/roles/storage/tasks/main.yml b/ansible/roles/storage/tasks/main.yml new file mode 100644 index 0000000..09f3a56 --- /dev/null +++ b/ansible/roles/storage/tasks/main.yml @@ -0,0 +1,72 @@ +- name: "Add GlusterFS Repo Key" + apt_key: + url: https://download.gluster.org/pub/gluster/glusterfs/5/rsa.pub + state: present + +- name: "Add GlusterFS official repository" + apt_repository: + repo: "deb [arch=amd64] https://download.gluster.org/pub/gluster/glusterfs/5/LATEST/Debian/buster/amd64/apt buster main" + state: present + filename: gluster + +- name: "Install GlusterFS" + apt: + name: + - glusterfs-server + - glusterfs-client + state: present + +- name: "Ensure Gluster Daemon started and enabled" + service: + name: glusterd + enabled: yes + state: started + +- name: "Create directory for GlusterFS bricks" + file: path=/mnt/storage/glusterfs/brick1 recurse=yes state=directory + +- name: "Create GlusterFS volumes" + gluster_volume: + state: present + name: donnees + bricks: /mnt/storage/glusterfs/brick1/g1 + #rebalance: yes + redundancies: 1 + disperses: 3 + #replicas: 3 + force: yes + options: + client.event-threads: "8" + server.event-threads: "8" + performance.stat-prefetch: "on" + nfs.disable: "on" + features.cache-invalidation: "on" + performance.client-io-threads: "on" + config.transport: tcp + performance.quick-read: "on" + performance.io-cache: "on" + nfs.export-volumes: "off" + cluster.lookup-optimize: "on" + + cluster: "{% for selected_host in groups['cluster_nodes'] %}{{ hostvars[selected_host]['private_ip'] }}{{ ',' if not loop.last else '' }}{% endfor %}" + run_once: true + +- name: "Create mountpoint" + file: path=/mnt/glusterfs recurse=yes state=directory + +- name: "Flush handlers (umount glusterfs and restart ganesha)" + meta: flush_handlers + +- name: "Add fstab entry" + tags: gluster-fstab + mount: + path: /mnt/glusterfs + src: "{{ private_ip }}:/donnees" + fstype: glusterfs + opts: "defaults,_netdev" + state: present + +- name: Mount everything + command: mount -a + args: + warn: no diff --git a/ansible/roles/users/files/erwan-key1.pub b/ansible/roles/users/files/erwan-key1.pub new file mode 100644 index 0000000..450e79f --- /dev/null +++ b/ansible/roles/users/files/erwan-key1.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ/p26O7UY7D2y6ZshqmywNf0YD90KYWT4Z9DvpgZj3iLh9o/QL7XIYT/qHYPaEBXZJOdMaZRLmdxVlybKCE0KU= Arm0nius@armonius diff --git a/ansible/roles/users/files/quentin-key1.pub b/ansible/roles/users/files/quentin-key1.pub new file mode 100644 index 0000000..f3667e0 --- /dev/null +++ b/ansible/roles/users/files/quentin-key1.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDT1+H08FdUSvdPpPKdcafq4+JRHvFVjfvG5Id97LAoROmFRUb/ZOMTLdNuD7FqvW0Da5CPxIMr8ZxfrFLtpGyuG7qdI030iIRZPlKpBh37epZHaV+l9F4ZwJQMIBO9cuyLPXgsyvM/s7tDtrdK1k7JTf2EVvoirrjSzBaMhAnhi7//to8zvujDtgDZzy6aby75bAaDetlYPBq2brWehtrf9yDDG9WAMYJqp//scje/WmhbRR6eSdim1HaUcWk5+4ZPt8sQJcy8iWxQ4jtgjqTvMOe5v8ZPkxJNBine/ZKoJsv7FzKem00xEH7opzktaGukyEqH0VwOwKhmBiqsX2yN quentin@dufour.io diff --git a/ansible/roles/users/files/quentin-key2.pub b/ansible/roles/users/files/quentin-key2.pub new file mode 100644 index 0000000..c1b19fd --- /dev/null +++ b/ansible/roles/users/files/quentin-key2.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBu+KUebaWwlugMC5fGbNhHc6IaQDAC6+1vMc4Ww7nVU1rs2nwI7L5qcWxOwNdhFaorZQZy/fJuCWdFbF61RCKGayBWPLZHGPsfqDuggYNEi1Qil1kpeCECfDQNjyMTK058ZBBhOWNMHBjlLWXUlRJDkRBBECY0vo4jRv22SvSaPUCAnkdJ9rbAp/kqb497PTIb2r1l1/ew8YdhINAlpYQFQezZVfkZdTKxt22n0QCjhupqjfh3gfNnbBX0z/iO+RvAOWRIZsjPFLC+jXl+n7cnu2cq1nvST5eHiYfXXeIgIwmeENLKqp+2Twr7PIdv22PnJkh6iR5kx7eTRxkNZdN quentin@deuxfleurs.fr diff --git a/ansible/roles/users/files/valentin-key1.pub b/ansible/roles/users/files/valentin-key1.pub new file mode 100644 index 0000000..26026d1 --- /dev/null +++ b/ansible/roles/users/files/valentin-key1.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLsa6M4gYCXxEnv4SY24I1Yixv9okhTlDChxr27WLsLEpKt8AX2Q456ip2o3hCe3FbyD3vnliObKsG0/QXHV7Sw= valentin@linux.home diff --git a/ansible/roles/users/tasks/main.yml b/ansible/roles/users/tasks/main.yml new file mode 100644 index 0000000..990a041 --- /dev/null +++ b/ansible/roles/users/tasks/main.yml @@ -0,0 +1,39 @@ +- name: Add users in the system + user: + name: "{{ item.username }}" + #groups: docker + shell: "{{ item.shell | default('/bin/bash') }}" + append: no + loop: "{{ active_users + | selectattr('is_admin', 'defined') + | rejectattr('is_admin') + | list + | union( active_users + | selectattr('is_admin', 'undefined') + | list )}}" + +- name: Set admin rights + user: + name: "{{ item.username }}" + groups: docker, sudo + shell: "{{ item.shell | default('/bin/bash') }}" + append: no + loop: "{{ active_users + | selectattr('is_admin', 'defined') + | selectattr('is_admin') + | list }}" + +# [V How SSH Key works] magic is done by subelements, understand the trick at: +# https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#subelements-filter +- name: Add SSH keys + authorized_key: + user: "{{ item.0.username }}" + state: present + key: "{{ lookup('file', item.1) }}" + loop: "{{ active_users | subelements('ssh_keys', skip_missing=True) }}" + +- name: Disable old users + user: + name: "{{ item }}" + state: absent + loop: "{{ disabled_users }}" diff --git a/ansible/roles/users/vars/main.yml b/ansible/roles/users/vars/main.yml new file mode 100644 index 0000000..924b62e --- /dev/null +++ b/ansible/roles/users/vars/main.yml @@ -0,0 +1,18 @@ +--- +active_users: + - username: 'quentin' + is_admin: true + ssh_keys: + - 'quentin-key1.pub' + - 'quentin-key2.pub' + + - username: 'erwan' + ssh_keys: + - 'erwan-key1.pub' + + - username: 'valentin' + ssh_keys: + - 'valentin-key1.pub' + +disabled_users: + - 'john.doe' |