Compare commits

...

10 Commits

66 changed files with 549 additions and 213 deletions

View File

@ -12,7 +12,7 @@ en1:
skylab_location: Newton MA skylab_location: Newton MA
skylab_dashboard: info.en1.local skylab_dashboard: info.en1.local
# gross hack for now, will be refactored later # gross hack for now, will be refactored later
_skylab_adguard_nat_rule: 8 _skylab_adguard_nat_rule: 9
hosts: hosts:
core: core:
@ -42,6 +42,7 @@ en1:
vars: vars:
skylab_targets: [cluster, datastore] skylab_targets: [cluster, datastore]
skylab_compose_version: 3.8 skylab_compose_version: 3.8
skylab_compose_dir: "{{ skylab_state_dir }}/compose"
hosts: hosts:
pegasus: # jupiter pegasus: # jupiter
@ -58,13 +59,14 @@ en1:
interface: interface:
access: bond0 access: bond0
internal: bond0.99 internal: bond0.99
skylab_datastore_device: sdb
skylab_networking: skylab_networking:
eno1: eno1:
bond: bond0 bond: bond0
eno2: eno2:
bond: bond0 bond: bond0
bond0: bond0:
type: bond device: bond
firewall: internal firewall: internal
gateway: 10.42.101.1/24 gateway: 10.42.101.1/24
dns: dns:
@ -74,7 +76,7 @@ en1:
- 192.168.255.255/32 - 192.168.255.255/32
dhcp: false dhcp: false
bond0.99: bond0.99:
type: vlan device: vlan
firewall: trusted firewall: trusted
addresses: addresses:
- 192.168.42.10/24 - 192.168.42.10/24
@ -100,7 +102,7 @@ en1:
eno2: eno2:
bond: bond0 bond: bond0
bond0: bond0:
type: bond device: bond
firewall: internal firewall: internal
dhcp: false dhcp: false
gateway: 10.42.101.1/24 gateway: 10.42.101.1/24
@ -110,7 +112,7 @@ en1:
dns: dns:
- 10.42.101.1 - 10.42.101.1
bond0.99: bond0.99:
type: vlan device: vlan
firewall: trusted firewall: trusted
dhcp: false dhcp: false
addresses: addresses:
@ -137,7 +139,7 @@ en1:
eno2: eno2:
bond: bond0 bond: bond0
bond0: bond0:
type: bond device: bond
firewall: internal firewall: internal
gateway: 10.42.101.1/24 gateway: 10.42.101.1/24
dns: dns:
@ -147,7 +149,7 @@ en1:
- 192.168.255.255/32 - 192.168.255.255/32
dhcp: false dhcp: false
bond0.99: bond0.99:
type: vlan device: vlan
firewall: trusted firewall: trusted
addresses: addresses:
- 192.168.42.30/24 - 192.168.42.30/24

View File

@ -1 +0,0 @@
../resources

View File

@ -1 +0,0 @@
../roles

View File

@ -1 +0,0 @@
../tasks

View File

@ -1 +0,0 @@
../resources

View File

@ -1 +0,0 @@
../vars/

501
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ license = "MIT"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.8" python = "^3.8"
ansible = "^3.4.0" ansible = "^4.9.0"
docker = "^4.2.0" docker = "^4.2.0"
docker-compose = "^1.25.4" docker-compose = "^1.25.4"
paramiko = "^2.7.1" paramiko = "^2.7.1"

4
requirements.yml Normal file
View File

@ -0,0 +1,4 @@
---
collections:
- source: ./skylab/
type: subdirs

3
skylab/core/README.md Normal file
View File

@ -0,0 +1,3 @@
# Ansible Collection - skylab.core
Documentation for the collection.

19
skylab/core/galaxy.yml Normal file
View File

@ -0,0 +1,19 @@
---
namespace: skylab
name: core
version: 0.0.0
description: Network deployment procedures and configuration state management
authors:
- Ethan Paul <me@enp.one>
license:
- MIT
readme: README.md
tags: []
repository: https://vcs.enp.one/skylab/skylab-ansible/
build_ignore: []
# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
# collection label 'namespace.name'. The value is a version range
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
# range specifiers can be set and are separated by ','
dependencies: {}

View File

@ -0,0 +1,2 @@
---
requires_ansible: ">=2.11,<2.15"

View File

@ -0,0 +1,200 @@
---
- 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
tags:
- cleanup
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: Fetch existing Nginx configs
ansible.builtin.command:
cmd: ls {{ local_datastore_mount }}/appdata/nginx/conf.d/
changed_when: false
register: _nginx_configs
- name: Remove legacy nginx configs
when: item.replace('.conf', '') not in skylab_services
ansible.builtin.file:
path: "{{ local_datastore_mount }}/appdata/nginx/conf.d/{{ item }}.conf"
state: absent
loop: "{{ _nginx_configs.stdout_lines }}"
- 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: Create compose directory
become: true
ansible.builtin.file:
path: "{{ skylab_compose_dir }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ skylab_group_admin.name }}"
mode: 0770
- 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: Configure datastore directories
run_once: true
block:
- 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') }}"
- name: Deploy stack
vars:
ansible_python_interpreter: "{{ skylab_ansible_venv }}/bin/python"
community.docker.docker_stack:
name: "{{ item.key }}"
compose:
- "{{ skylab_compose_dir }}/{{ item.key }}.yaml"
prune: false
state: present
loop: "{{ _services | dict2items }}"
loop_control:
label: "{{ item.key }}"
- name: Configure reverse proxy
run_once: true
block:
- name: Create nginx config
when: item.value.domain is defined
ansible.builtin.template:
src: stack-nginx.conf.j2
dest: "{{ local_datastore_mount }}/appdata/nginx/conf.d/{{ item.key }}.conf"
owner: "{{ ansible_user }}"
group: "{{ skylab_group_admin.name }}"
mode: 0464
loop: "{{ _services | dict2items }}"
loop_control:
label: "{{ item.value.domain | default(item.key) }}"

View File

@ -2,6 +2,9 @@
- name: Check cluster state - name: Check cluster state
hosts: cluster hosts: cluster
any_errors_fatal: true any_errors_fatal: true
pre_tasks:
- name: Configure remot execution environment
ansible.builtin.import_tasks: tasks/meta/bootstrap-remote-env.yaml
tasks: tasks:
- name: Validate user input - name: Validate user input
run_once: true run_once: true

View File

@ -5,6 +5,9 @@
- name: skylab_datastore_encryption_password - name: skylab_datastore_encryption_password
prompt: Enter datastore block decryption password prompt: Enter datastore block decryption password
private: true private: true
pre_tasks:
- name: Configure remot execution environment
ansible.builtin.import_tasks: tasks/meta/bootstrap-remote-env.yaml
roles: roles:
- role: datastore - role: datastore
tasks: tasks:

View File

@ -1,6 +1,6 @@
--- ---
skylab_services: skylab_services:
_meta: meta:
networks: networks:
ext: 192.168.99.0/24 ext: 192.168.99.0/24
volumes: volumes:
@ -17,7 +17,7 @@ skylab_services:
loopback_address: 192.168.255.255 loopback_address: 192.168.255.255
minecraft: minecraft:
user: auto_minecraft user: autocraft
domain: mcs.enp.one domain: mcs.enp.one
networks: networks:
ext: 192.168.102.0/24 ext: 192.168.102.0/24