diff --git a/inventory.yaml b/inventory.yaml index 276af33..e4d9e77 100644 --- a/inventory.yaml +++ b/inventory.yaml @@ -42,6 +42,7 @@ en1: vars: skylab_targets: [cluster, datastore] skylab_compose_version: 3.8 + skylab_compose_dir: "{{ skylab_state_dir }}/compose" hosts: pegasus: # jupiter diff --git a/playbooks/deploy.yaml b/playbooks/deploy.yaml new file mode 100644 index 0000000..86c338a --- /dev/null +++ b/playbooks/deploy.yaml @@ -0,0 +1,145 @@ +--- +- name: Bootstrap remote ansible environment + hosts: linux + tags: + - always + tasks: + - include_tasks: tasks/meta/bootstrap-remote-env.yaml + + +- name: Clean up old orechestration data + hosts: cluster + gather_facts: false + vars_files: + - vars/services.yaml + - vars/access.yaml + tasks: + - name: Create compose storage directory + become: true + ansible.builtin.file: + path: "{{ skylab_compose_dir }}" + state: directory + owner: "{{ ansible_user }}" + group: "{{ skylab_group_admin.name }}" + mode: 0770 + + - name: Fetch existing compose files + ansible.builtin.command: + cmd: /usr/bin/ls {{ skylab_compose_dir }} + changed_when: false + register: _compose_contents_raw + + - name: Remove legacy compose files + when: item.replace('.yaml', '') not in skylab_services + ansible.builtin.file: + path: "{{ skylab_compose_dir }}/{{ item }}" + state: absent + loop: "{{ _compose_contents_raw.stdout_lines }}" + + - name: Fetch existing stacks + vars: + ansible_python_interpreter: "{{ skylab_ansible_venv }}/bin/python" + community.docker.docker_stack_info: {} + register: _stack_info + + - name: Remove legacy stacks + vars: + ansible_python_interpreter: "{{ skylab_ansible_venv }}/bin/python" + when: item.Orchestrator == 'Swarm' and item.Name not in skylab_services + community.docker.docker_stack: + name: "{{ item.Name }}" + state: absent + loop: "{{ _stack_info.results }}" + loop_control: + label: "{{ item.Name }}" + + +- name: Deploy stack service{{ (' ' + service) if service is defined else 's' }} + hosts: cluster + gather_facts: false + vars: + local_datastore_mount: /mnt/datastore + vars_files: + - vars/access.yaml + - vars/services.yaml + tasks: + - name: Validate user input + when: service is defined + ansible.builtin.assert: + that: + - service in skylab_services + + - name: Determine service stacks to deploy + ansible.builtin.set_fact: + _services: "{{ {service: skylab_services[service]} if service is defined else skylab_services }}" + + - name: Determine app account mapping + vars: + _service_accounts: {} + when: item.service | default(false) + ansible.builtin.set_fact: + _service_accounts: "{{ _service_accounts | combine({item.name: item}) }}" + loop: "{{ skylab_accounts }}" + loop_control: + label: "{{ item.name }}" + + - name: Install compose file + vars: + app: "{{ item.value }}" + _app_account: "{{ _service_accounts[item.value.user] if item.value.user is defined else false }}" + ansible.builtin.template: + src: docker-compose/{{ item.key }}.yaml.j2 + dest: "{{ skylab_compose_dir }}/{{ item.key }}.yaml" + owner: "{{ ansible_user }}" + group: "{{ skylab_group_admin.name }}" + mode: 0660 + loop: "{{ _services | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Create automation groups + become: true + when: item.value.user is defined + ansible.builtin.group: + name: "{{ item.value.user }}" + gid: "{{ _service_accounts[item.value.user].uid }}" + state: present + loop: "{{ _services | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Create automation accounts + become: true + when: item.value.user is defined + ansible.builtin.user: + name: "{{ item.value.user }}" + state: present + uid: "{{ _service_accounts[item.value.user].uid }}" + group: "{{ item.value.user }}" + groups: "{{ [skylab_group_automation.name, skylab_group.name] }}" + system: true + generate_ssh_key: false + password: "{{ _service_accounts[item.value.user].password }}" + loop: "{{ _services | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Determine volume directories + vars: + _stack_volume_directories: [] + when: item.value.volumes is defined + ansible.builtin.set_fact: + _stack_volume_directories: "{{ _stack_volume_directories + [{'user': (item.value.user | default(ansible_user)), 'volumes': (item.value.volumes.values() | list)}] }}" + loop: "{{ _services | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Create service directories + become: true + ansible.builtin.file: + path: "{{ local_datastore_mount }}{{ item.1 }}" + state: directory + owner: "{{ item.0.user }}" + group: "{{ skylab_group_admin.name }}" + mode: 0770 + loop: "{{ _stack_volume_directories | subelements('volumes') }}"