diff --git a/destroy_container.yaml b/destroy_container.yaml new file mode 100644 index 0000000..5a9539f --- /dev/null +++ b/destroy_container.yaml @@ -0,0 +1,25 @@ +--- +- hosts: lilikhost + vars_prompt: + - name: container_name + prompt: 'what container should be destroyed?' + private: no + - name: confirm1 + prompt: 'are you sure you want to delete the container?' + private: no + - name: confirm2 + prompt: 'if you really are sure, enter "cthulhu" backwards' + private: no + tasks: + - block: + - name: shutdown lxc container + lxc_container: + name: "{{ container_name }}" + state: stopped + - name: clean LVM volume + command: "dd if=/dev/zero of=/dev/sysvg/vm_{{ container_name }} bs=1M count=128" + - name: delete lxc container + lxc_container: + name: "{{ container_name }}" + state: absent + when: "confirm1 == 'yes' and confirm2 == 'uhluhtc'" diff --git a/dokuwiki.yaml b/dokuwiki.yaml new file mode 100644 index 0000000..250e0f4 --- /dev/null +++ b/dokuwiki.yaml @@ -0,0 +1,17 @@ +--- +- hosts: wiki + remote_user: root + tasks: + - name: ensure that php5 is at the latest versions + apt: name={{ item }} state=latest + with-items: + - php5-cgi + - php5-gd + - name: ensure that dokuwiki is at the latest version + apt: name=dokuwiki state=latest + notify: + - restart nginx + roles: + - role: nginx + configuration_file: 'templates/dokuwiki-nginx.conf' + dest: 'dokuwiki' diff --git a/ldap_server.yaml b/ldap_server.yaml new file mode 100644 index 0000000..78cda0f --- /dev/null +++ b/ldap_server.yaml @@ -0,0 +1,10 @@ +--- +- hosts: lilikhost + roles: + - role: lxc_host + vm_name: ldap +- hosts: ldap + roles: + - role: ldap + ldap_domain: 'lilik.it' + ldap_organization: 'LILiK' diff --git a/library/json_file.py b/library/json_file.py new file mode 100644 index 0000000..b2af3d9 --- /dev/null +++ b/library/json_file.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: json_file +author: Daniele Baracchi +short_description: Manipulate json files +description: + - Manipulate json files +options: + path: + required: true + description: + - Path to the JSON file to be manipulated. + key: + required: true + description: + - Key to be checked. + value: + required: false + description: + - Value to set the key to. + state: + required: false + default: "present" + choices: [ "present", "absent" ] + description: + - Whether the key should exist or not, taking action if the state is different from what is stated. +''' + +import json +import os.path + +from ansible.module_utils.basic import * + + +class JsonFile(object): + def __init__(self, path): + self.path = path + + with open(path, 'r') as stream: + self.contents = json.load(stream) + + def has_key(self, key): + key_path = key.split('.') + + container = self.contents + + for part in key_path: + if part in container: + container = container[part] + else: + return False + + return True + + def has_pair(self, key, value): + key_path = key.split('.') + + container = self.contents + + for part in key_path: + if part in container: + container = container[part] + else: + return False + + return container == value + + def drop_key(self, key): + key_path = key.split('.') + + container = self.contents + + for part in key_path[:-1]: + container = container[part] + + del container[key_path[-1]] + + def set_key(self, key, value): + key_path = key.split('.') + + container = self.contents + + for part in key_path[:-1]: + if part not in container: + container[part] = {} + container = container[part] + + container[key_path[-1]] = value + + def serialize(self): + with open(self.path, 'w') as stream: + json.dump(self.contents, stream, indent=4) + + +def main(): + module = AnsibleModule( + argument_spec=dict( + state=dict(default='present', choices=['present', 'absent'], + type='str'), + path=dict(required=True, type='str'), + key=dict(required=True, type='str'), + value=dict(default=None, type='str') + ), + supports_check_mode=True + ) + + path = module.params.get('path') + key = module.params.get('key') + state = module.params.get('state') + + result = {} + result['path'] = path + result['key'] = key + result['state'] = state + + if not os.path.exists(path): + module.fail_json("File not found: %s" % path) + + the_file = JsonFile(path) + + if state == 'absent': + if the_file.has_key(key): + if module.check_mode: + module.exit_json(changed=True) + else: + the_file.drop_key(key) + the_file.serialize() + result['changed'] = True + elif state == 'present': + value = module.params.get('value') + result['value'] = value + + if not the_file.has_pair(key, value): + if module.check_mode: + module.exit_json(changed=True) + else: + the_file.set_key(key, value) + the_file.serialize() + result['changed'] = True + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/prepare_host.yaml b/prepare_host.yaml new file mode 100644 index 0000000..11291b6 --- /dev/null +++ b/prepare_host.yaml @@ -0,0 +1,15 @@ +--- +- hosts: vm_hosts + tasks: + - name: install lxc related packages + apt: name={{ item }} state=latest + with_items: + - lxc + - lxc-dev + - python + - python-dev + - python-pip + - name: install lxc python support + pip: name=lxc-python2 state=latest + - name: install utilities + apt: name=vim state=latest diff --git a/roles/dokuwiki/meta/main.yaml b/roles/dokuwiki/meta/main.yaml new file mode 100644 index 0000000..b6f5775 --- /dev/null +++ b/roles/dokuwiki/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - nginx diff --git a/roles/dokuwiki/tasks/main.yaml b/roles/dokuwiki/tasks/main.yaml new file mode 100644 index 0000000..fb3d9b2 --- /dev/null +++ b/roles/dokuwiki/tasks/main.yaml @@ -0,0 +1,8 @@ +--- +- name: install dokuwiki and associated packages + apt: name={{ item }} state=latest + with_items: + - php5-cgi + - php5-fpm + - php5-gd + - dokuwiki diff --git a/roles/ldap/tasks/main.yaml b/roles/ldap/tasks/main.yaml new file mode 100644 index 0000000..f7c32f8 --- /dev/null +++ b/roles/ldap/tasks/main.yaml @@ -0,0 +1,20 @@ +- name: configure OpenLDAP (domain) + debconf: + name: 'slapd' + question: 'slapd/domain' + vtype: 'string' + value: '{{ ldap_domain }}' +- name: configure OpenLDAP (organization) + debconf: + name: 'slapd' + question: 'shared/organization' + vtype: 'string' + value: '{{ ldap_organization }}' +- name: install ldap packages + apt: + name: '{{ item }}' + state: latest + install_recommends: false + with_items: + - slapd + - ldap-utils diff --git a/roles/lxc_host/defaults/main.yaml b/roles/lxc_host/defaults/main.yaml new file mode 100644 index 0000000..d0cb4f7 --- /dev/null +++ b/roles/lxc_host/defaults/main.yaml @@ -0,0 +1,4 @@ +--- +auto_start: true +container_state: started +user_ca_key: "" diff --git a/roles/lxc_host/handlers/main.yaml b/roles/lxc_host/handlers/main.yaml new file mode 100644 index 0000000..29f4d13 --- /dev/null +++ b/roles/lxc_host/handlers/main.yaml @@ -0,0 +1,5 @@ +- name: restart container + lxc_container: + name: "{{ vm_name }}" + state: restarted + when: "auto_start == true" diff --git a/roles/lxc_host/tasks/main.yaml b/roles/lxc_host/tasks/main.yaml new file mode 100644 index 0000000..98d8ea3 --- /dev/null +++ b/roles/lxc_host/tasks/main.yaml @@ -0,0 +1,41 @@ +- name: check for lxc container existance + shell: "[ -d /var/lib/lxc/{{ vm_name }} ] && echo true || echo false" + register: lxc_existance + ignore_errors: true + changed_when: false +- block: + - name: create the lxc container + lxc_container: + name: "{{ vm_name }}" + backing_store: lvm + vg_name: sysvg + lv_name: "vm_{{ vm_name }}" + fs_type: xfs + container_log: true + template: debian + template_options: --release stretch --packages "ssh python" + container_command: | + echo "ssh-rsa {{ user_ca_key }}" > /etc/ssh/user_ca.pub + echo "TrustedUserCAKeys /etc/ssh/user_ca.pub" >> /etc/ssh/sshd_config + sed -i 's/eth0 inet dhcp/eth0 inet manual/' /etc/network/interfaces + state: stopped + - name: deploy container config + template: src=config.j2 dest="/var/lib/lxc/{{ vm_name }}/config" + - name: start container + lxc_container: + name: "{{ vm_name }}" + state: started + when: auto_start|bool + when: "lxc_existance.stdout == 'false'" +- block: + - name: update container config + template: src=config.j2 dest="/var/lib/lxc/{{ vm_name }}/config" + notify: + - restart container + - name: set container running state + lxc_container: + name: "{{ vm_name }}" + state: "{{ container_state }}" + when: "lxc_existance.stdout == 'true'" +- name: "waiting for ssh on {{ vm_name }} vm to start" + wait_for: host="{{ hostvars[vm_name]['ansible_host'] }}" port=22 timeout=20 diff --git a/roles/lxc_host/templates/config.j2 b/roles/lxc_host/templates/config.j2 new file mode 100644 index 0000000..f61fc21 --- /dev/null +++ b/roles/lxc_host/templates/config.j2 @@ -0,0 +1,15 @@ +lxc.include = /usr/share/lxc/config/debian.common.conf + +lxc.utsname = {{ vm_name }} +lxc.rootfs = /dev/sysvg/vm_{{ vm_name }} + +lxc.tty = 4 +lxc.arch = amd64 + +lxc.network.type = veth +lxc.network.flags = up +lxc.network.link = br0 +lxc.network.name = eth0 +lxc.network.ipv4 = {{ hostvars[vm_name]['ansible_host'] }}/24 +lxc.network.ipv4.gateway = {{ hostvars['ext_gateway']['ansible_host'] }} +lxc.start.auto = {% if auto_start %}1{% else %}0{% endif %} diff --git a/roles/mattermost/tasks/main.yaml b/roles/mattermost/tasks/main.yaml new file mode 100644 index 0000000..44ed000 --- /dev/null +++ b/roles/mattermost/tasks/main.yaml @@ -0,0 +1,52 @@ +- name: install postgresql + apt: name={{ item }} state=latest + with_items: + - postgresql + - postgresql-contrib + - python-psycopg2 + - ca-certificates +- block: + - postgresql_db: name=mattermost + - postgresql_user: + name: mmuser + password: mmuser_password # FIXME + db: mattermost + priv: ALL + become: true + become_method: su + become_user: postgres +- name: download latest mattermost + get_url: url=https://github.com/mattermost/platform/releases/download/v2.1.0/mattermost.tar.gz dest=/opt/mattermost.tar.gz + register: new_download +- name: unpack mattermost + unarchive: src=/opt/mattermost.tar.gz dest=/opt copy=no + when: new_download.changed +- name: create mattermost data directory + file: path=/opt/mattermost/data state=directory +- name: create mattermost group + group: name=mattermost system=true +- name: create mattermost user and group + user: name=mattermost group=mattermost system=true +- name: set mattermost directory permissions + file: + path: /opt/mattermost + owner: mattermost + group: mattermost + mode: g+w + recurse: true +- name: configure mattermost (driver name) + json_file: + path: /opt/mattermost/config/config.json + key: "SqlSettings.DriverName" + value: "postgres" +- name: configure mattermost (data source) + json_file: + path: /opt/mattermost/config/config.json + key: "SqlSettings.DataSource" + value: "postgres://mmuser:mmuser_password@127.0.0.1:5432/mattermost?sslmode=disable&connect_timeout=10" +- name: install mattermost systemd unit + template: + src: mattermost.service.j2 + dest: /etc/systemd/system/mattermost.service +- name: enable mattermost service + service: name=mattermost enabled=yes state=started diff --git a/roles/mattermost/templates/mattermost.service.j2 b/roles/mattermost/templates/mattermost.service.j2 new file mode 100644 index 0000000..b3bda1d --- /dev/null +++ b/roles/mattermost/templates/mattermost.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=Mattermost +After=network.target + +[Service] +User=mattermost +ExecStart=/opt/mattermost/bin/platform +WorkingDirectory=/opt/mattermost +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx/handlers/main.yaml b/roles/nginx/handlers/main.yaml new file mode 100644 index 0000000..3f6d024 --- /dev/null +++ b/roles/nginx/handlers/main.yaml @@ -0,0 +1,10 @@ +--- +- name: restart nginx + service: name=nginx state=restarted + +- name: validate nginx configuration + command: nginx -t -c /etc/nginx/nginx.conf + changed_when: False + +- name: reload nginx + service: name=nginx state=reloaded diff --git a/roles/nginx/tasks/main.yaml b/roles/nginx/tasks/main.yaml new file mode 100644 index 0000000..1ff6bf4 --- /dev/null +++ b/roles/nginx/tasks/main.yaml @@ -0,0 +1,8 @@ +--- +- name: install nginx + apt: pkg=nginx state=latest +- name: start nginx at boot + service: name=nginx state=started enabled=yes +# - name: copy nginx configuration +# template: src={{ configuration_file }} dest=/etc/nginx/sites-available/{{ dest }} +# notify: restart nginx diff --git a/roles/nginx_proxy/meta/main.yaml b/roles/nginx_proxy/meta/main.yaml new file mode 100644 index 0000000..b6f5775 --- /dev/null +++ b/roles/nginx_proxy/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - nginx diff --git a/roles/nginx_proxy/tasks/main.yaml b/roles/nginx_proxy/tasks/main.yaml new file mode 100644 index 0000000..eda30b8 --- /dev/null +++ b/roles/nginx_proxy/tasks/main.yaml @@ -0,0 +1,15 @@ +--- +- name: upload nginx proxy configuration + template: + src: site_config.j2 + dest: "/etc/nginx/sites-available/{{ config_name }}" + notify: restart nginx +- name: disable nginx default configuration + file: path=/etc/nginx/sites-enabled/default state=absent + notify: restart nginx +- name: enable nginx proxy configuration + file: + src: "/etc/nginx/sites-available/{{ config_name }}" + dest: "/etc/nginx/sites-enabled/{{ config_name }}" + state: link + notify: restart nginx diff --git a/roles/nginx_proxy/templates/site_config.j2 b/roles/nginx_proxy/templates/site_config.j2 new file mode 100644 index 0000000..226a591 --- /dev/null +++ b/roles/nginx_proxy/templates/site_config.j2 @@ -0,0 +1,15 @@ +server { + server_name {{ server_name }}; + + location / { + client_max_body_size 50M; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Frame-Options SAMEORIGIN; + proxy_pass {{ remote_host }}; + } +} diff --git a/team_server.yaml b/team_server.yaml new file mode 100644 index 0000000..84eaaae --- /dev/null +++ b/team_server.yaml @@ -0,0 +1,12 @@ +--- +- hosts: lilikhost + roles: + - role: lxc_host + vm_name: team +- hosts: team + roles: + - role: mattermost + - role: nginx_proxy + server_name: "team.lilik.it" + config_name: "mattermost" + remote_host: "http://127.0.0.1:8065" diff --git a/wiki_server.yaml b/wiki_server.yaml new file mode 100644 index 0000000..99d84c9 --- /dev/null +++ b/wiki_server.yaml @@ -0,0 +1,8 @@ +--- +- hosts: lilikhost + roles: + - role: lxc_host + vm_name: wiki +- hosts: wiki + roles: + - role: dokuwiki