Compare commits
	
		
			54 Commits
		
	
	
		
			48e7b8208e
			...
			devel
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4a516eee15 | |||
| 15a1411f1a | |||
| 868ab721dd | |||
| 9776e9a316 | |||
| 28f1f80d6f | |||
| 0f9479731a | |||
| 3df0115191 | |||
| fcb25b79ce | |||
| e591db8581 | |||
| e4fd90c013 | |||
| 219b03b4ee | |||
| 1b941a11a2 | |||
| 12991700b9 | |||
| 02b6460cff | |||
| 5f602c797f | |||
| 538bb26f83 | |||
| fa0df823ee | |||
| 49eacf103c | |||
| 4d1d28c64b | |||
| 5803ea337e | |||
| 20e9ec68d2 | |||
| d901c1d940 | |||
| 875d8f1538 | |||
| 1e1677cb4d | |||
| 29bccbac02 | |||
| 80015c6535 | |||
| 3bcbee1b85 | |||
| 8f965c3e2b | |||
| 88247b4011 | |||
| 740b73cb7d | |||
| 857e83a6fe | |||
| 745f6acc04 | |||
| 43fbb3993b | |||
| 955d7e8a64 | |||
| 614fca41c0 | |||
| 0163d5ab18 | |||
| eb2ad9e60a | |||
| 11235ab859 | |||
| ce72850721 | |||
| d5f92811bd | |||
| 2d26caba54 | |||
| 36ce40d718 | |||
| a7d9e1b270 | |||
| a6d1d46236 | |||
| d9c00a0d9e | |||
| f3008294e4 | |||
| 58dcf4694f | |||
| a822fe0915 | |||
| cd1910c2bd | |||
| 421ceabd9e | |||
| 068a33626d | |||
| 8b4fb71160 | |||
| 72d8e7cdde | |||
| 58128eec46 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -7,3 +7,5 @@ playbooks/testing.yml | ||||
| .venv/ | ||||
| .ansible/ | ||||
| .tox/ | ||||
| .terraform/ | ||||
| .terraform.lock.* | ||||
|   | ||||
| @@ -32,3 +32,11 @@ repos: | ||||
|           - "--wrap=90" | ||||
|         types: | ||||
|           - markdown | ||||
|  | ||||
|       - id: terraform | ||||
|         name: terraform format | ||||
|         entry: terraform | ||||
|         language: system | ||||
|         args: | ||||
|           - fmt | ||||
|         files: ".*\\.tf$" | ||||
|   | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ clean: | ||||
| 	rm --recursive --force .tox/ | ||||
|  | ||||
| dev: | ||||
| 	@poetry install --remove-untracked | ||||
| 	@poetry install --sync | ||||
| 	@poetry run pre-commit install | ||||
| 	@poetry run ansible-galaxy collection install --requirements-file ./requirements.yaml --collections-path ./.ansible | ||||
| 	@bash ./link-local-collections.sh | ||||
|   | ||||
| @@ -11,7 +11,8 @@ poetry run ansible-playbook ... | ||||
|  | ||||
| ## Boostraping remote system for management: | ||||
|  | ||||
| 1. Install a supported operating system: [Rocky Linux](https://rockylinux.org) | ||||
| 1. Install a supported operating system: [Rocky Linux](https://rockylinux.org), | ||||
|    [Fedora](https://getfedora.org) | ||||
| 2. During installation create a user named `ansible` with any password | ||||
| 3. After installation copy SSH key to the `ansible` user | ||||
| 4. Enable password-less sudo access for the `ansible` user with this command: | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| [defaults] | ||||
| host_key_checking = false | ||||
| host_key_checking = true | ||||
| collections_path = .ansible | ||||
| inventory = inventory.yaml | ||||
| inventory = inventory/ | ||||
|  | ||||
| [ssh_connection] | ||||
| ssh_args = "-o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes" | ||||
| ssh_args = "-o ControlMaster=auto -o ControlPersist=60s" | ||||
|  | ||||
| [inventory] | ||||
| enable_plugins = ansible.builtin.yaml | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| --- | ||||
| all: | ||||
|   vars: | ||||
|     skylab_state_dir: /var/lib/skylab | ||||
|     skylab_ansible_venv: "{{ skylab_state_dir }}/ansible-runtime" | ||||
|     skylab_pip_version: 19.3.1 | ||||
|     ansible_user: ansible | ||||
|     ansible_ssh_common_args: "-o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes" | ||||
| workstation: | ||||
|   hosts: | ||||
|     voyager: | ||||
|       skylab_description: Personal Workstation | ||||
|       skylab_hostname: voyager.skylab.enp.one | ||||
|       skylab_targets: [workstation] | ||||
| 
 | ||||
| en1: | ||||
|   vars: | ||||
							
								
								
									
										51
									
								
								inventory/en1.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								inventory/en1.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| --- | ||||
| en1: | ||||
|  | ||||
|   vars: | ||||
|     skylab_location: Cambridge | ||||
|  | ||||
|   children: | ||||
|     domain: | ||||
|       children: | ||||
|  | ||||
|         cluster: | ||||
|           hosts: | ||||
|             canaveral: | ||||
|               ansible_host: 10.42.101.10 | ||||
|               skylab_description: Compute and Storage Node | ||||
|             baikonur: | ||||
|               ansible_host: 10.42.101.11 | ||||
|               skylab_description: Compute and Storage Node | ||||
|             vandenberg: | ||||
|               ansible_host: 10.42.101.12 | ||||
|               skylab_description: Compute and Storage Node | ||||
|             andoya: | ||||
|               ansible_host: 10.42.101.13 | ||||
|               skylab_description: Auxilary Compute Node | ||||
|             jiuquan: | ||||
|               ansible_host: 10.42.101.14 | ||||
|               skylab_description: Auxilary Compute Node | ||||
|  | ||||
|         datastore: | ||||
|           hosts: | ||||
|             canaveral: | ||||
|               skylab_datastore_block: /dev/sda | ||||
|             baikonur: | ||||
|               skylab_datastore_block: /dev/sda | ||||
|             vandenberg: | ||||
|               skylab_datastore_block: /dev/sda | ||||
|  | ||||
|         hosts: | ||||
|           3d-printer: {} | ||||
|           mediastore: {} | ||||
|           backstore: {} | ||||
|  | ||||
|     local: | ||||
|       hosts: | ||||
|         core: {} | ||||
|         switch-1: {} | ||||
|         switch-2: {} | ||||
|         wap-1: {} | ||||
|         wap-2: {} | ||||
|         wap-3: {} | ||||
|         printer: {} | ||||
							
								
								
									
										39
									
								
								inventory/group_vars/all.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								inventory/group_vars/all.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| --- | ||||
| ansible_user: ansible | ||||
|  | ||||
| ansible_port: 4242 | ||||
|  | ||||
| skylab_state_dir: /var/lib/skylab | ||||
|  | ||||
| skylab_ansible_venv: "{{ skylab_state_dir }}/ansible-runtime" | ||||
|  | ||||
| skylab_ansible_vault_password: !vault | | ||||
|           $ANSIBLE_VAULT;1.1;AES256 | ||||
|           61323762623165383963316238343539346336663864366631616339356564346636373561616237 | ||||
|           6666363531393234636337656431366365343236346536320a346163353935366636303131313661 | ||||
|           32623635363063383039363539303135393838376264356463646465376435616363376163373663 | ||||
|           6366633665373939380a373234633365376632376433643034336539346338613566353537663731 | ||||
|           34323464633165626133306464363464333539363761343831316565356266373833 | ||||
|  | ||||
| skylab_tfstate_backend: | ||||
|   hostname: cluster.lab.enp.one | ||||
|   username: terraform | ||||
|   schema: terraform | ||||
|   port: 32421 | ||||
|   password: !vault | | ||||
|           $ANSIBLE_VAULT;1.1;AES256 | ||||
|           30313365393065316563323363663135313438616461356439366632303636343735653033363930 | ||||
|           6334613931376566363064663539643639326363663933610a306138616362376435386466306538 | ||||
|           30626330613932363339363438356430613461313335333536623931343436353330393433373630 | ||||
|           3631343463616631380a386661336534663033383637666538316665303962353034376232356235 | ||||
|           65323339353563623431666535366465353133343137653232326534326436323661636536373564 | ||||
|           3466633762303966366366653531613261336561356531636461 | ||||
|  | ||||
| skylab_mgmt: | ||||
|   sshport: 4242 | ||||
|   group: skylab | ||||
|   user: ansible | ||||
|   id: 1400 | ||||
|   sshkeys: | ||||
|   - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5TGKururOa1Y+cbv8AWXYI5zhfZCDV0fsBG+33IYUc enpaul@ansible.voyager | ||||
|   - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBf7i/8hSJDYnoD95noCJJVtSxxCp9N5EmnshALufiwm enpaul@ansible.opportunity | ||||
							
								
								
									
										3080
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3080
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -7,22 +7,21 @@ license = "MIT" | ||||
|  | ||||
| [tool.poetry.dependencies] | ||||
| python = "^3.10" | ||||
| ansible-core = "^2.12.1" | ||||
| docker = "^4.2.0" | ||||
| docker-compose = "^1.25.4" | ||||
| ansible-core = "^2.14.3" | ||||
| docker = "^6.0.1" | ||||
| paramiko = "^2.7.1" | ||||
| jsondiff = "^1.2.0" | ||||
| jsondiff = "^2.0.0" | ||||
| netaddr = "^0.8.0" | ||||
|  | ||||
| [tool.poetry.dev-dependencies] | ||||
| ansible-lint = "^4.2.0" | ||||
| ipython = "^7.28.0" | ||||
| mdformat = "^0.7.9" | ||||
| mdformat-gfm = "^0.3.3" | ||||
| poetry = "^1.1.0" | ||||
| pre-commit = "^2.9.2" | ||||
| pre-commit-hooks = "^3.3.0" | ||||
| safety = "^1.9.0" | ||||
| ansible-lint = {version = "^6.14.0", markers = "platform_system != 'Windows'"} | ||||
| ipython = "^8.11.0" | ||||
| mdformat = "^0.7.16" | ||||
| mdformat-gfm = "^0.3.5" | ||||
| poetry = "^1.3.0" | ||||
| pre-commit = "^3.2.0" | ||||
| pre-commit-hooks = "^4.4.0" | ||||
| safety = "^2.3.5" | ||||
| tox = "^3.20.1" | ||||
| tox-poetry-installer = {extras = ["poetry"], version = "^0.8.3"} | ||||
| yamllint = "^1.20.0" | ||||
| tox-poetry-installer = {extras = ["poetry"], version = "^0.10.0"} | ||||
| yamllint = "^1.29.0" | ||||
|   | ||||
| @@ -38,3 +38,10 @@ | ||||
|   roles: | ||||
|     - role: skylab.core.dashboard | ||||
|       dashboard_hostname: "{{ skylab_dashboard }}" | ||||
|  | ||||
|  | ||||
| - name: Configure workstations | ||||
|   hosts: workstation | ||||
|   gather_facts: false | ||||
|   roles: | ||||
|     - role: skylab.core.workstation | ||||
|   | ||||
| @@ -5,8 +5,9 @@ function _parse_git_branch() { | ||||
| export PS1="\[\e[0;97m\]\[\e[37m\e[1m\]\u\[\e[1;94m\]@\[\e[94m\]\H\[\e[37m\]:\w\[\e[33m\]\[\e[0;33m\]\$(_parse_git_branch) \[\e[37m\]\[\e[0;97m\]$\[\e[0m\] " | ||||
| export rc=/home/$USERNAME/.bashrc | ||||
| export VIRTUALENV_DIR=/home/$USERNAME/.venvs | ||||
| export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt | ||||
|  | ||||
| random() { | ||||
| function random() { | ||||
|      if [[ $# -eq 0 ]]; then | ||||
|           num=32 | ||||
|      else | ||||
| @@ -19,9 +20,10 @@ function up() { cd $(eval printf '../'%.0s {1..$1}); } | ||||
|  | ||||
| function pipin() { pip freeze | grep $1; } | ||||
|  | ||||
| function continuous () { while true; do ${@}; sleep 3; done; } | ||||
|  | ||||
| alias bk='cd -' | ||||
| alias fuck='sudo $(history -p \!\!)' | ||||
| alias ls='ls -lshF --color --group-directories-first --time-style=long-iso' | ||||
| alias version='uname -orp && lsb_release -a | grep Description' | ||||
| alias activate='source ./bin/activate' | ||||
| alias cls='clear' | ||||
| @@ -32,3 +34,4 @@ alias whatismyip='curl https://icanhazip.com/' | ||||
| alias uuid="python3 -c 'import uuid; print(uuid.uuid4());'" | ||||
| alias epoch="python3 -c 'import time; print(time.time());'" | ||||
| alias uptime="command uptime --pretty" | ||||
| alias unmount="umount" | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| --- | ||||
| - name: Install CentOS 8 python bindings | ||||
|   when: ansible_distribution == "Rocky" | ||||
|   when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora" | ||||
|   become: true | ||||
|   ansible.builtin.dnf: | ||||
|     state: present | ||||
|     name: | ||||
|       - libffi-devel | ||||
|       - python3-devel | ||||
|       - python3-libselinux | ||||
|       - python3-policycoreutils | ||||
|       - python3-firewall | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
|     key: edgeos | ||||
|  | ||||
| - name: Group supported Linux hosts | ||||
|   when: ansible_distribution == "Rocky" | ||||
|   when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora" | ||||
|   changed_when: false | ||||
|   group_by: | ||||
|     key: linux | ||||
|   | ||||
| @@ -76,3 +76,24 @@ services: | ||||
|       restart_policy: | ||||
|         condition: any | ||||
|         delay: 24h | ||||
|  | ||||
|   backup: | ||||
|     image: rockylinux:latest | ||||
|     hostname: backup | ||||
|     command: bash /datastore/backup/mkbkup.sh /datastore/ | ||||
|     networks: | ||||
|       - meta | ||||
|     volumes: | ||||
|       - type: volume | ||||
|         source: meta-backup | ||||
|         target: /datastore/backup | ||||
|         read_only: false | ||||
|       - type: volume | ||||
|         source: meta-appdata | ||||
|         target: /datastore/appdata | ||||
|         read_only: true | ||||
|     deploy: | ||||
|       replicas: 1 | ||||
|       restart_policy: | ||||
|         condition: any | ||||
|         delay: 24h | ||||
|   | ||||
| @@ -0,0 +1,113 @@ | ||||
| --- | ||||
| version: '3.7' | ||||
|  | ||||
| volumes: | ||||
|   photoprism-database: | ||||
|     name: datastore/appdata/photoprism/database | ||||
|     driver: glusterfs | ||||
|   photoprism-metadata: | ||||
|     name: datastore/appdata/photoprism/metadata | ||||
|   photoprism-originals: | ||||
|     name: datastore/media/photoprism | ||||
|     driver: glusterfs | ||||
|   photoprism-import: | ||||
|     name: datastore/media/upload | ||||
|     driver: glusterfs | ||||
|  | ||||
| networks: | ||||
|   photoprism: | ||||
|     internal: true | ||||
|     name: photoprism | ||||
|     driver: overlay | ||||
|     ipam: | ||||
|       driver: default | ||||
|       config: | ||||
|         - subnet: 192.168.109.0/24 | ||||
|  | ||||
| services: | ||||
|   app: | ||||
|     image: photoprism/photoprism:latest | ||||
|     hostname: app | ||||
|     depends_on: | ||||
|       - database | ||||
|     networks: | ||||
|       - photoprism | ||||
|     ports: | ||||
|       - published: 2342 | ||||
|         target: 2342 | ||||
|         protocol: tcp | ||||
|         mode: ingress | ||||
|     environment: | ||||
|       PHOTOPRISM_ADMIN_PASSWORD: "gm2auW34GNawZ8Dqiub8W8vOlvsHCnfj" | ||||
|       PHOTOPRISM_SITE_URL: "http://cluster.skylab.enp.one:2342/" | ||||
|       PHOTOPRISM_ORIGINALS_LIMIT: 5000 | ||||
|       PHOTOPRISM_HTTP_COMPRESSION: "gzip" | ||||
|       PHOTOPRISM_DEBUG: "false" | ||||
|       PHOTOPRISM_PUBLIC: "false" | ||||
|       PHOTOPRISM_READONLY: "false" | ||||
|       PHOTOPRISM_EXPERIMENTAL: "false" | ||||
|       PHOTOPRISM_DISABLE_CHOWN: "false" | ||||
|       PHOTOPRISM_DISABLE_WEBDAV: "false" | ||||
|       PHOTOPRISM_DISABLE_SETTINGS: "false" | ||||
|       PHOTOPRISM_DISABLE_TENSORFLOW: "false" | ||||
|       PHOTOPRISM_DISABLE_FACES: "false" | ||||
|       PHOTOPRISM_DISABLE_CLASSIFICATION: "false" | ||||
|       PHOTOPRISM_DARKTABLE_PRESETS: "false" | ||||
|       PHOTOPRISM_DETECT_NSFW: "false" | ||||
|       PHOTOPRISM_UPLOAD_NSFW: "true" | ||||
|       PHOTOPRISM_DATABASE_DRIVER: "mysql" | ||||
|       PHOTOPRISM_DATABASE_SERVER: "database:3306" | ||||
|       PHOTOPRISM_DATABASE_NAME: "photoprism" | ||||
|       PHOTOPRISM_DATABASE_USER: "photoprism" | ||||
|       PHOTOPRISM_DATABASE_PASSWORD: "KcIKhME9OwWKVz4tGyqI4VXzyDBs33Xp"       # MariaDB or MySQL database user password | ||||
|       PHOTOPRISM_SITE_TITLE: "Skylab Images" | ||||
|       PHOTOPRISM_SITE_CAPTION: "Browse Your Life" | ||||
|       PHOTOPRISM_SITE_DESCRIPTION: "" | ||||
|       PHOTOPRISM_SITE_AUTHOR: "EN Paul" | ||||
|       HOME: "/photoprism" | ||||
|       PHOTOPRISM_UID: 1408 | ||||
|       PHOTOPRISM_GID: 1408 | ||||
|       ## Hardware video transcoding config (optional) | ||||
|       # PHOTOPRISM_FFMPEG_BUFFERS: "64"              # FFmpeg capture buffers (default: 32) | ||||
|       # PHOTOPRISM_FFMPEG_BITRATE: "32"              # FFmpeg encoding bitrate limit in Mbit/s (default: 50) | ||||
|       # PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m"    # Use Video4Linux for AVC transcoding (default: libx264) | ||||
|       # PHOTOPRISM_FFMPEG_ENCODER: "h264_qsv"        # Use Intel Quick Sync Video for AVC transcoding (default: libx264) | ||||
|       # PHOTOPRISM_INIT: "intel-graphics tensorflow-amd64-avx2" # Enable TensorFlow AVX2 & Intel Graphics support | ||||
|       ## Enable TensorFlow AVX2 support for modern Intel CPUs (requires starting the container as root) | ||||
|       # PHOTOPRISM_INIT: "tensorflow-amd64-avx2" | ||||
|     user: "1408:1408" | ||||
|     working_dir: "/photoprism" | ||||
|     volumes: | ||||
|       - type: volume | ||||
|         source: photoprism-originals | ||||
|         target: /photoprism/originals | ||||
|         read_only: false | ||||
|       - type: volume | ||||
|         source: photoprism-metadata | ||||
|         target: /photoprism/storage | ||||
|         read_only: false | ||||
|       - type: volume | ||||
|         source: photoprism-import | ||||
|         target: /photoprism/import | ||||
|         read_only: true | ||||
|     deploy: | ||||
|       replicas: 1 | ||||
|  | ||||
|   database: | ||||
|     image: mariadb:10.6 | ||||
|     hostname: database | ||||
|     command: mysqld --innodb-buffer-pool-size=128M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120 | ||||
|     networks: | ||||
|       - photoprism | ||||
|     volumes: | ||||
|       - type: volume | ||||
|         source: photoprism-database | ||||
|         target: /var/lib/mysql | ||||
|         read_only: false | ||||
|     environment: | ||||
|       MYSQL_ROOT_PASSWORD: insecure | ||||
|       MYSQL_DATABASE: photoprism | ||||
|       MYSQL_USER: photoprism | ||||
|       MYSQL_PASSWORD: KcIKhME9OwWKVz4tGyqI4VXzyDBs33Xp | ||||
|     deploy: | ||||
|       replicas: 1 | ||||
							
								
								
									
										34
									
								
								skylab/core/playbooks/templates/stack-nginx.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								skylab/core/playbooks/templates/stack-nginx.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| # Ansible managed file - do not manually edit | ||||
| # | ||||
| server { | ||||
|     server_name  {{ app.publish.domain }}; | ||||
|     root         /usr/share/nginx/html; | ||||
|  | ||||
|     location / { | ||||
|         proxy_pass        http://dockerloopback:{{ app.publish.http }}/; | ||||
|         proxy_set_header  Host $host; | ||||
|     } | ||||
|  | ||||
|     listen 443           ssl; | ||||
|     ssl_certificate      /etc/letsencrypt/live/{{ app.publish.domain }}/fullchain.pem; | ||||
|     ssl_certificate_key  /etc/letsencrypt/live/{{ app.publish.domain }}/privkey.pem; | ||||
|     include              /etc/letsencrypt/options-ssl-nginx.conf; | ||||
|     ssl_dhparam          /etc/letsencrypt/ssl-dhparams.pem; | ||||
| } | ||||
|  | ||||
| server { | ||||
|     listen	 80; | ||||
|     listen	 [::]:80; | ||||
|     server_name  {{ app.publish.domain }}; | ||||
|  | ||||
|     location ^~ /.well-known/acme-challenge/ { | ||||
|         proxy_pass        http://dockerloopback:8088/.well-known/acme-challenge/; | ||||
|         proxy_set_header  Host $host; | ||||
|     } | ||||
|  | ||||
|     location / { | ||||
|         return 301 https://$host$request_uri; | ||||
|     } | ||||
| } | ||||
|  | ||||
| # EOF | ||||
| @@ -24,7 +24,7 @@ | ||||
|     - vars/packages.yaml | ||||
|   tasks: | ||||
|     - name: Update system packages via DNF | ||||
|       when: ansible_distribution == "Rocky" | ||||
|       when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora" | ||||
|       become: true | ||||
|       ansible.builtin.dnf: | ||||
|         name: "*" | ||||
| @@ -39,7 +39,7 @@ | ||||
|         group: "{{ ansible_user }}" | ||||
|         mode: 0644 | ||||
|  | ||||
|     - name: Install universal packages | ||||
|     - name: Install universal packages on Rocky | ||||
|       when: ansible_distribution == "Rocky" | ||||
|       become: true | ||||
|       ansible.builtin.dnf: | ||||
| @@ -47,6 +47,14 @@ | ||||
|         state: present | ||||
|         update_cache: true | ||||
|  | ||||
|     - name: Install universal packages on Fedora | ||||
|       when: ansible_distribution == "Fedora" | ||||
|       become: true | ||||
|       ansible.builtin.dnf: | ||||
|         name: "{{ skylab_packages_global + skylab_packages_fedora }}" | ||||
|         state: present | ||||
|         update_cache: true | ||||
|  | ||||
|  | ||||
| - name: Update unix accounts | ||||
|   hosts: linux | ||||
| @@ -132,7 +140,7 @@ | ||||
|       ansible.builtin.set_fact: | ||||
|         _determined_member_groups: "{{ _determined_member_groups | default({}) | combine({item.name: [ | ||||
|           skylab_group.name, | ||||
|           'wheel' if (item.admin | default(false) and ansible_distribution == 'Rocky') else '', | ||||
|           'wheel' if (item.admin | default(false) and ansible_os_family == 'RedHat') else '', | ||||
|           'sudo' if (item.admin | default(false) and ansible_os_family == 'Debian') else '', | ||||
|           skylab_group_admin.name if item.admin | default(false) else '', | ||||
|           skylab_group_automation.name if item.service | default(false) else '', | ||||
| @@ -151,7 +159,11 @@ | ||||
|         groups: "{{ _determined_member_groups[item.name] }}" | ||||
|         comment: "{{ item.fullname | default('') }}" | ||||
|         system: "{{ item.service | default(false) }}" | ||||
|         generate_ssh_key: false | ||||
|         generate_ssh_key: true | ||||
|         ssh_key_bits: 4096 | ||||
|         ssh_key_passphrase: "{{ item.password }}" | ||||
|         ssh_key_comment: "{{ item.name }}@{{ inventory_hostname }}" | ||||
|         ssh_key_type: ed25519 | ||||
|         password: "{{ item.password }}" | ||||
|       loop: "{{ _active_accounts }}" | ||||
|       loop_control: | ||||
|   | ||||
| @@ -3,13 +3,13 @@ skylab_accounts: | ||||
|   - name: enpaul | ||||
|     uid: 1300 | ||||
|     fullname: Ethan N. Paul | ||||
|     targets: [network, datastore, cluster, cloud] | ||||
|     targets: [network, datastore, cluster, cloud, workstation] | ||||
|     admin: true | ||||
|     password: $6$H7jZEL2Ey93zfMTD$CzUlZkXDudPHgUMU/OFUn8/Yhzo8nBxoSI8thD15toIFlWN.iUfq/Jp5z3KpDCGTxyv.IbRTvE8dOVWjoRfgJ. | ||||
|  | ||||
|   - name: ansible | ||||
|     uid: 1400 | ||||
|     targets: [network, datastore, cluster, cloud] | ||||
|     targets: [network, datastore, cluster, cloud, workstation] | ||||
|     admin: true | ||||
|     service: true | ||||
|     password: $6$qNKmYg4y9YS4f5Gr$m0mAqEVbymPguj.1cS.pfclt33Okfmn1KhFC0r1iQ3eVvz/OIZY3x0qGmPnJ1zOXDWyKKs5hnlGTAeZgCh49C. | ||||
|   | ||||
| @@ -27,3 +27,9 @@ skylab_packages_rocky: | ||||
|   - python3-virtualenv | ||||
|   - systemd-networkd | ||||
|   - wget | ||||
|  | ||||
| skylab_packages_fedora: | ||||
|   - bind-utils | ||||
|   - nc | ||||
|   - nfs-utils | ||||
|   - wget | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
| skylab_ssh_keys: | ||||
|   enpaul: | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDi9rWRC15og/+3Jc3AMHOrlIc2BHaAX9PLbklz3qfFtSOp9bIScMcH5ZR6lyVSgP8RCEjI5HuZejDUJTXUQYfvEJeno//vmxn9Vw66lpMz/FSJ3JcDbjDVI1pe3A8mTOAS+AoVOEzCUOJVZJvdI272Hgf+QRBu+ONQ12u+2XYdVfLFDe7mAG+vEJRBatwb8B7Al+/LUpIrCuPm9PzMBtCMFjWGaqQgnyJYRSPIGxz9231XIjwhHLOQG1R0jLGuS37X+J49Y5JYDaHf9q9KH76GjdO2rOq6aGvwN93Y4Z+D2hMOklhD0Ez/ZE+I3ZUPV0e5pF28gsA6L7gTeqmSGpQaKdwjCUoU12VM70OVxng5p2+7DIc0k2np7rnvd4zybgn9OMM+TIO5M3c6ocDuNsEmRgfS3V99X5oh9qNy35UdBXV08j0wFoUo1KcyGwyNBYzKzvkkvtgJezVKmqSPKeBjMgMX4UsJsMn27Zosk0ZgoUwLFPO9Pg7uShncwgsTnvYDR1ws53PV832gc7A85ud/dC9Fjn6jBsMQaCFbiZktc5J8mv3cugQHQesbq8Y2aNVRu+ECb+KUvAEdPacWdBOkk0IvZ4PvLrAs2xehF6FYVqKVtPlJMaUAAwj9vVx7Nl2HnsSRIrCgxsMOTOhbbp/3NrvM8r6K7zKBzXg2TNgQeQ== enpaul@ph-1 | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8K74AXz6LBYfoXRbY1pKP+1rvi5BpjFOkg1uYuMM+q78toagSREpLrbjvPtoL8fkEFox4T9TUaME08ZP8560R6iRk35extTTiXquflEwvpsF+e9Lv8E712s/1ydJpkYoux1OohE4W5D9DjVMEW1tjXeb+9aDUcVml6YKMpKLpjEIVanyjHMN13XgswKZGoK3mVMnWxE36fbGVVfiFCvMr/BpjqGShRCxmvldzgq76i1BpTKi6omOjvpgRQcUJcDhYcHAUVSlNccgGLmlAPiUillA//pk84yczzH1dQBB6571Ab5ldoUDBU/hJ0W27aeOfrepup4hNuUt2oux+zAn+uetAuAWKU2Kd0Oo6L5IKObbAQLI0CXfyrmHlrYXwTyNMFleeOdw7s9lf2ra3YCYVXfMALdE6pp+HJLBxzg9kMBbTp6zkV7ZKi75AQhyBJA0s4+vRUccBtJit3Tls+aw/3rd9Dt9lLaXkE80khoKsUI0eiuXtPDlurGxkpcTe6Al/lChNA19pdKEUsBmhD6UUvMTYWlApmta/+xf0wDsSyHqJcnIGx8Qdtg3c4j1Ch+WXwbdOwk8XJrL0atWmv2ium1ll/arO2NFBmbwG1LG/lzJ1k/DoAiHrKrb1HdlwDk0O/7xF/zyC2mfVZKO36+g4XlA7wDJc0tB5vIymlEy2rw== enpaul@serico-nox | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDHUXG01NQ7IahqBwLx+lqvbnhU5Cynt+Y4xCk2u5pwjU2KwKyRfqc5LUROU4mcFLuA1mP9uoMaYmiJ/rIWvM/A9OVplilCoSKXxWJW09fR/rOPmCn7pOR+CpFXBNOiRR0WoiDeu1D0tifbSuK/qOxKy6Lp9MH20Ma46d89xA57L9LX+B5CrwF9fR2FXIQGojCiFFyByaUgmzuDMi5mCafm3XlqaR1/wcqoA1YwqFFiGR3gVylSbOmB/Q4GnnyLpBbcYAc5AQnbnD4LlM5biEsLNy7vtQj9s0SeloUkzsJ112dNozdwTI/tOWbINVM+o3AH4B2baTQayWK/UrG9sivjHgEz5Jk5A4xAbUWC1MrH7WHo7vevHu4AT+DiPLkmHli9Ztu0DqJuenheJDyRLfWwDPvIpoY9/AsbVZ/UXqRVbfIB4jV00IHneEg4zj0AdWbSHDz55BZ23JItpuU4i37cO9Cbo2tQYqZjgM5VAlZXwhNPUF7pxWJJxGFqiB5MTQM0LZcrmXpToxBPa0BSDmIcjvLP6NQWk1u+Fdjunyx/q9Gmlc3vFtFEz7swWCuKp4DavyUXFeWwSKt4dDRZyPPdSYrKxDPCncSaKeCv+G5sx4RyQLJjpx14tisnnZP0O5b5S6j3PfGzjgnNBhzl/xIzM5moUqPF7R2laOKh9CBdoQ== enpaul@vigil-nox | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8K74AXz6LBYfoXRbY1pKP+1rvi5BpjFOkg1uYuMM+q78toagSREpLrbjvPtoL8fkEFox4T9TUaME08ZP8560R6iRk35extTTiXquflEwvpsF+e9Lv8E712s/1ydJpkYoux1OohE4W5D9DjVMEW1tjXeb+9aDUcVml6YKMpKLpjEIVanyjHMN13XgswKZGoK3mVMnWxE36fbGVVfiFCvMr/BpjqGShRCxmvldzgq76i1BpTKi6omOjvpgRQcUJcDhYcHAUVSlNccgGLmlAPiUillA//pk84yczzH1dQBB6571Ab5ldoUDBU/hJ0W27aeOfrepup4hNuUt2oux+zAn+uetAuAWKU2Kd0Oo6L5IKObbAQLI0CXfyrmHlrYXwTyNMFleeOdw7s9lf2ra3YCYVXfMALdE6pp+HJLBxzg9kMBbTp6zkV7ZKi75AQhyBJA0s4+vRUccBtJit3Tls+aw/3rd9Dt9lLaXkE80khoKsUI0eiuXtPDlurGxkpcTe6Al/lChNA19pdKEUsBmhD6UUvMTYWlApmta/+xf0wDsSyHqJcnIGx8Qdtg3c4j1Ch+WXwbdOwk8XJrL0atWmv2ium1ll/arO2NFBmbwG1LG/lzJ1k/DoAiHrKrb1HdlwDk0O/7xF/zyC2mfVZKO36+g4XlA7wDJc0tB5vIymlEy2rw== enpaul@discovery | ||||
|     - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3ron1rnTp4t9iyB2VGY5jNuOuJcOgZD3KewjPqOijA enpaul@voyager | ||||
|   ansible: | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDN/E/zjwCruZf+mboBeBAtNFBInWMvdm6TjwpIg6jVoGgRmYQxEfIcqDSfBTQQ0gbyE3udTdTUDRLRu7ADktzL9J0IepEaYARfz8SANS/Hx2MR0NNy8DArrSFJCOillDA7E7UmNPIPeQl0O76p2ZjEDy6qZnTiW8eOtD7LCzJp4eGJanUPFhag8f4aSNbmiHGR25Zuk82w2/+KrqiI3gO0+jNlnPBf+XHNnFbtUIroupRfxgLdk1OahmkWHTSHkDtXiYrWIISarrHCgVqHTHo1KIX5+MPOH4S5VLB1kaY/O7+g/XlFrAciw8m0zjyBq0ILb+YTSrL9PYnSBtnHAVGJv2bB+TgCfF/nhQGqoqBqqQHFnX0y3JygmDTJMO+aE5wlvI5Laki7EHYPU4fL+Ge76l/dG9j2anw4/iHklbfk1UOxnLvJl593GAlILg1Kd8xx9VfYzVZ7GZym2zq3NI4uQ77T1H4iGoE67zarkn3peKacjX/KARq4weVvs3irHIHibnIuh/TGcS4eiQoNdPxsSA2wRKB6jeuXiV65F1rUDNGs80wcJmsAbZN8/u9Tt0o/Xc+L/LVhV0yrSeBUxzXtlaS+RfcteBXByO3xfC112Cj5grKVki5xWN9AY42Y6JhT3OyiO33dKUMEF/KfiEWWAfvQr/t1CI/rdcEbv3pyUw== enpaul@serico-nox-ansible | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIbXaUzVqDDKDSC1iO/nOmxIcJoOoMvXE+CJRobEdpkkYSBmlPfburJvGMDMQ3O/88OfgBrG5S7HKlbgVPGEII0Vpsk5iwzOk5Tmo03nLz02Ilx1xXYxTrjUSwnexzbHpluHmqunKEIUVTMHpDz2m4UPgZ4ECsGp9/6n6+n//uLeJ4fQUO9x4L+VMbpDrtfpKN7/P6U30XBIb9bZuKznVPtqTmCy/BFkxTkIn9QKqDh5d49FY/xkOjy1K9zTWb78DFzBRf4sGEykrp19N6inL0eRstGSZAKhqL+qdRXOy/7n6l0u+CdXWl9ZFVXRFhVdAhYOgkEvtuqoasK1Fk3OMqP6SflFanuDiFBostfgfrf8SUV+7CFvOuSpEWgTqx/jPFZV4Vr6wx5ZFVs02OzZ6TJFaEHaLvOE/R3iLOiuFcvqVNpvstLiyiigsj1+DwhDJcwOr3DaEsNdUbv0BTI2P03wtHJtBQw5CaVr5zCBDEeUsL0bBVQdq+6d0NT+CPJNxSZlTmmrBBbgkpupxdnmX6VVBYfXnylsE8UZxY1d7yxba3+Wzp2yvlr2MVocwQmMTPEqimIsW0hsQ8iXi1nrDXecSojlDAeu+LBFuaCxO8H59GrrVWVTI2dAPLEcP+stNGLHqKZuh62t5TnmxuMMi0SY6jH7KiKmusD4fYafzrlQ== enpaul@vigil-nox-ansible | ||||
|     - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5TGKururOa1Y+cbv8AWXYI5zhfZCDV0fsBG+33IYUc enpaul@ansible.voyager | ||||
|     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDN/E/zjwCruZf+mboBeBAtNFBInWMvdm6TjwpIg6jVoGgRmYQxEfIcqDSfBTQQ0gbyE3udTdTUDRLRu7ADktzL9J0IepEaYARfz8SANS/Hx2MR0NNy8DArrSFJCOillDA7E7UmNPIPeQl0O76p2ZjEDy6qZnTiW8eOtD7LCzJp4eGJanUPFhag8f4aSNbmiHGR25Zuk82w2/+KrqiI3gO0+jNlnPBf+XHNnFbtUIroupRfxgLdk1OahmkWHTSHkDtXiYrWIISarrHCgVqHTHo1KIX5+MPOH4S5VLB1kaY/O7+g/XlFrAciw8m0zjyBq0ILb+YTSrL9PYnSBtnHAVGJv2bB+TgCfF/nhQGqoqBqqQHFnX0y3JygmDTJMO+aE5wlvI5Laki7EHYPU4fL+Ge76l/dG9j2anw4/iHklbfk1UOxnLvJl593GAlILg1Kd8xx9VfYzVZ7GZym2zq3NI4uQ77T1H4iGoE67zarkn3peKacjX/KARq4weVvs3irHIHibnIuh/TGcS4eiQoNdPxsSA2wRKB6jeuXiV65F1rUDNGs80wcJmsAbZN8/u9Tt0o/Xc+L/LVhV0yrSeBUxzXtlaS+RfcteBXByO3xfC112Cj5grKVki5xWN9AY42Y6JhT3OyiO33dKUMEF/KfiEWWAfvQr/t1CI/rdcEbv3pyUw== enpaul@ansible.discovery | ||||
|   | ||||
							
								
								
									
										2
									
								
								skylab/core/roles/workstation/files/00-disable-user-list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								skylab/core/roles/workstation/files/00-disable-user-list
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| [org/gnome/login-screen] | ||||
| disable-user-list=true | ||||
| @@ -0,0 +1,2 @@ | ||||
| [org/gnome/mutter] | ||||
| experimental-features=['scale-monitor-framebuffer'] | ||||
							
								
								
									
										47
									
								
								skylab/core/roles/workstation/files/bashrc.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								skylab/core/roles/workstation/files/bashrc.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| if [ -f `which powerline-daemon` ]; then | ||||
|         powerline-daemon -q | ||||
|         POWERLINE_BASH_CONTINUATION=1 | ||||
|         POWERLINE_BASH_SELECT=1 | ||||
|         . /usr/share/powerline/bash/powerline.sh | ||||
| fi | ||||
|  | ||||
| export NVM_DIR="$HOME/.nvm" | ||||
| export PROJECTS_DIR="$HOME/projects" | ||||
|  | ||||
| function gg() { | ||||
|   cd "$PROJECTS_DIR/$1"; | ||||
|   if [ -f "$PROJECTS_DIR/$1/ansible.cfg" ]; then | ||||
|     ANSIBLE_CONFIG="$PROJECTS_DIR/$1/ansible.cfg" ANSIBLE_COLLECTIONS_PATH="$PROJECTS_DIR/$1/.ansible" poetry shell; | ||||
|   elif [ -f "$PROJECTS_DIR/$1/pyproject.toml" ]; then | ||||
|     poetry shell; | ||||
|   fi | ||||
| } | ||||
|  | ||||
| mpw() { | ||||
|     _copy() { | ||||
| 	if hash pbcopy 2>/dev/null; then | ||||
|             pbcopy | ||||
|         elif hash xclip 2>/dev/null; then | ||||
|             xclip -selection clip | ||||
|         else | ||||
|             cat; echo 2>/dev/null | ||||
|             return | ||||
|         fi | ||||
| 	echo >&2 "Copied!" | ||||
|     } | ||||
|  | ||||
|     # Empty the clipboard | ||||
|     :| _copy 2>/dev/null | ||||
|  | ||||
|     # Ask for the user's name and password if not yet known. | ||||
|     MPW_FULLNAME="Ethan Paul" | ||||
|  | ||||
|     # Start Master Password and copy the output. | ||||
|     printf %s "$(MPW_FULLNAME=$MPW_FULLNAME command mpw "$@")" | _copy | ||||
| } | ||||
|  | ||||
| alias explorer='nautilus' | ||||
| alias doc='cd ~/Documents' | ||||
| alias dn='cd ~/Downloads' | ||||
| alias prun="poetry run" | ||||
| alias psync="poetry install --remove-untracked" | ||||
							
								
								
									
										3
									
								
								skylab/core/roles/workstation/files/gdm-system
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								skylab/core/roles/workstation/files/gdm-system
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| user-db:user | ||||
| system-db:gdm | ||||
| file-db:/usr/share/gdm/greeter-dconf-defaults | ||||
							
								
								
									
										2
									
								
								skylab/core/roles/workstation/files/gdm-user
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								skylab/core/roles/workstation/files/gdm-user
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| user-db:user | ||||
| system-db:local | ||||
							
								
								
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/lightningbug-dark.tar.gz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/lightningbug-dark.tar.gz
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/multimc.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/multimc.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 42 KiB | 
							
								
								
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/wallpaper-discovery.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/wallpaper-discovery.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 664 KiB | 
							
								
								
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/wallpaper-voyager.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								skylab/core/roles/workstation/files/wallpaper-voyager.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 243 KiB | 
							
								
								
									
										6
									
								
								skylab/core/roles/workstation/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								skylab/core/roles/workstation/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| --- | ||||
| - name: dconf-update | ||||
|   become: true | ||||
|   changed_when: true | ||||
|   ansible.builtin.command: | ||||
|     cmd: dconf update | ||||
							
								
								
									
										144
									
								
								skylab/core/roles/workstation/tasks/environment.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								skylab/core/roles/workstation/tasks/environment.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| --- | ||||
| - name: Install user bashrc | ||||
|   become: true | ||||
|   ansible.builtin.copy: | ||||
|     src: bashrc.sh | ||||
|     dest: ~{{ item }}/.bashrc_ansible | ||||
|     owner: "{{ ansible_user }}" | ||||
|     group: "{{ item }}" | ||||
|     mode: 0644 | ||||
|   loop: "{{ _local_human_users }}" | ||||
|  | ||||
| - name: Configure user bashrc loading | ||||
|   become: true | ||||
|   ansible.builtin.lineinfile: | ||||
|     path: ~{{ item }}/.bashrc | ||||
|     line: source ~/.bashrc_ansible | ||||
|     state: present | ||||
|   loop: "{{ _local_human_users }}" | ||||
|  | ||||
| - name: Configure local bash completions loading | ||||
|   become: true | ||||
|   ansible.builtin.lineinfile: | ||||
|     path: ~{{ item }}/.bashrc | ||||
|     line: source ~/.config/bash_completions | ||||
|     state: present | ||||
|   loop: "{{ _local_human_users }}" | ||||
|  | ||||
| - name: Configure bash completions | ||||
|   become: true | ||||
|   ansible.builtin.blockinfile: | ||||
|     path: ~{{ item }}/.config/bash_completions | ||||
|     create: true | ||||
|     block: >- | ||||
|       function _gg_completion() { | ||||
|           local cur=${COMP_WORDS[COMP_CWORD]}; | ||||
|           COMPREPLY=( $(compgen -W "$(command ls $PROJECTS_DIR)" -- $cur) ); | ||||
|       } | ||||
|  | ||||
|       complete -F _gg_completion gg | ||||
|     owner: "{{ ansible_user }}" | ||||
|     group: "{{ item }}" | ||||
|     mode: 0664 | ||||
|   loop: "{{ _local_human_users }}" | ||||
|  | ||||
| - name: Enforce ownership of the SSH keys | ||||
|   become: true | ||||
|   ansible.builtin.file: | ||||
|     path: ~{{ item.0 }}/.ssh/id_ed25519{{ item.1 }} | ||||
|     state: file | ||||
|     owner: "{{ item.0 }}" | ||||
|     group: "{{ item.0 }}" | ||||
|   loop: "{{ _local_human_users | product(['', '.pub']) }}" | ||||
|  | ||||
| - name: Configure dconf setting | ||||
|   become: true | ||||
|   block: | ||||
|     - name: Create dconf config directories | ||||
|       ansible.builtin.file: | ||||
|         path: "{{ item }}" | ||||
|         state: directory | ||||
|         owner: root | ||||
|         group: "{{ ansible_user }}" | ||||
|         mode: 0755 | ||||
|       loop: | ||||
|         - /etc/dconf/profile | ||||
|         - /etc/dconf/db/gdm.d | ||||
|  | ||||
|     - name: Create global dconf config | ||||
|       ansible.builtin.copy: | ||||
|         src: gdm-system | ||||
|         dest: /etc/dconf/profile/gdm | ||||
|         owner: root | ||||
|         group: "{{ ansible_user }}" | ||||
|         mode: 0644 | ||||
|       notify: | ||||
|         - dconf-update | ||||
|  | ||||
|     - name: Create user dconf config | ||||
|       ansible.builtin.copy: | ||||
|         src: gdm-user | ||||
|         dest: /etc/dconf/profile/user | ||||
|         owner: root | ||||
|         group: "{{ ansible_user }}" | ||||
|         mode: 0644 | ||||
|       notify: | ||||
|         - dconf-update | ||||
|  | ||||
|     - name: Disable user list | ||||
|       ansible.builtin.copy: | ||||
|         src: 00-disable-user-list | ||||
|         dest: /etc/dconf/db/gdm.d/00-disable-user-list | ||||
|         owner: root | ||||
|         group: "{{ ansible_user }}" | ||||
|         mode: 0644 | ||||
|       notify: | ||||
|         - dconf-update | ||||
|  | ||||
|     - name: Enable fractional scaling | ||||
|       ansible.builtin.copy: | ||||
|         src: 00-enable-fractional-scaling | ||||
|         dest: /etc/dconf/db/local.d/00-enable-fractional-scaling | ||||
|         owner: root | ||||
|         group: "{{ ansible_user }}" | ||||
|         mode: 0644 | ||||
|       notify: | ||||
|         - dconf-update | ||||
|  | ||||
| - name: Install themes | ||||
|   become: true | ||||
|   block: | ||||
|     - name: Create local themes directory | ||||
|       ansible.builtin.file: | ||||
|         path: ~{{ item }}/.themes | ||||
|         state: directory | ||||
|         owner: "{{ item }}" | ||||
|         group: "{{ item }}" | ||||
|         mode: 0750 | ||||
|       loop: "{{ _local_human_users }}" | ||||
|  | ||||
|     - name: Unarchive LightningBug into local directory | ||||
|       ansible.builtin.unarchive: | ||||
|         src: lightningbug-dark.tar.gz | ||||
|         dest: ~{{ item }}/.themes | ||||
|         owner: "{{ item }}" | ||||
|         group: "{{ item }}" | ||||
|       loop: "{{ _local_human_users }}" | ||||
|  | ||||
| - name: Install wallpaper | ||||
|   become: true | ||||
|   ansible.builtin.copy: | ||||
|     src: wallpaper-{{ inventory_hostname }}.jpg | ||||
|     dest: ~{{ item }}/Pictures/wallpaper.jpg | ||||
|     owner: "{{ item }}" | ||||
|     group: "{{ item }}" | ||||
|   loop: "{{ _local_human_users }}" | ||||
|  | ||||
| - name: Link external media directory | ||||
|   become: true | ||||
|   ansible.builtin.file: | ||||
|     path: ~{{ item }}/Drives | ||||
|     src: /run/media/{{ item }} | ||||
|     state: link | ||||
|     force: true | ||||
|   loop: "{{ _local_human_users }}" | ||||
							
								
								
									
										59
									
								
								skylab/core/roles/workstation/tasks/install_mpw.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								skylab/core/roles/workstation/tasks/install_mpw.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| --- | ||||
| - name: Check for MPW binary | ||||
|   ansible.builtin.stat: | ||||
|     path: /usr/local/bin/mpw | ||||
|   register: _mpw_binary_stat | ||||
|  | ||||
| - name: Install MPW | ||||
|   when: (not _mpw_binary_stat.stat.exists) or (force_reinstall | default(false)) | ||||
|   block: | ||||
|     - name: Install build dependencies on Fedora | ||||
|       when: ansible_distribution == "Fedora" | ||||
|       become: true | ||||
|       ansible.builtin.dnf: | ||||
|         name: | ||||
|           - libsodium-devel | ||||
|         state: present | ||||
|  | ||||
|     - name: Create temporary build directory | ||||
|       ansible.builtin.tempfile: | ||||
|         prefix: ansible.build.mpw | ||||
|         state: directory | ||||
|       register: _mpw_build_dir | ||||
|  | ||||
|     - name: Download MPW source | ||||
|       ansible.builtin.git: | ||||
|         repo: https://gitlab.com/MasterPassword/MasterPassword.git | ||||
|         version: 344771db | ||||
|         recursive: false  # does *not* clone submodules | ||||
|         dest: "{{ _mpw_build_dir.path }}" | ||||
|  | ||||
|     # God I hate this | ||||
|     - name: Patch .gitmodules to use HTTPS | ||||
|       ansible.builtin.replace: | ||||
|         path: "{{ _mpw_build_dir.path }}/.gitmodules" | ||||
|         regexp: "url = git://" | ||||
|         replace: "url = https://" | ||||
|  | ||||
|     - name: Initialize submodules | ||||
|       ansible.builtin.command: | ||||
|         cmd: git submodule update --init | ||||
|         chdir: "{{ _mpw_build_dir.path }}" | ||||
|  | ||||
|     - name: Build MasterPassword binary | ||||
|       ansible.builtin.command: | ||||
|         cmd: bash build | ||||
|         chdir: "{{ _mpw_build_dir.path }}/platform-independent/cli-c/" | ||||
|  | ||||
|     - name: Copy binary to system path | ||||
|       become: true | ||||
|       ansible.builtin.copy: | ||||
|         remote_src: true | ||||
|         src: "{{ _mpw_build_dir.path }}/platform-independent/cli-c/mpw" | ||||
|         dest: "/usr/local/bin" | ||||
|         mode: 0755 | ||||
|   always: | ||||
|     - name: Remove temporary directory | ||||
|       ansible.builtin.file: | ||||
|         path: "{{ _mpw_build_dir.path }}" | ||||
|         state: absent | ||||
							
								
								
									
										79
									
								
								skylab/core/roles/workstation/tasks/install_multimc.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								skylab/core/roles/workstation/tasks/install_multimc.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| --- | ||||
| - name: Check whether binary exists | ||||
|   become: true | ||||
|   ansible.builtin.stat: | ||||
|     path: "~{{ local_username }}/.local/bin/MultiMC" | ||||
|   register: _multimc_stat | ||||
|  | ||||
| - name: Install MultiMC | ||||
|   when: (not _multimc_stat.stat.exists) or (force_reinstall | default(false)) | ||||
|   block: | ||||
|     - name: Create temp dir | ||||
|       ansible.builtin.tempfile: | ||||
|         state: directory | ||||
|       register: _multimc_tempdir | ||||
|  | ||||
|     - name: Download and unpack distribution archive | ||||
|       ansible.builtin.unarchive: | ||||
|         src: https://files.multimc.org/downloads/mmc-stable-lin64.tar.gz | ||||
|         remote_src: true | ||||
|         dest: "{{ _multimc_tempdir.path }}" | ||||
|  | ||||
|     - name: Ensure ~/.local/share/ exists | ||||
|       become: true | ||||
|       ansible.builtin.file: | ||||
|         path: ~{{ local_username }}/.local/share | ||||
|         state: directory | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0700 | ||||
|  | ||||
|     - name: Ensure ~/.local/bin/ exists | ||||
|       become: true | ||||
|       ansible.builtin.file: | ||||
|         path: ~{{ local_username }}/.local/bin | ||||
|         state: directory | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0700 | ||||
|  | ||||
|     - name: Copy MMC distribution to ~/.local/share/ | ||||
|       become: true | ||||
|       ansible.builtin.copy: | ||||
|         remote_src: true | ||||
|         src: "{{ _multimc_tempdir.path }}/MultiMC/" | ||||
|         dest: "~{{ local_username }}/.local/share/multimc" | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0700 | ||||
|  | ||||
|     - name: Link MMC binary into ~/.local/bin/ | ||||
|       become: true | ||||
|       ansible.builtin.file: | ||||
|         state: link | ||||
|         src: ~{{ local_username }}/.local/share/multimc/MultiMC | ||||
|         path: ~{{ local_username }}/.local/bin/MultiMC | ||||
|  | ||||
|     - name: Copy application icon | ||||
|       become: true | ||||
|       ansible.builtin.copy: | ||||
|         src: multimc.png | ||||
|         dest: ~{{ local_username }}/.local/share/icons/multimc.png | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0755 | ||||
|  | ||||
|     - name: Template application desktop entry | ||||
|       become: true | ||||
|       ansible.builtin.template: | ||||
|         src: multimc.desktop.j2 | ||||
|         dest: ~{{ local_username }}/.local/share/applications/multimc.desktop | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0755 | ||||
|  | ||||
|   always: | ||||
|     - name: Delete temp dir | ||||
|       ansible.builtin.file: | ||||
|         path: "{{ _multimc_tempdir.path }}" | ||||
|         state: absent | ||||
							
								
								
									
										0
									
								
								skylab/core/roles/workstation/tasks/install_nvm.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								skylab/core/roles/workstation/tasks/install_nvm.yml
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										27
									
								
								skylab/core/roles/workstation/tasks/install_pipx.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								skylab/core/roles/workstation/tasks/install_pipx.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| --- | ||||
| - name: Create install directory | ||||
|   become: true | ||||
|   ansible.builtin.file: | ||||
|     path: /opt/pipx | ||||
|     state: directory | ||||
|     owner: "{{ ansible_user }}" | ||||
|     group: "{{ skylab_group_admin.name }}" | ||||
|     mode: 0755 | ||||
|  | ||||
| - name: Create install venv | ||||
|   ansible.builtin.command: | ||||
|     cmd: python3 -m venv /opt/pipx | ||||
|     creates: /opt/pipx/bin/python | ||||
|  | ||||
| - name: Install pipx | ||||
|   ansible.builtin.pip: | ||||
|     name: | ||||
|       - pipx | ||||
|     executable: /opt/pipx/bin/pip | ||||
|  | ||||
| - name: Link pipx binary into system path | ||||
|   become: true | ||||
|   ansible.builtin.file: | ||||
|     state: link | ||||
|     src: /opt/pipx/bin/pipx | ||||
|     path: /usr/local/bin/pipx | ||||
							
								
								
									
										1
									
								
								skylab/core/roles/workstation/tasks/install_poetry.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								skylab/core/roles/workstation/tasks/install_poetry.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| --- | ||||
							
								
								
									
										53
									
								
								skylab/core/roles/workstation/tasks/install_tor_browser.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								skylab/core/roles/workstation/tasks/install_tor_browser.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| --- | ||||
| - name: Check whether Tor Browser is already installed | ||||
|   become: true | ||||
|   ansible.builtin.stat: | ||||
|     path: "~{{ local_username }}/.local/share/tor-browser/start-tor-browser.desktop" | ||||
|   register: _torbrowser_stat | ||||
|  | ||||
| - name: Install Tor Browser | ||||
|   when: not _torbrowser_stat.stat.exists | ||||
|   block: | ||||
|     - name: Create temp dir | ||||
|       ansible.builtin.tempfile: | ||||
|         state: directory | ||||
|       register: _torbrowser_tempdir | ||||
|  | ||||
|     - name: Download and unpack distribution archive | ||||
|       ansible.builtin.unarchive: | ||||
|         src: https://dist.torproject.org/torbrowser/11.0.10/tor-browser-linux64-11.0.10_en-US.tar.xz | ||||
|         remote_src: true | ||||
|         dest: "{{ _torbrowser_tempdir.path }}" | ||||
|  | ||||
|     - name: Ensure ~/.local/share/ exists | ||||
|       become: true | ||||
|       ansible.builtin.file: | ||||
|         path: ~{{ local_username }}/.local/share | ||||
|         state: directory | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0700 | ||||
|  | ||||
|     - name: Copy Tor Browser distribution to ~/.local/share/ | ||||
|       become: true | ||||
|       ansible.builtin.copy: | ||||
|         remote_src: true | ||||
|         src: "{{ _torbrowser_tempdir.path }}/tor-browser_en-US/" | ||||
|         dest: "~{{ local_username }}/.local/share/tor-browser" | ||||
|         owner: "{{ local_username }}" | ||||
|         group: "{{ local_username }}" | ||||
|         mode: 0700 | ||||
|  | ||||
|     - name: Register application | ||||
|       become: true | ||||
|       become_user: "{{ local_username }}" | ||||
|       changed_when: true | ||||
|       ansible.builtin.command: | ||||
|         cmd: ./start-tor-browser.desktop | ||||
|         chdir: ~{{ local_username }}/.local/share/tor-browser | ||||
|  | ||||
|   always: | ||||
|     - name: Delete temp dir | ||||
|       ansible.builtin.file: | ||||
|         path: "{{ _torbrowser_tempdir.path }}" | ||||
|         state: absent | ||||
							
								
								
									
										40
									
								
								skylab/core/roles/workstation/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								skylab/core/roles/workstation/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| --- | ||||
| - name: Include access vars | ||||
|   ansible.builtin.include_vars: | ||||
|     file: vars/access.yaml | ||||
|  | ||||
| - name: Determine local user accounts | ||||
|   when: skylab_targets | intersect(item.targets | default([])) | ||||
|   vars: | ||||
|     _local_users: [] | ||||
|   ansible.builtin.set_fact: | ||||
|     _local_users: "{{ _local_users + [item] }}" | ||||
|   loop: "{{ skylab_accounts }}" | ||||
|   loop_control: | ||||
|     label: "{{ item.name }},{{ item.uid }}" | ||||
|  | ||||
| - name: Determine local human user accounts | ||||
|   when: not (item.service | default(false)) | ||||
|   vars: | ||||
|     _local_human_users: [] | ||||
|   ansible.builtin.set_fact: | ||||
|     _local_human_users: "{{ _local_human_users + [item.name] }}" | ||||
|   loop: "{{ _local_users }}" | ||||
|   loop_control: | ||||
|     label: "{{ item.name }},{{ item.uid }}" | ||||
|  | ||||
| - name: Determine local admin user accounts | ||||
|   when: item.admin | default(false) | ||||
|   vars: | ||||
|     _local_admin_users: [] | ||||
|   ansible.builtin.set_fact: | ||||
|     _local_admin_users: "{{ _local_admin_users + [item.name] }}" | ||||
|   loop: "{{ _local_users }}" | ||||
|   loop_control: | ||||
|     label: "{{ item.name }},{{ item.uid }}" | ||||
|  | ||||
| - name: Install software | ||||
|   ansible.builtin.import_tasks: software.yml | ||||
|  | ||||
| - name: Configure environment | ||||
|   ansible.builtin.import_tasks: environment.yml | ||||
							
								
								
									
										121
									
								
								skylab/core/roles/workstation/tasks/software.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								skylab/core/roles/workstation/tasks/software.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| --- | ||||
| - name: Install repositories on Fedora | ||||
|   become: true | ||||
|   when: ansible_distribution == "Fedora" | ||||
|   block: | ||||
|     - name: Install RPMFusion repositories | ||||
|       ansible.builtin.dnf: | ||||
|         name: | ||||
|           - https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm | ||||
|           - https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm | ||||
|         state: present | ||||
|         disable_gpg_check: true | ||||
|  | ||||
|     - name: Install Docker CE repository | ||||
|       ansible.builtin.yum_repository: | ||||
|         name: docker-ce-stable | ||||
|         description: Docker CE Stable - $basearch | ||||
|         baseurl: https://download.docker.com/linux/fedora/$releasever/$basearch/stable | ||||
|         enabled: true | ||||
|         gpgcheck: true | ||||
|         gpgkey: https://download.docker.com/linux/fedora/gpg | ||||
|  | ||||
|     - name: Install VSCode repository | ||||
|       ansible.builtin.yum_repository: | ||||
|         name: vscode | ||||
|         description: Visual Studio Code | ||||
|         baseurl: https://packages.microsoft.com/yumrepos/vscode | ||||
|         enabled: true | ||||
|         gpgcheck: true | ||||
|         gpgkey: https://packages.microsoft.com/keys/microsoft.asc | ||||
|  | ||||
|     - name: Enable Signal-Desktop COPR repository | ||||
|       community.general.copr: | ||||
|         name: luminoso/Signal-Desktop | ||||
|         state: enabled | ||||
|  | ||||
| - name: Install packages on Fedora | ||||
|   become: true | ||||
|   when: ansible_distribution == "Fedora" | ||||
|   ansible.builtin.dnf: | ||||
|     name: | ||||
|       - arc-theme | ||||
|       - cmake | ||||
|       - code  # visual studio code | ||||
|       - deluge | ||||
|       - docker-ce | ||||
|       - gcc | ||||
|       - gcc-c++ | ||||
|       - gnome-tweaks | ||||
|       - gnome-shell-extension-material-shell | ||||
|       - gnome-shell-extension-openweather | ||||
|       - gnome-shell-extension-system-monitor-applet | ||||
|       - gnome-shell-extension-vertical-overview | ||||
|       - gnupg2 | ||||
|       - guvcview | ||||
|       - java-17-openjdk | ||||
|       - jq | ||||
|       - libffi-devel | ||||
|       - libvirt | ||||
|       - libvirt-devel | ||||
|       - libxml2-devel | ||||
|       - mediawriter | ||||
|       - ncurses-devel | ||||
|       - NetworkManager-tui | ||||
|       - pinta | ||||
|       - powerline | ||||
|       - python27 | ||||
|       - python36 | ||||
|       - python37 | ||||
|       - python38 | ||||
|       - python39 | ||||
|       - python310 | ||||
|       - ShellCheck | ||||
|       - signal-desktop | ||||
|       - steam | ||||
|       - systemd-devel | ||||
|       - texlive-fontawesome5 | ||||
|       - texlive-roboto | ||||
|       - texlive-scheme-tetex | ||||
|       - texlive-sourcesanspro | ||||
|       - virt-manager | ||||
|       - vlc | ||||
|       - xclip | ||||
|       - yarnpkg | ||||
|     state: present | ||||
|  | ||||
| - name: Install unsigned packages on Fedora | ||||
|   when: ansible_distribution == "Fedora" | ||||
|   become: true | ||||
|   ansible.builtin.dnf: | ||||
|     name: | ||||
|       # draw.io/diagrams.net | ||||
|       - https://github.com/jgraph/drawio-desktop/releases/download/v17.4.2/drawio-x86_64-17.4.2.rpm | ||||
|       # zoom | ||||
|       - https://zoom.us/client/latest/zoom_x86_64.rpm | ||||
|     state: present | ||||
|     disable_gpg_check: true | ||||
|  | ||||
| - ansible.builtin.import_tasks: install_mpw.yml | ||||
| - ansible.builtin.import_tasks: install_nvm.yml | ||||
| - ansible.builtin.import_tasks: install_pipx.yml | ||||
| - ansible.builtin.import_tasks: install_poetry.yml | ||||
| - ansible.builtin.import_tasks: install_postman.yml | ||||
| - ansible.builtin.import_tasks: install_rustup.yml | ||||
| - ansible.builtin.import_tasks: install_typora.yml | ||||
|  | ||||
| # It is now day eight hundred and thirty nine of begging the ansible devs to let | ||||
| # me loop over blocks. pls bcoca i have a family | ||||
| - name: Install Tor Browser | ||||
|   ansible.builtin.include_tasks: | ||||
|     file: install_tor_browser.yml | ||||
|   loop: "{{ _local_human_users }}" | ||||
|   loop_control: | ||||
|     loop_var: local_username | ||||
|  | ||||
| - name: Install MultiMC | ||||
|   ansible.builtin.include_tasks: | ||||
|     file: install_multimc.yml | ||||
|   loop: "{{ _local_human_users }}" | ||||
|   loop_control: | ||||
|     loop_var: local_username | ||||
| @@ -0,0 +1,9 @@ | ||||
| [Desktop Entry] | ||||
| Name=MultiMC | ||||
| Comment=Minecraft environment manager | ||||
| Exec="/home/{{ local_username }}/.local/bin/MultiMC" | ||||
| Terminal=false | ||||
| Type=Application | ||||
| Icon="/home/{{ local_username }}/.local/share/icons/multimc.png" | ||||
| Categories=Gaming;Graphics; | ||||
| TryExec="/home/{{ local_username }}/.local/bin/MultiMC" | ||||
							
								
								
									
										3
									
								
								skylab/infra/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								skylab/infra/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # Ansible Collection - skylab.infra | ||||
|  | ||||
| Documentation for the collection. | ||||
							
								
								
									
										16
									
								
								skylab/infra/galaxy.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								skylab/infra/galaxy.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| 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: [] | ||||
|  | ||||
| dependencies: | ||||
|   community.general: ">=6.5.0,<7.0" | ||||
|   ansible.posix: ">=1.5.1,<2.0" | ||||
							
								
								
									
										2
									
								
								skylab/infra/meta/runtime.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								skylab/infra/meta/runtime.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| --- | ||||
| requires_ansible: '>=2.9.10' | ||||
							
								
								
									
										230
									
								
								skylab/infra/playbooks/bootstrap.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								skylab/infra/playbooks/bootstrap.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| --- | ||||
| - name: Prompt for parameters | ||||
|   hosts: localhost | ||||
|   gather_facts: false | ||||
|   vars_prompt: | ||||
|   - name: bootstrap_hostname | ||||
|     prompt: Enter hostname (or IP address) of bootstrap target | ||||
|     private: false | ||||
|   - name: bootstrap_username | ||||
|     prompt: Enter username to use for connecting to boostrap target | ||||
|     default: root | ||||
|     private: false | ||||
|   - name: bootstrap_password | ||||
|     prompt: Enter password to use for connecting to boostrap target | ||||
|     private: true | ||||
|     default: skylab | ||||
|   - name: bootstrap_port | ||||
|     prompt: Enter SSH port to connect to on bootstrap target | ||||
|     default: 22 | ||||
|     private: false | ||||
|   tasks: | ||||
|   - name: Add boostrap host | ||||
|     changed_when: false | ||||
|     ansible.builtin.add_host: | ||||
|       hostname: bootstrap | ||||
|       ansible_host: "{{ bootstrap_hostname }}" | ||||
|       ansible_user: "{{ bootstrap_username }}" | ||||
|       ansible_ssh_pass: "{{ bootstrap_password }}" | ||||
|       ansible_port: "{{ bootstrap_port }}" | ||||
|  | ||||
|   - name: Test connection | ||||
|     delegate_to: bootstrap | ||||
|     delegate_facts: true | ||||
|     vars: | ||||
|       ansible_host_key_checking: false | ||||
|     ansible.builtin.ping: {} | ||||
|  | ||||
| - name: Bootstrap remote | ||||
|   hosts: bootstrap | ||||
|   vars: | ||||
|     ansible_host_key_checking: false | ||||
|   vars_prompt: | ||||
|   - name: skylab_ansible_vault_password | ||||
|     prompt: Enter Ansible vault password for generating user secrets | ||||
|     private: true | ||||
|     confirm: true | ||||
|   tasks: | ||||
|   - name: Check OS requirements | ||||
|     ansible.builtin.assert: | ||||
|       that: | ||||
|       - ansible_distribution == 'Rocky' | ||||
|       - ansible_distribution_major_version in ['8', '9'] | ||||
|       success_msg: >- | ||||
|         Host is running supported OS {{ ansible_distribution }} {{ ansible_distribution_version }} | ||||
|       fail_msg: >- | ||||
|         Unsupported operating system ({{ ansible_distribution }} {{ ansible_distribution_major_version }}), | ||||
|         only RockyLinux 8 and RockyLinux 9 are supported. | ||||
|  | ||||
|   - name: Check that management keys are defined | ||||
|     ansible.builtin.assert: | ||||
|       that: | ||||
|         - skylab_mgmt is defined | ||||
|         - skylab_mgmt.sshkeys != [] | ||||
|       success_msg: >- | ||||
|         Found {{ skylab_mgmt.sshkeys | length }} SSH keys to install to the Ansible management user | ||||
|       fail_msg: >- | ||||
|         No management keys were found for installation to the Ansible management user. Aborting to avoid | ||||
|         locking out SSH access to the boostrap host. Please define the 'skylab_mgmt.sshkeys' variable with | ||||
|         a list of SSH public keys to install to the Ansible management user. | ||||
|  | ||||
|   - name: Install RockyLinux python bindings | ||||
|     become: true | ||||
|     ansible.builtin.dnf: | ||||
|       state: present | ||||
|       name: | ||||
|         - libffi-devel | ||||
|         - python3-devel | ||||
|         - python3-libselinux | ||||
|         - python3-policycoreutils | ||||
|         - python3-firewall | ||||
|  | ||||
|   - name: Create mgmt group | ||||
|     become: true | ||||
|     ansible.builtin.group: | ||||
|       name: "{{ skylab_mgmt.group }}" | ||||
|       state: present | ||||
|       gid: "{{ skylab_mgmt.id }}" | ||||
|  | ||||
|   - name: Generate mgmt user account password | ||||
|     delegate_to: localhost | ||||
|     no_log: true | ||||
|     changed_when: false | ||||
|     ansible.builtin.shell: | ||||
|       cmd: > | ||||
|         command mpw -qq -F none -t max -u {{ skylab_mgmt.user }} {{ ansible_host }} -p <<< | ||||
|         '{{ skylab_ansible_vault_password }}' | | ||||
|         python3 -c 'import crypt; print(crypt.crypt(input(), crypt.mksalt(crypt.METHOD_SHA512)))' | ||||
|       executable: /bin/bash | ||||
|     register: _password_mgmt | ||||
|  | ||||
|   - name: Update mgmt user account | ||||
|     become: true | ||||
|     ansible.builtin.user: | ||||
|       name: "{{ skylab_mgmt.user }}" | ||||
|       state: present | ||||
|       group: "{{ skylab_mgmt.group }}" | ||||
|       groups: | ||||
|         - "{{ skylab_mgmt.group }}" | ||||
|         - wheel | ||||
|       uid: "{{ skylab_mgmt.id }}" | ||||
|       password: "{{ _password_mgmt.stdout }}" | ||||
|  | ||||
|   - name: Update mgmt user authorized keys | ||||
|     become: true | ||||
|     ansible.posix.authorized_key: | ||||
|       user: "{{ skylab_mgmt.user }}" | ||||
|       exclusive: true | ||||
|       key: "{{ skylab_mgmt.sshkeys | join('\n') }}" | ||||
|  | ||||
|   - name: Remove mgmt user group | ||||
|     become: true | ||||
|     ansible.builtin.group: | ||||
|       name: "{{ skylab_mgmt.user }}" | ||||
|       state: absent | ||||
|  | ||||
|   - name: Update root user authorized keys | ||||
|     become: true | ||||
|     ansible.posix.authorized_key: | ||||
|       user: root | ||||
|       exclusive: true | ||||
|       key: "" | ||||
|  | ||||
|   - name: Disable sudo password for WHEEL group | ||||
|     become: true | ||||
|     ansible.builtin.copy: | ||||
|       content: "%wheel ALL=(ALL) NOPASSWD: ALL" | ||||
|       dest: /etc/sudoers.d/30-wheel | ||||
|       owner: root | ||||
|       group: "{{ skylab_mgmt.group }}" | ||||
|       mode: 0644 | ||||
|  | ||||
|   - name: Disable SSHD password auth | ||||
|     become: true | ||||
|     ansible.builtin.replace: | ||||
|       path: /etc/ssh/sshd_config | ||||
|       regexp: '^(#?)PasswordAuthentication .*$' | ||||
|       replace: PasswordAuthentication no | ||||
|  | ||||
|   - name: Disable SSHD root login | ||||
|     become: true | ||||
|     ansible.builtin.replace: | ||||
|       path: /etc/ssh/sshd_config | ||||
|       regexp: '^(#?)PermitRootLogin .*$' | ||||
|       replace: PermitRootLogin no | ||||
|  | ||||
|   - name: Update SSHD mgmt port | ||||
|     become: true | ||||
|     ansible.builtin.replace: | ||||
|       path: /etc/ssh/sshd_config | ||||
|       regexp: '^(#?)Port .*$' | ||||
|       replace: Port {{ skylab_mgmt.sshport }} | ||||
|  | ||||
|   - name: Grant SSHD permissions on the mgmt port | ||||
|     become: true | ||||
|     community.general.seport: | ||||
|       ports: "{{ skylab_mgmt.sshport }}" | ||||
|       proto: tcp | ||||
|       setype: ssh_port_t | ||||
|       state: present | ||||
|  | ||||
|   - name: Install Firewalld | ||||
|     become: true | ||||
|     ansible.builtin.dnf: | ||||
|       name: firewalld | ||||
|       state: present | ||||
|  | ||||
|   - name: Enable Firewalld | ||||
|     become: true | ||||
|     ansible.builtin.service: | ||||
|       name: firewalld | ||||
|       enabled: true | ||||
|  | ||||
|   - name: Grant SSHD firewall access to the mgmt port | ||||
|     become: true | ||||
|     ansible.posix.firewalld: | ||||
|       port: "{{ skylab_mgmt.sshport }}/tcp" | ||||
|       state: enabled | ||||
|       permanent: true | ||||
|  | ||||
|   - name: Revoke SSHD firewall access to default port | ||||
|     become: true | ||||
|     ansible.posix.firewalld: | ||||
|       service: ssh | ||||
|       permanent: true | ||||
|       state: disabled | ||||
|  | ||||
|   - name: Update OS | ||||
|     become: true | ||||
|     ansible.builtin.dnf: | ||||
|       name: "*" | ||||
|       state: latest | ||||
|       allowerasing: true | ||||
|  | ||||
|   - name: Generate root user account password | ||||
|     delegate_to: localhost | ||||
|     no_log: true | ||||
|     changed_when: false | ||||
|     ansible.builtin.shell: | ||||
|       cmd: > | ||||
|         command mpw -qq -F none -t max -u root {{ ansible_host }} -p <<< | ||||
|         '{{ skylab_ansible_vault_password }}' | | ||||
|         python3 -c 'import crypt; print(crypt.crypt(input(), crypt.mksalt(crypt.METHOD_SHA512)))' | ||||
|       executable: /bin/bash | ||||
|     register: _password_root | ||||
|  | ||||
|   - name: Update root user account | ||||
|     become: true | ||||
|     ansible.builtin.user: | ||||
|       name: root | ||||
|       state: present | ||||
|       password: "{{ _password_root.stdout }}" | ||||
|  | ||||
|   - name: Create SkyLab directory | ||||
|     become: true | ||||
|     ansible.builtin.file: | ||||
|       state: directory | ||||
|       path: "{{ skylab_state_dir }}" | ||||
|       owner: "{{ skylab_mgmt.user }}" | ||||
|       group: "{{ skylab_mgmt.group }}" | ||||
|       mode: 0750 | ||||
							
								
								
									
										46
									
								
								skylab/infra/playbooks/cloud.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								skylab/infra/playbooks/cloud.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| --- | ||||
| - name: Provision DigitalOcean cloud | ||||
|   hosts: localhost | ||||
|   vars: | ||||
|     terraform_backend: "postgres://{{ skylab_tfstate_backend.username }}:{{ skylab_tfstate_backend.password }}@{{ skylab_tfstate_backend.hostname }}:{{ skylab_tfstate_backend.port }}/{{ skylab_tfstate_backend.schema }}" | ||||
|   tasks: | ||||
|   - name: Deploy terraform config | ||||
|     block: | ||||
|     - name: Create temp plan file | ||||
|       changed_when: false | ||||
|       ansible.builtin.tempfile: | ||||
|         state: file | ||||
|         prefix: skylab | ||||
|         suffix: tfplan | ||||
|       register: _tfplan_tempfile | ||||
|  | ||||
|     # Generating a plan file before yeeting a deployment into the | ||||
|     # wind helps to ensure that the syntax is correct, backend and | ||||
|     # state are valid, and all the plumbing is working as expected. | ||||
|     # We don't want errors when we deploy, so it's better to | ||||
|     # generate the plan first | ||||
|     - name: Initialize terraform backend and generate plan file | ||||
|       community.general.terraform: | ||||
|         state: planned | ||||
|         project_path: terraform/ | ||||
|         backend_config: | ||||
|           conn_str: "{{ terraform_backend }}" | ||||
|         force_init: true | ||||
|         init_reconfigure: true | ||||
|         plan_file: "{{ _tfplan_tempfile.path }}" | ||||
|  | ||||
|     # TODO: update to take DO token from invocation args rather than | ||||
|     # implicit env var | ||||
|     - name: Apply terraform plan | ||||
|       community.general.terraform: | ||||
|         state: present | ||||
|         project_path: terraform/ | ||||
|         backend_config: | ||||
|           conn_str: "{{ terraform_backend }}" | ||||
|         plan_file: "{{ _tfplan_tempfile.path }}" | ||||
|     always: | ||||
|     - name: Remove temp plan file | ||||
|       changed_when: false | ||||
|       ansible.builtin.file: | ||||
|         path: "{{ _tfplan_tempfile.path }}" | ||||
|         state: absent | ||||
							
								
								
									
										57
									
								
								skylab/infra/playbooks/terraform/domain.allaroundhere.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								skylab/infra/playbooks/terraform/domain.allaroundhere.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| resource "digitalocean_domain" "allaroundhere" { | ||||
|   name = "allaroundhere.org" | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard hostname configuration | ||||
| resource "digitalocean_record" "allaroundhere" { | ||||
|   domain = digitalocean_domain.allaroundhere.id | ||||
|   type   = "A" | ||||
|   name   = "@" | ||||
|   value  = "24.2.156.189" | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "allaroundhere_www" { | ||||
|   domain = digitalocean_domain.allaroundhere.id | ||||
|   type   = "CNAME" | ||||
|   name   = "www" | ||||
|   value  = "@" | ||||
|   ttl    = 43200 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "allaroundhere_content" { | ||||
|   domain = digitalocean_domain.allaroundhere.id | ||||
|   type   = "CNAME" | ||||
|   name   = "content" | ||||
|   value  = "en1.enp.one." | ||||
|   ttl    = 10300 | ||||
| } | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard DO configuration for all managed domains, includes | ||||
| # NS records and SOA | ||||
| resource "digitalocean_record" "allaroundhere_ns1" { | ||||
|   domain = digitalocean_domain.allaroundhere.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns1.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "allaroundhere_ns2" { | ||||
|   domain = digitalocean_domain.allaroundhere.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns2.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "allaroundhere_ns3" { | ||||
|   domain = digitalocean_domain.allaroundhere.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns3.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
							
								
								
									
										200
									
								
								skylab/infra/playbooks/terraform/domain.enp.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								skylab/infra/playbooks/terraform/domain.enp.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,200 @@ | ||||
| resource "digitalocean_domain" "enp" { | ||||
|   name = "enp.one" | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard hostname configuration | ||||
| resource "digitalocean_record" "enp" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "A" | ||||
|   name   = "@" | ||||
|   value  = "24.2.156.189" | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_en1" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "A" | ||||
|   name   = "en1" | ||||
|   value  = digitalocean_record.enp.value | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Service CNAME configuration | ||||
| resource "digitalocean_record" "enp_vcs" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "vcs" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_ssv" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "ssv" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_pms" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "pms" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_cdn" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "cdn" | ||||
|   value  = "${digitalocean_cdn.enp.endpoint}." | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_vpn" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "vpn" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_www" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "www" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_sso" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "sso" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_img" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "img" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard DO configuration for all managed domains, includes | ||||
| # NS records and SOA | ||||
| resource "digitalocean_record" "enp_ns1" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns1.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_ns2" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns2.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_ns3" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns3.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # DMARC and HTTPS security configuration | ||||
| resource "digitalocean_record" "enp_dmarc" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "TXT" | ||||
|   name   = "_dmarc" | ||||
|   value  = "v=DMARC1; p=quarantine; adkim=s" | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_caa" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CAA" | ||||
|   name   = "@" | ||||
|   value  = "letsencrypt.org." | ||||
|   ttl    = 3600 | ||||
|   tag    = "issue" | ||||
|   flags  = 0 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_iodef" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CAA" | ||||
|   name   = "@" | ||||
|   value  = "mailto:admin@enp.one" | ||||
|   ttl    = 3600 | ||||
|   tag    = "iodef" | ||||
|   flags  = 0 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Tutanota mailer integration configuration | ||||
| resource "digitalocean_record" "enp_mx" { | ||||
|   domain   = digitalocean_domain.enp.id | ||||
|   type     = "MX" | ||||
|   name     = "@" | ||||
|   value    = "mail.tutanota.de." | ||||
|   ttl      = 3600 | ||||
|   priority = 1010 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_spf" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "TXT" | ||||
|   name   = "@" | ||||
|   value  = "v=spf1 include:spf.tutanota.de -all" | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_domainkey1" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "s1._domainkey" | ||||
|   value  = "s1._domainkey.tutanota.de." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_domainkey2" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "s2._domainkey" | ||||
|   value  = "s2._domainkey.tutanota.de." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_mta1" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "_mta-sts" | ||||
|   value  = "_mta-sts.tutanota.com." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enp_mta2" { | ||||
|   domain = digitalocean_domain.enp.id | ||||
|   type   = "CNAME" | ||||
|   name   = "mta-sts" | ||||
|   value  = "mta-sts.tutanota.com." | ||||
|   ttl    = 10600 | ||||
| } | ||||
							
								
								
									
										123
									
								
								skylab/infra/playbooks/terraform/domain.enpaul.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								skylab/infra/playbooks/terraform/domain.enpaul.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | ||||
| resource "digitalocean_domain" "enpaul" { | ||||
|   name = "enpaul.net" | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard hostname configuration | ||||
| resource "digitalocean_record" "enpaul" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "A" | ||||
|   name   = "@" | ||||
|   value  = digitalocean_record.enp.value | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_www" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "CNAME" | ||||
|   name   = "www" | ||||
|   value  = "@" | ||||
|   ttl    = 10800 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard DO configuration for all managed domains, includes | ||||
| # NS records and SOA | ||||
| resource "digitalocean_record" "enpaul_ns1" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns1.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_ns2" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns2.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_ns3" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns3.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # DMARC and HTTPS security configuration | ||||
| resource "digitalocean_record" "enpaul_dmarc" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "TXT" | ||||
|   name   = "_dmarc" | ||||
|   value  = "v=DMARC1; p=quarantine; adkim=s" | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_caa" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "CAA" | ||||
|   name   = "@" | ||||
|   value  = "letsencrypt.org." | ||||
|   ttl    = 3600 | ||||
|   tag    = "issue" | ||||
|   flags  = 0 | ||||
| } | ||||
|  | ||||
|  | ||||
| # ========================================================================== | ||||
| # Tutanota mailer integration configuration | ||||
| resource "digitalocean_record" "enpaul_mx" { | ||||
|   domain   = digitalocean_domain.enpaul.id | ||||
|   type     = "MX" | ||||
|   name     = "@" | ||||
|   value    = "mail.tutanota.de." | ||||
|   ttl      = 3600 | ||||
|   priority = 10 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_spf" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "TXT" | ||||
|   name   = "@" | ||||
|   value  = "v=spf1 include:spf.tutanota.de -all" | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_domainkey1" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "CNAME" | ||||
|   name   = "s1._domainkey" | ||||
|   value  = "s1._domainkey.tutanota.de." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_domainkey2" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "CNAME" | ||||
|   name   = "s2._domainkey" | ||||
|   value  = "s2._domainkey.tutanota.de." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_mta1" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "CNAME" | ||||
|   name   = "_mta-sts" | ||||
|   value  = "_mta-sts.tutanota.com." | ||||
|   ttl    = 10600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "enpaul_mta2" { | ||||
|   domain = digitalocean_domain.enpaul.id | ||||
|   type   = "CNAME" | ||||
|   name   = "mta-sts" | ||||
|   value  = "mta-sts.tutanota.com." | ||||
|   ttl    = 10600 | ||||
| } | ||||
							
								
								
									
										72
									
								
								skylab/infra/playbooks/terraform/domain.scipiocapital.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								skylab/infra/playbooks/terraform/domain.scipiocapital.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| resource "digitalocean_domain" "scipiocapital" { | ||||
|   name = "scipiocapital.us" | ||||
| } | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard hostname configuration | ||||
| resource "digitalocean_record" "scipiocapital" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "A" | ||||
|   name   = "@" | ||||
|   value  = digitalocean_record.enp.value | ||||
|   ttl    = 3600 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "scipiocapital_app" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "CNAME" | ||||
|   name   = "app" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 43200 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "scipiocapital_notify" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "CNAME" | ||||
|   name   = "notify" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 43200 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "scipiocapital_docs" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "CNAME" | ||||
|   name   = "docs" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 43200 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "scipiocapital_auth" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "CNAME" | ||||
|   name   = "auth" | ||||
|   value  = "${digitalocean_record.enp_en1.fqdn}." | ||||
|   ttl    = 43200 | ||||
| } | ||||
|  | ||||
| # ========================================================================== | ||||
| # Standard DO configuration for all managed domains, includes | ||||
| # NS records and SOA | ||||
| resource "digitalocean_record" "scipiocapital_ns1" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns1.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "scipiocapital_ns2" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns2.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
|  | ||||
| resource "digitalocean_record" "scipiocapital_ns3" { | ||||
|   domain = digitalocean_domain.scipiocapital.id | ||||
|   type   = "NS" | ||||
|   name   = "@" | ||||
|   value  = "ns3.digitalocean.com." | ||||
|   ttl    = 1800 | ||||
| } | ||||
							
								
								
									
										10
									
								
								skylab/infra/playbooks/terraform/main.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								skylab/infra/playbooks/terraform/main.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| terraform { | ||||
|   backend "pg" {} | ||||
|  | ||||
|   required_providers { | ||||
|     digitalocean = { | ||||
|       source  = "digitalocean/digitalocean" | ||||
|       version = "~> 2.0" | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										13
									
								
								skylab/infra/playbooks/terraform/project.scipio.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								skylab/infra/playbooks/terraform/project.scipio.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| resource "digitalocean_project" "scipio" { | ||||
|   name        = "Scipio Capital" | ||||
|   description = "Eventual home of Scipio Capital systems" | ||||
|   purpose     = "Service or API" | ||||
|   environment = "Production" | ||||
| } | ||||
|  | ||||
| resource "digitalocean_project_resources" "scipio" { | ||||
|   project = digitalocean_project.scipio.id | ||||
|   resources = [ | ||||
|     digitalocean_domain.scipiocapital.urn, | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										17
									
								
								skylab/infra/playbooks/terraform/project.skylab.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								skylab/infra/playbooks/terraform/project.skylab.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| resource "digitalocean_project" "skylab" { | ||||
|   name        = "SkyLab" | ||||
|   description = "SkyLab resources, with emphasis on Sky" | ||||
|   purpose     = "Operational / Developer tooling" | ||||
|   environment = "Development" | ||||
|   is_default  = true | ||||
| } | ||||
|  | ||||
| resource "digitalocean_project_resources" "skylab" { | ||||
|   project = digitalocean_project.skylab.id | ||||
|   resources = [ | ||||
|     digitalocean_domain.allaroundhere.urn, | ||||
|     digitalocean_domain.enpaul.urn, | ||||
|     digitalocean_domain.enp.urn, | ||||
|     digitalocean_spaces_bucket.enp_cdn.urn | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										18
									
								
								skylab/infra/playbooks/terraform/spaces.cdn.tf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								skylab/infra/playbooks/terraform/spaces.cdn.tf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| resource "digitalocean_spaces_bucket" "enp_cdn" { | ||||
|   name          = "en2-cdn" | ||||
|   region        = "nyc3" | ||||
|   acl           = "public-read" | ||||
|   force_destroy = false | ||||
| } | ||||
|  | ||||
| resource "digitalocean_certificate" "enp_cdn" { | ||||
|   name    = "CDN" | ||||
|   type    = "lets_encrypt" | ||||
|   domains = ["cdn.enp.one", "enp.one"] | ||||
| } | ||||
|  | ||||
| resource "digitalocean_cdn" "enp" { | ||||
|   origin           = digitalocean_spaces_bucket.enp_cdn.bucket_domain_name | ||||
|   custom_domain    = "cdn.enp.one" | ||||
|   certificate_name = digitalocean_certificate.enp_cdn.name | ||||
| } | ||||
							
								
								
									
										10
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tox.ini
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| [tox] | ||||
| envlist = ansible, python, security | ||||
| envlist = ansible, security | ||||
| skipsdist = true | ||||
|  | ||||
| [testenv] | ||||
| @@ -36,7 +36,9 @@ locked_deps = | ||||
|     poetry | ||||
|     safety | ||||
| commands = | ||||
|     poetry export --format requirements.txt --without-hashes --dev --output {envtmpdir}/req.txt | ||||
|     safety check --json --file {envtmpdir}/req.txt \ | ||||
|     poetry export --format requirements.txt --without-hashes --with dev --output {envtmpdir}/req.txt | ||||
|     safety check --output text --file {envtmpdir}/req.txt \ | ||||
|         # Ignore unfixed CVE-2021-3532 from ansible \ | ||||
|         --ignore 42923 | ||||
|         --ignore 42923 \ | ||||
|         # https://github.com/pytest-dev/py/issues/287#issuecomment-1283567565 | ||||
|         --ignore 51457 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user