24 Commits
Author SHA1 Message Date
Alex Tavarez 3208cd0b09 added package for adapting to remote kitty-based terminal sessions 2026-07-16 00:12:30 -04:00
Alex Tavarez e5f178e583 added a minidlna package for staging1.test host 2026-07-14 16:49:28 -04:00
Alex Tavarez 1accba1566 added more documentation links 2026-07-14 16:00:29 -04:00
Alex Tavarez 101c1cc0aa added a link 2026-07-14 15:17:07 -04:00
Alex Tavarez a367b3c5e4 fixed typo in documentation 2026-07-14 15:13:39 -04:00
Alex Tavarez 673e318824 changed shell script examples to reflect added fully qualified domain name optional argument for subcommands running playbooks 2026-07-14 15:05:51 -04:00
Alex Tavarez 71261e4017 added option to script subcommand for specifying a fully qualified domain name 2026-07-14 15:04:45 -04:00
Alex Tavarez 9fb64cef30 changed script to reflect change in Python envirohnment path 2026-07-14 14:45:24 -04:00
Alex Tavarez 29d4f33a46 inserted 'fqdn' variable so use of inventory hostname as a fully qualified domain name for managed node or target host services could be overridden 2026-07-14 14:43:49 -04:00
Alex Tavarez 80fd0ebb09 edited documentation so installation section reflects changes in dependency management package use 2026-07-14 14:41:57 -04:00
Alex Tavarez a4d46ada94 changed pip freeze method of dependency management to uv based method for Python 2026-07-14 14:41:17 -04:00
Alex Tavarez e04ed6f273 excluding uv Python dependency manager from version control 2026-07-14 14:39:48 -04:00
Alex Tavarez d44c67df42 added passlib library as a requirement for auto-generation of passwords by Ansible 2026-07-14 14:18:58 -04:00
Alex Tavarez 7574b8f9b4 added installation instructions; clarified how FQDN assignment for managed nodes works and its relevant for a given use-case 2026-07-14 14:15:03 -04:00
Alex Tavarez aa590effb2 added missing step or assurance 2026-07-14 12:54:34 -04:00
Alex Tavarez 5d1e073470 added clarity to a callout/alert in the documentation 2026-07-14 09:30:38 -04:00
Alex Tavarez c7b1d2d30b added more shell script examples, this time showing how to use the shell script in this repo 2026-07-14 09:28:38 -04:00
Alex Tavarez ba7283b583 added SSH-related auth details as defaults when no HTTP auth available 2026-07-14 09:00:08 -04:00
Alex Tavarez 1060724cf8 added some documentation for configuring and using this Ansible project 2026-07-14 08:57:49 -04:00
Alex Tavarez aae7b50c8d wrapped package names in quotes as convention 2026-07-13 13:13:16 -04:00
Alex Tavarez 36b293f923 added a soulseek-cli installation 2026-07-13 13:03:57 -04:00
Alex Tavarez 7e1c8c3f46 enabled julia installation and added virtualization packages for staging hosts 2026-07-13 10:21:22 -04:00
Alex Tavarez c9ceb8e9cf added port forwarding to Vagrant VMs and changed their SSH defaults 2026-07-13 07:13:16 -04:00
Alex Tavarez 26eb7b38b9 changed networking options in Vagrantfiles 2026-07-12 16:56:35 -04:00
20 changed files with 588 additions and 184 deletions
+1
View File
@@ -4,6 +4,7 @@
/hosts.yml
/hosts.yaml
/hosts.json
uv.lock
# Ansible runtime and backups
*.bak
+229
View File
@@ -0,0 +1,229 @@
# SKATO ANSIBLE
## Installation
Make sure you have `git`, `venv`, and `uv` installed. On GNU/Linux Debian-based distros with pre-installed `apt` package manager, the corresponding packages are:
- `git`
- `python3-venv`
- [Follow this guide](https://docs.astral.sh/uv/getting-started/installation/) for installing `uv`
Ansible must also be installed on your system (see [this guide](https://docs.ansible.com/projects/ansible/latest/installation_guide/index.html)). Then, in your interactive bash shell session, run the following in order:
```bash
git clone https://git.sukaato.moe/admin/skato-ansible.git
cd ./skato-ansible
uv venv .venv
uv sync
source .venv/bin/activate
ansible-galaxy collections install -r ./collections/requirements.yml
```
## Essential Background
### Software Management
The standard use-case, which we call the container routing case, of this Ansible library is to run its playbooks in such a way that one host ends up acting as a router (via VPN service) to services on another host.
In the container routing case these services are defined by a repository declared in `${ANSIBLE_PROJECT_ROOT}/vars/source_code.yml`, via setting `source_code.repos.compose.name` and `source_code.repos.compose.rpath`, respectively, to the name of a version-controlled source repository and to a desired path within that repository (that path written such that it treats the repository path as root, i.e. as `/`).
As can then be noted, the `source_code` dictionary holds an attribute `repos` with itself attributes of fixed name representing various services or utilities, each of whom must have a `name` attribute defined that represents the name of the corresponding version-controlled source repository for that service or utility.
The point of this set-up is to allow the repository name at its endpoint to change without requiring manual changes in the code using or deploying that repository as consequence. One unfortunate result of this is that adding a service or utiltiy from one's git bare repositories means making manual corresponding changes in `pkgs` software object groups in relevant [host variable files](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables), in `${ANSIBLE_PROJECT_ROOT}/roles/init-server/handlers/{core,userspace}.yml` for calling installation or post-installation actions, and in `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/${SOFTWARE_NAME}.yml` for executing those actions. The convention is for [handler](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) [notifiers](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers), [handler](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) [listeners](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers) and software names to all be equivalent, though the software name can deviate from this relational pattern.
Importantly, the following top-level attributes of the `source_code` variable or dictionary are necessary if your version-controlled source repository source requires authentication:
- `host`
- `user`/`ssh_user`
- `http_password`/`ssh_password`
If you wish to be able to use both SSH and HTTP authentication methods for the version-controlled source repository or change the default preference for HTTP credential use, you may edit `${ANSIBLE_PROJECT_ROOT}/roles/init-server/templates/user/netrc.j2`. See [the CURL docuemntation for more information on the NetRC file format](https://everything.curl.dev/usingcurl/netrc.html).
The point of the `source_code` dictionary is that it allows plugging in and executing custom code from one's own source repositories.
All other software is simply handled through the aforementioned patttern of adding an entry to any of the following in a given [host variables file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables):
- `pkgs.mngr.core` or `pkgs.mngr.userspace` (software installed by package manager--in this case, `apt` as most tasks assume a Linux Debian system at Ansible's managed node)
- `pkgs.script.core` or `pkgs.script.userspace` (since different installation shell scripts allow for different parameters, entries for installation shell scripts here are downloaded--for actual installation, the script has to be ran in a set of tasks specified in a YAML file under `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/`)
- `pkgs.archive.core` or `pkgs.archive.userspace` (similar as before, except things like path movement or specification, building/compilation, etc., are what take place via the set of tasks specified under the YAML file under `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/`)
- `pkgs.git_repos.core` or `pkgs.git_repos.userspace` (similar as before, fulfilling any arbitrary set of specified tasks for the pulled git source repository--you get the point)
Each entry item must have a `handler` attribute whose value will be used to [notify](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers) a [handler](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) [listener](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers), whose `listen` attribute has that same value, that then includes tasks found in a YAML file under `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/` whose basename, conventionally, is the same as those `handler` and `listen` attribute values. All of which, again, also conventionally share the same value as the `name` attribute of the entry item.
The structure of entries within each `pkgs.${SOFTWARE_GROUP}.core`/`pkgs.${SOFTWARE_GROUP}.userspace` depends on `$SOFTWARE_GROUP` because it changes the semantics of installation. All entries are dictionary items.
> [!NOTE]
> A table will be added at a later date, covering the attributes of the dictionary items for each `$SOFTWARE_GROUP`. For now, the [host variable files](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) for the staging hosts found in the [YAML inventory file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html) can be used as reference.
### Configuration Management
#### System Configuration
The most important configuration is that needed for each host. This involves software installation, though [that is already covered in the above section](#software-management). Other important [host variables](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) for any given [host variable file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) are:
variable name | type | default | semantics
--- | --- | --- | ---
`password` | `str` | auto-generated | the hashed password for the root user if the managed node had not spawned prior to playbook run
`ssh_keys` | `list` | `["ed25519@staging", "ecdsa@staging"]` | the basenames of the SSH key pairs for the root user
`admins` | `list` | `[{"username": "senpai", "services": None, "ssh_keys": ["ed25519@staging", "ecdsa@staging"], "password": ""} for d in admins]` | the list of Linux superusers, i.e. administrators, to exist
`token` | `str` | `None` | API key for cloud hosting account to spawn a VPS
`origin` | `str` | `us-east` | region or location of the VPS to determine timezones and locale; useful for Akamai Linode cloud hosting
`operating_system` | `str` | `None` | name or path to operating system for cloud hosted VPS or a VM / bare metal system
#### Software Configuration
Other configuration involves Ansible role templates or files, e.g. those found in `${ANSIBLE_PROJECT_ROOT}/roles/init-server/{templates,files}`. Generally, these Ansible role templates or files are sent over to the Ansible managed node by tasks provided by that same role, and referred to by tasks in the [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html).
The convention for templates is to set some desired though non- software native "defaults" and leave some settings or values to variables, grouped by the software for which they are relevant into variable files in `${ANSIBLE_PROJECT_ROOT}/vars/`, or what we may call the [playbook variable files](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-in-included-files-and-roles). These YAML variable files by convention have as their basename `${SOFTWARE_NAME}_settings` (with some exceptions), and must be listed (as paths relative to `$ANSIBLE_PROJECT_ROOT`) under `vars_files` on the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) that will be running the tasks/[handlers](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables), native to itself or taken from a role, that send the respective files or (after processing) templates over to the managed Ansible node(s). These kinds of files shall be called "settings files."
Inside each such settings file, the convention is for there to be a top-level variable (i.e., a single variable that takes a dictionary value) with a name of `$SOFTWARE_NAME`, whose value has attributes representing configuration options for the given software.
Some common, shared attributes for settings files are:
attribute name | type | default value | required? | semantics
--- | --- | --- | --- | ---
`containerized` | `bool` | `True` | only for services or software that is service-capable | determines whether the configuration is for a containerized or base system install
`mode` | `str` | "prod" | no | usefully allows for setting the mode for an individual piece of software rather than having it automatically agree with [the playbook mode](#essential-usage) or having it assume production mode
Other common ones, especially for services, are `port` (which can be an integer or string) and--for web servers--`scheme` (which can be either string "http" or "https", serving to toggle SSL/TLS DNS authentication for HTTP connections). These can exist at any nesting level under the top-level dictionary, based on the feature scope of the given software.
## Essential Usage
Before running any Ansible [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) in either development or production mode, make sure to specify the username and the home directory path of the user on the system you are currently using in `{ANSIBLE_PROJECT_ROOT}/vars/local_facts.yml`.
### Development Mode
For development purposes in the container routing case, either first manually set up two Debian virtual machines, or (**recommended**) change into the `${ANSIBLE_PROJECT_ROOT}/staging0.test/` directory then `${ANSIBLE_PROJECT_ROOT}/staging1.test/` directory, running `vagrant up` for each. Running the [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) in development mode also requires supplying "dev" as an argument for the extra `mode` parameter.
> [!WARNING]
> Vagrantfiles for neither staging host has yet been tested. Proceed by your own discretion.
If you intend to run the [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) in production, the argument for this extra parameter should be "prod" (skip to the [Production Mode](#production-mode) section). The additional extra parameter of `chosen_host` should be adjusted to reflect the name of the host enlisted in the [YAML inventory file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html) for production purposes.
> [!IMPORTANT]
> The names of hosts should be equivalent to their intended final domain name for services on any given host for the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) to work correctly.
Anyway, for *any* mode double-check that the correct values are set for `chosen_user`. The first playbook you run for each host or IP in each pair of `ansible-playbook` commands in the upcoming shell script should always have `chosen_user` as "root". The extra parameter `chosen_user` for the second `ansible-playbook` command of each pair of `ansible-playbook` commands shown below should take an argument whose value is the same as that of the `username` attribute of any of the items in the `admins` list in the [host variables file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) for the given host. With that in mind, execute the below for development mode for container routing case while in the `$ANSIBLE_PROJECT_ROOT` directory:
```bash
#!/bin/bash
set -euo pipefail
SSH_KEYS=()
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" init\@vps.yml
$SSH_KEYS | xargs -I %k ssh-add %k # ADD NEEDED SSH KEY FILEPATHS
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" administrate\@vps.yml
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" init\@homeserver.yml
# UNCOMMENT BELOW TO REASSIGN ENVIRONMENT VARIABLE FOR NEW ARRAY OF SSH KEYPAIR FILEPATHS
# SSH_KEYS=()
# UNCOMMENT BELOW TO ADD UPDATED SSH KEY PAIR FILEPATHS TO SSH_AGENT
# $SSH_KEYS | xargs -I %k ssh-add %k
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" administrate\@homeserver.yml
```
> [!WARNING]
> In the container routing case, development mode may not supply an accurate test of the intended networking result if the virtual machines for staging were manually created, but the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) should run successfully. This is because apppropriate networking must be set for the virtual machine itself for VPN client containers in one virtual machine to "speak" with the VPN server in another virtual machine. The supplied Vagrantfiles are a WIP.
### Production Mode
Its important to note that the above shell script example for development mode would have to be modified in production mode for the container routing case such that every `ansible-playbook` call instance has its extra parameter `chosen_host` share the same value throughout. This is due to the combination of how SSL/TLS and domain names are set up in the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) and the requirements of the container routing case. Namely, the former treats the inventory hostname used for the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) as the [fully qualified domain name](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) of that server host, while the container routing case requires that both server hosts share that [fully qualified domain name](https://en.wikipedia.org/wiki/Fully_qualified_domain_name).
This means that `chosen_host`'s value being the same across all `ansible-playbook` commands does not mean that value should represent the same managed node or host [IP](https://en.wikipedia.org/wiki/IP_address) throughout. Whether it does so is of course determined by whatever is in the [YAML inventory file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html), so that would need to be changed when running [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) against the second chosen host in the container routing case.
To drive all that home, in production we may instead need something like the following (again, executed while in the `$ANSIBLE_PROJECT_ROOT` directory):
```bash
#!/bin/bash
set -euo pipefail
SSH_KEYS=()
HOST_FQDN=web.site # a fully qualified domain name you own
CURRENT_IP= # whatever the current IP of the host $HOST_FQDN is
UPDATED_IP= # the desired new IP for the host $HOST_FQDN
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=root" --extra-vars "mode=prod" init\@vps.yml
$SSH_KEYS | xargs -I %k ssh-add %k # ADD NEEDED SSH KEY PAIR FILEPATHS TO SSH_AGENT
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=senpai" --extra-vars "mode=prod" administrate\@vps.yml
sed '/'"$HOST_FQDN"':{N;s/'"$HOST_FQDN"':\n {6}ansible_host: '"$CURRENT_IP"'/'"$HOST_FQDN"':\n ansible_host: '"$NEW_IP"'/g}' hosts.yml
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=root" --extra-vars "mode=prod" init\@homeserver.yml
# UNCOMMENT BELOW TO REASSIGN ENVIRONMENT VARIABLE FOR NEW ARRAY OF SSH KEYPAIR FILEPATHS
# SSH_KEYS=()
# UNCOMMENT BELOW TO ADD UPDATED SSH KEY PAIR FILEPATHS TO SSH_AGENT
# $SSH_KEYS | xargs -I %k ssh-add %k
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=senpai" --extra-vars "mode=prod" administrate\@homeserver.yml
```
**There *is* a way to avoid reassigning the IP address of the shared inventory hostname for each host the pair of playbooks is being run against in the container routing case under production.** This involves defining `fqdn` as a playbook variable or as an extra parameter for all `ansible-playbook` commands in the shell script, resulting in a shell script that looks more similar to our [development mode shell script](#development-mode):
```bash
#!/bin/bash
set -euo pipefail
SSH_KEYS=()
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" init\@vps.yml
$SSH_KEYS | xargs -I %k ssh-add %k # ADD NEEDED SSH KEY FILEPATHS
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" administrate\@vps.yml
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" init\@homeserver.yml
# UNCOMMENT BELOW TO REASSIGN ENVIRONMENT VARIABLE FOR NEW ARRAY OF SSH KEYPAIR FILEPATHS
# SSH_KEYS=()
# UNCOMMENT BELOW TO ADD UPDATED SSH KEY PAIR FILEPATHS TO SSH_AGENT
# $SSH_KEYS | xargs -I %k ssh-add %k
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" administrate\@homeserver.yml
```
> [!TIP]
> Adding the extra parameter here to the `ansible-playbook` commands of the development mode execution for the container routing use-case may also improve the realism of its execution and final state, virtual machine network configurations notwithstanding. Consider doing so for more realistic networking tests under the container routing case.
### Custom Playbooks
As long as you are matching the appropriate set of [playbook variable files](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-in-included-files-and-roles) or settings files with the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) according to its need of those variable definitions/declarations, mostly determined by [the intended targeted hosts' own variables](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) together with role [handlers](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables), and as long as you have appropriately set up software installations, (see [Software Management](#software-management)) creating new/custom [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) should be relatively easy.
Depending on what you are trying to do with a new [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html), the best approach may be to just copy/duplicate the extant [playbook files](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) and then edit them, as this allows one to mitigate errors as well as have a reliable reference point for changes.
### CLI Tool
As an alternative, you can use the `skato-ansible` shell script in `$ANSIBLE_PROJECT_ROOT` as an abstraction of the `ansible-playbook` commands for the container routing case. I plan to replace it with a CLI app covering more intended use-cases.
When using the `skato-ansible.sh` script in development mode for the container routing use case:
```bash
#!/bin/bash
set -euo pipefail
./skato-ansible.sh init vps -v 3 -m dev -n staging0.test
./skato-ansible.sh populate-agent staging
./skato-ansible.sh bootstrap vps -s 1 -v 3 -m dev -n staging0.test
./skato-ansible.sh init homeserver -v 3 -m dev -n staging1.test
# BELOW ONLY IF $SKANSIBLE_SSH_KEY ALTERED IN THE SHELL SCRIPT
# ./skato-ansible.sh populate-agent staging
./skato-ansible.sh bootstrap vps -s 1 -v 3 -m dev -n staging1.test
```
Otherwise, in production mode:
```bash
#!/bin/bash
set -euo pipefail
INVENTORY_HOSTNAMES=(web1 web2)
FQDN=web.site
./skato-ansible.sh init vps -v 3 -n "${INVENTORY_HOSTNAMES[0]}" -d "$FQDN"
./skato-ansible.sh populate-agent staging
./skato-ansible.sh bootstrap vps -s 1 -v 3 -n "${INVENTORY_HOSTNAMES[0]}" -d "$FQDN"
./skato-ansible.sh init homeserver -v 3 -n "${INVENTORY_HOSTNAMES[1]}" -d "$FQDN"
# BELOW ONLY IF $SKANSIBLE_SSH_KEY ALTERED IN THE SHELL SCRIPT
# ./skato-ansible.sh populate-agent staging
./skato-ansible.sh bootstrap vps -s 1 -v 3 -n "${INVENTORY_HOSTNAMES[1]}" -d "$FQDN"
```
> [!IMPORTANT]
> If you have different SSH keypairs for staging, make sure to change the value of `SKANSIBLE_SSH_KEYS` environment variable in the `${ANSIBLE_PROJECT_ROOT}/skato-ansible.sh` shell script before running the above shell scripts from `$ANSIBLE_PROJECT_ROOT`.
+8
View File
@@ -168,6 +168,14 @@
hour: "4-15"
weekday: "1-5"
job: "{{ ansible_user_home.stdout }}/.local/bin/flexget --cron execute"
- name: Checking presence of dependency
when: "'nvm' in all_core_pkgs or 'nvm' in all_userspace_pkgs"
block:
- name: Installing SoulSeek CLI
community.general.npm:
name: "soulseek-cli"
global: true
state: present
- name: Opening port 51820
become: true
ansible.builtin.iptables:
+65 -25
View File
@@ -17,8 +17,8 @@ admins:
# <list[<str>]> list of control node or local SSH key basenames for this user
ssh_keys:
# @TODO add secondary and teriary Yubikeys
- ecdsa-37851076-sk@staging
- ed25519-37851076-sk@staging
- ed25519@staging
- ecdsa@staging
# <str<vault?>> hashed (and maybe salted) password
password: "{{ lookup('password', './.tmp/senpai@' + inventory_hostname + '.pass', seed='senpai@' + inventory_hostname, encrypt='sha512_crypt') }}"
# <dict[<str>:<dict>]> package groups
@@ -27,7 +27,7 @@ pkgs:
mngr:
# <list[<dict>]> representing system-level or essential packages
core:
- name: zfsutils-linux
- name: "zfsutils-linux"
uri: ~
sigkey: ~
sources: ~
@@ -35,7 +35,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: zfs-dkms
- name: "zfs-dkms"
uri: ~
sigkey: ~
sources: ~
@@ -51,7 +51,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: cron-daemon-common
- name: "cron-daemon-common"
uri: ~
sigkey: ~
sources: ~
@@ -59,7 +59,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-certbot
- name: "python3-certbot"
uri: ~
sigkey: ~
sources: ~
@@ -67,7 +67,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-certbot-dns-standalone
- name: "python3-certbot-dns-standalone"
uri: ~
sigkey: ~
sources: ~
@@ -83,7 +83,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: xz-utils
- name: "xz-utils"
uri: ~
sigkey: ~
sources: ~
@@ -99,7 +99,7 @@ pkgs:
suites: ~
comps: ~
handler: wireguard
- name: wireguard-tools
- name: "wireguard-tools"
uri: ~
sigkey: ~
sources: ~
@@ -115,7 +115,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: qemu-system
- name: "vagrant-libvirt"
uri: ~
sigkey: ~
sources: ~
@@ -123,7 +123,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: qemu-kvm
- name: "qemu-system"
uri: ~
sigkey: ~
sources: ~
@@ -131,7 +131,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: bridge-utils
- name: "qemu-kvm"
uri: ~
sigkey: ~
sources: ~
@@ -139,7 +139,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: libvirt-clients
- name: "bridge-utils"
uri: ~
sigkey: ~
sources: ~
@@ -147,7 +147,39 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: libvirt-daemon-system
- name: libvirt
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "libvirt-clients"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "libvirt-daemon-system"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "virt-install"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "virt-viewer"
uri: ~
sigkey: ~
sources: ~
@@ -163,7 +195,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: git-doc
- name: "kitty-terminfo"
uri: ~
sigkey: ~
sources: ~
@@ -171,7 +203,15 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: git-delta
- name: "git-doc"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "git-delta"
uri: ~
sigkey: ~
sources: ~
@@ -236,7 +276,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: gnupg-agent
- name: "gnupg-agent"
uri: ~
sigkey: ~
sources: ~
@@ -252,7 +292,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: cpu-checker
- name: "cpu-checker"
uri: ~
sigkey: ~
sources: ~
@@ -277,14 +317,14 @@ pkgs:
comps: ~
handler: headscale
userspace:
- name: libpam-google-authenticator
- name: "libpam-google-authenticator"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: libpam-google-authenticator
handler: "libpam-google-authenticator"
- name: vim
uri: ~
sources: ~
@@ -293,7 +333,7 @@ pkgs:
suites: ~
comps: ~
handler: vim
- name: vim-vimwiki
- name: "vim-vimwiki"
uri: ~
sigkey: ~
sources: ~
@@ -301,7 +341,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: vim-doc
- name: "vim-doc"
uri: ~
sigkey: ~
sources: ~
@@ -341,7 +381,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-venv
- name: "python3-venv"
uri: ~
sigkey: ~
sources: ~
@@ -349,7 +389,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-pip
- name: "python3-pip"
uri: ~
sigkey: ~
sources: ~
@@ -365,7 +405,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: golang-doc
- name: "golang-doc"
uri: ~
sigkey: ~
sources: ~
+132 -44
View File
@@ -15,8 +15,8 @@ admins:
# <list[<str>]> list of control node or local SSH key basenames for this user
ssh_keys:
# @TODO add secondary and teriary Yubikeys
- ecdsa-37851076-sk@staging
- ed25519-37851076-sk@staging
- ed25519@staging
- ecdsa@staging
# <str<vault?>> hashed (and maybe salted) password
password: "{{ lookup('password', './.tmp/senpai@' + inventory_hostname + '.pass', seed='senpai@' + inventory_hostname, encrypt='sha512_crypt') }}"
# <dict[<str>:<dict>]> package groups
@@ -25,7 +25,7 @@ pkgs:
mngr:
# <list[<dict>]> representing system-level or essential packages
core:
- name: zfsutils-linux
- name: "zfsutils-linux"
uri: ~
sigkey: ~
sources: ~
@@ -33,7 +33,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: zfs-dkms
- name: "zfs-dkms"
uri: ~
sigkey: ~
sources: ~
@@ -49,7 +49,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: cron-daemon-common
- name: "cron-daemon-common"
uri: ~
sigkey: ~
sources: ~
@@ -57,7 +57,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: xz-utils
- name: "xz-utils"
uri: ~
sigkey: ~
sources: ~
@@ -73,7 +73,87 @@ pkgs:
suites: ~
comps: ~
handler: wireguard
- name: wireguard-tools
- name: "wireguard-tools"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: vagrant
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "vagrant-libvirt"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "qemu-system"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "qemu-kvm"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "bridge-utils"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: libvirt
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "libvirt-clients"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "libvirt-daemon-system"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "virt-install"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: "virt-viewer"
uri: ~
sigkey: ~
sources: ~
@@ -89,7 +169,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: kitty-terminfo
- name: "kitty-terminfo"
uri: ~
sigkey: ~
sources: ~
@@ -129,7 +209,7 @@ pkgs:
suites: ~
comps: ~
handler: git
- name: git-delta
- name: "git-delta"
uri: ~
sources: ~
sigkey: ~
@@ -137,7 +217,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: git-doc
- name: "git-doc"
uri: ~
sources: ~
sigkey: ~
@@ -145,7 +225,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: git-man
- name: "git-man"
uri: ~
sources: ~
sigkey: ~
@@ -185,7 +265,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: build-essential
- name: "build-essential"
uri: ~
sigkey: ~
sources: ~
@@ -297,7 +377,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: cpu-checker
- name: "cpu-checker"
uri: ~
sigkey: ~
sources: ~
@@ -305,7 +385,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: libpam-doc
- name: "libpam-doc"
uri: ~
sigkey: ~
sources: ~
@@ -321,7 +401,15 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: gnupg-agent
- name: "gnupg-agent"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: minidlna
uri: ~
sigkey: ~
sources: ~
@@ -338,14 +426,14 @@ pkgs:
suites: ~
comps: ~
handler: aria
- name: libpam-google-authenticator
- name: "libpam-google-authenticator"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: libpam-google-authenticator
handler: "libpam-google-authenticator"
- name: vim
uri: ~
sources: ~
@@ -354,7 +442,7 @@ pkgs:
suites: ~
comps: ~
handler: vim
- name: vim-vimwiki
- name: "vim-vimwiki"
uri: ~
sigkey: ~
sources: ~
@@ -362,7 +450,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: vim-doc
- name: "vim-doc"
uri: ~
sigkey: ~
sources: ~
@@ -402,7 +490,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: podman-compose
- name: "podman-compose"
uri: ~
sigkey: ~
sources: ~
@@ -426,7 +514,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-venv
- name: "python3-venv"
uri: ~
sigkey: ~
sources: ~
@@ -434,7 +522,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-pip
- name: "python3-pip"
uri: ~
sigkey: ~
sources: ~
@@ -442,7 +530,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: python3-doc
- name: "python3-doc"
uri: ~
sigkey: ~
sources: ~
@@ -458,7 +546,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: golang-doc
- name: "golang-doc"
uri: ~
sigkey: ~
sources: ~
@@ -474,7 +562,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: yt-dlp
- name: "yt-dlp"
uri: ~
sigkey: ~
sources: ~
@@ -482,7 +570,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: syncthing-discosrv
- name: "syncthing-discosrv"
uri: ~
sigkey: ~
sources: ~
@@ -490,15 +578,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: syncthing-relaysrv
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
- name: syncthing-relaysrv
- name: "syncthing-relaysrv"
uri: ~
sigkey: ~
sources: ~
@@ -554,7 +634,7 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: erlang-hex
- name: "erlang-hex"
uri: ~
sigkey: ~
sources: ~
@@ -578,6 +658,14 @@ pkgs:
suites: ~
comps: ~
handler: default
- name: "libsecret-1-dev"
uri: ~
sigkey: ~
sources: ~
types: ~
suites: ~
comps: ~
handler: default
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
script:
# <list[<dict>]> representing user-level or supplemental shell script installations
@@ -592,11 +680,11 @@ pkgs:
pre: ~
post: ~
handler: rustup
# - name: julia
# src: "https://install.julialang.org"
# pre: ~
# post: ~
# handler: julia
- name: julia
src: "https://install.julialang.org"
pre: ~
post: ~
handler: julia
- name: uv
src: "https://astral.sh/uv/install.sh"
pre: ~
@@ -636,7 +724,7 @@ pkgs:
# pre: ~
# post: ~
# handler: false
- name: skato-compose
- name: "skato-compose"
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.compose.name }}.git"
branch: main
deploy: ~
@@ -650,14 +738,14 @@ pkgs:
pre: ~
post: ~
handler: skato_cli
- name: skato-blog-theme
- name: "skato-blog-theme"
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.blog_theme.name }}.git"
branch: main
deploy: ~
pre: ~
post: ~
handler: skato_blog_theme
- name: skato-blog
- name: "skato-blog"
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.blog.name }}.git"
branch: main
deploy: ~
+2 -2
View File
@@ -34,13 +34,13 @@
- name: Updating hostname
become: true
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
name: "{{ fqdn | default(inventory_hostname) }}"
- name: Updating hosts file
become: true
ansible.builtin.lineinfile:
path: /etc/hosts
regexp: "^127\\.0\\.1\\.1"
line: "127.0.1.1 {{ inventory_hostname }}"
line: "127.0.1.1 {{ fqdn | default(inventory_hostname) }}"
insertbefore: BOF
state: present
- name: Updating host icon name
+2 -2
View File
@@ -37,13 +37,13 @@
- name: Updating hostname
become: true
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
name: "{{ fqdn | default(inventory_hostname) }}"
- name: Updating hosts file
become: true
ansible.builtin.lineinfile:
path: /etc/hosts
regexp: "^127\\.0\\.1\\.1"
line: "127.0.1.1 {{ inventory_hostname }}"
line: "127.0.1.1 {{ fqdn | default(inventory_hostname) }}"
insertbefore: BOF
state: present
- name: Updating host icon name
+73
View File
@@ -0,0 +1,73 @@
[project]
name = "skato-ansible"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"ansible==13.7.0",
"ansible-builder==3.1.1",
"ansible-compat==26.3.0",
"ansible-core==2.20.6",
"ansible-lint==26.4.0",
"ansible-navigator==26.4.0",
"ansible-runner==2.4.3",
"ansible-specdoc==0.0.20",
"appdirs==1.4.4",
"attrs==26.1.0",
"baron==0.10.1",
"bindep==2.14.0",
"black==26.5.1",
"bracex==2.6",
"certifi==2026.5.20",
"cffi==2.0.0",
"charset-normalizer==3.4.7",
"click==8.4.1",
"cryptography==48.0.0",
"deprecated==1.3.1",
"distro==1.9.0",
"enrich==1.2.7",
"filelock==3.29.0",
"idna==3.16",
"jinja2==3.1.6",
"jsonschema==4.26.0",
"jsonschema-specifications==2025.9.1",
"linode-api4==5.44.0",
"lockfile==0.12.2",
"markdown-it-py==4.2.0",
"markupsafe==3.0.3",
"mdurl==0.1.2",
"molecule==26.4.0",
"mypy-extensions==1.1.0",
"onigurumacffi==1.5.0",
"packaging==26.2",
"parsley==1.3",
"passlib==1.7.4",
"pathspec==1.0.4",
"pbr==7.0.3",
"pexpect==4.9.0",
"pip==25.1.1",
"platformdirs==4.9.6",
"pluggy==1.6.0",
"polling==0.3.2",
"ptyprocess==0.7.0",
"pycparser==3.0",
"pygments==2.20.0",
"python-daemon==3.1.2",
"pytokens==0.4.1",
"pyyaml==6.0.3",
"redbaron==0.9.2",
"referencing==0.37.0",
"requests==2.34.2",
"resolvelib==1.2.1",
"rich==15.0.0",
"rpds-py==0.30.0",
"rply==0.7.8",
"ruamel-yaml==0.19.1",
"ruamel-yaml-clib==0.2.15",
"setuptools==82.0.1",
"subprocess-tee==0.4.2",
"tzdata==2026.2",
"urllib3==2.7.0",
"wcmatch==10.1",
"wrapt==2.2.1",
"yamllint==1.38.0",
]
-65
View File
@@ -1,65 +0,0 @@
ansible==13.7.0
ansible-builder==3.1.1
ansible-compat==26.3.0
ansible-core==2.20.6
ansible-lint==26.4.0
ansible-navigator==26.4.0
ansible-runner==2.4.3
ansible-specdoc==0.0.20
appdirs==1.4.4
attrs==26.1.0
baron==0.10.1
bindep==2.14.0
black==26.5.1
bracex==2.6
certifi==2026.5.20
cffi==2.0.0
charset-normalizer==3.4.7
click==8.4.1
cryptography==48.0.0
deprecated==1.3.1
distro==1.9.0
enrich==1.2.7
filelock==3.29.0
idna==3.16
jinja2==3.1.6
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
linode-api4==5.44.0
lockfile==0.12.2
markdown-it-py==4.2.0
markupsafe==3.0.3
mdurl==0.1.2
molecule==26.4.0
mypy-extensions==1.1.0
onigurumacffi==1.5.0
packaging==26.2
parsley==1.3
pathspec==1.0.4
pbr==7.0.3
pexpect==4.9.0
platformdirs==4.9.6
pluggy==1.6.0
polling==0.3.2
ptyprocess==0.7.0
pycparser==3.0
pygments==2.20.0
python-daemon==3.1.2
pytokens==0.4.1
pyyaml==6.0.3
redbaron==0.9.2
referencing==0.37.0
requests==2.34.2
resolvelib==1.2.1
rich==15.0.0
rpds-py==0.30.0
rply==0.7.8
ruamel-yaml==0.19.1
ruamel-yaml-clib==0.2.15
setuptools==82.0.1
subprocess-tee==0.4.2
tzdata==2026.2
urllib3==2.7.0
wcmatch==10.1
wrapt==2.2.1
yamllint==1.38.0
@@ -38,10 +38,10 @@
- name: Exemplifying needed ACME record
ansible.builtin.set_fact:
acme_record: |
{{ inventory_hostname }} IN A {{ ipify_public_ip }}
_acme-challenge.{{ inventory_hostname }} IN CNAME {{ inventory_hostname }}.acme.{{ inventory_hostname }}.
acme.{{ inventory_hostname }} IN NS ns.acme.{{ inventory_hostname }}.
ns.acme.{{ inventory_hostname }} IN A {{ ipify_public_ip }}
{{ fqdn | default(inventory_hostname) }} IN A {{ ipify_public_ip }}
_acme-challenge.{{ fqdn | default(inventory_hostname) }} IN CNAME {{ fqdn | default(inventory_hostname) }}.acme.{{ fqdn | default(inventory_hostname) }}.
acme.{{ fqdn | default(inventory_hostname) }} IN NS ns.acme.{{ fqdn | default(inventory_hostname) }}.
ns.acme.{{ fqdn | default(inventory_hostname) }} IN A {{ ipify_public_ip }}
- name: Informing user of need to set up ACME record
ansible.builtin.debug:
msg: "Please set ACME record in domain name provider:\n {{ acme_record }}"
@@ -67,12 +67,12 @@
when: data_method.user_input == "fetch"
block:
- name: Informing user of inventory requirements for VPN clients
when: not item.name in groups.homeserver
when: ((fqdn is undefined or fqdn == None) and item.name != fqdn) or not item.name in groups.homeserver
ansible.builtin.fail:
msg: The VPN client must be the name of an inventory host in a homeserver group
loop: "{{ vpn.clients }}"
- name: Dupliciating DSNet VPN service client configuration files to control node
when: item.name in groups.homeserver
when: ((fqdn is defined and fqdn != None) and item.name == fqdn) or item.name in groups.homeserver
ansible.builtin.fetch:
src: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf"
dest: "./.tmp/{{ inventory_hostname }}-dsnet/"
@@ -181,7 +181,7 @@
- name: Copying VPN client configuration files
become: true
become_user: "{{ current_user.stdout }}"
when: item.name == inventory_hostname
when: ((fqdn is defined and fqdn != None) and item.name == fqdn) or item.name == inventory_hostname
ansible.builtin.copy:
src: "user/wg/containerized/{{ item.name }}{{ (idx | string) }}.conf"
dest: "{{ ansible_user_home.stdout }}/.wg/containerized/"
@@ -772,7 +772,7 @@
- name: Creating required tailnet container secret for tailnet container specified by Compose file
become: true
# become_user: "{{ current_user.stdout }}"
when: item.name == inventory_hostname
when: ((fqdn is defined and fqdn != None) and item.name == fqdn) or item.name == inventory_hostname
ansible.builtin.copy:
src: "{{ item.name }}-{{ headscale.users.admin.username }}@headscale/headscale{{ (idx | string) }}.key"
dest: "{{ ansible_user_home.stdout }}/.podsecrets/headscale.key"
@@ -1,6 +1,6 @@
CERTBOT_EMAIL="{{ certbot.email }}"
CERTBOT_AUTHENTICATOR={{ certbot.auth_method }}
SERVER_WEBROOT_PATH={{ ansible_user_home.stdout + "/srv/acme." + inventory_hostname }}
SERVER_WEBROOT_PATH={{ ansible_user_home.stdout + "/srv/certbot." + (fqdn | default(inventory_hostname)) }}
{% if compose.mode == "dev" %}
# @TODO find a better way to have processed the below in Ansible
CERTBOT_CHALLENGE_DOMAINS={{ certbot.domains | map("regex_replace", "\\.([^\\.]*)$", ".test") | list | join(",") }}
@@ -1,11 +1,27 @@
http://<< inventory_hostname >> {
handle /.well-known/acme-challenge/* {
reverse_proxy localhost:80
}
http://<< web_fqdn >> {
handle /.well-known/acme-challenge/* {
reverse_proxy localhost:80
}
handle {
redir https://{host}{uri} 308
}
}
:80 {
root * /srv/<< inventory_hostname >>
file_server
encode gzip
root /srv/certbot.<< web_fqdn >>
browse
}
<< web_fqdn >> {
respond 503
# root /srv/<< web_fqdn >>
file_server
header /.well-known/openpgpkey/* {
Content-Type application/octet-stream
Access-Control-Allow-Origin *
}
handle_errors {
rewrite /error/{err.status_code}.html
templates
}
}
+2 -2
View File
@@ -1,3 +1,3 @@
machine {{ source_code.host }}
login {{ source_code.user }}
password {{ source_code.http_password }}
login {{ source_code.user | default(source_code.ssh_user) }}
password {{ source_code.http_password | default(source_code.ssh_password) }}
+23 -21
View File
@@ -15,24 +15,24 @@ if [[ "$1" == "version" ]]; then
fi
if [[ "$1" == "show-defaults" ]]; then
source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
printf "Private SSH keys available throufh SSH agent: |\n%s\n" "$(ssh-add -l)"
fi
if [[ "$1" == "start-agent" ]]; then
source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
eval "$(ssh-agent -s)"
fi
if [[ "$1" == "list-agent" ]]; then
source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
ssh-add -l
fi
if [[ "$1" == "populate-agent" ]]; then
shift 1
source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
if [[ "$1" == "all" ]]; then
for SKANSIBLE_SSH_KEY in ~/.ssh/*; do
@@ -69,7 +69,7 @@ fi
if [[ "$1" == "init" ]]; then
shift 1
source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
if [[ "$1" == "vps" ]]; then
SKANSIBLE_PLAY_HOST="$1"
@@ -82,7 +82,7 @@ if [[ "$1" == "init" ]]; then
exit 1
fi
while getopts "htm:s:n:v:u:" opt; do
while getopts "htd:m:s:n:v:u:" opt; do
case $opt in
h) Help "init";;
s) SKANSIBLE_STAGE="$OPTARG";;
@@ -91,6 +91,7 @@ if [[ "$1" == "init" ]]; then
t) SKANSIBLE_UNITTEST=True;;
u) export ANSIBLE_REMOTE_USER="$OPTARG";;
m) SKANSIBLE_MODE="$OPTARG";;
d) SKANSIBLE_FQDN="$OPTARG";;
*) echo "Err: Invalid option set"; exit 1;;
esac
done
@@ -99,23 +100,23 @@ if [[ "$1" == "init" ]]; then
# SKANSIBLE_CONN_HOST=staging${SKANSIBLE_STAGE}.test
if [[ "$SKANSIBLE_STAGE" == 0 ]]; then
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
sudo ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
sudo ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
else
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
fi
elif [[ "$SKANSIBLE_STAGE" == 1 ]]; then
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
sudo ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
sudo ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
else
sudo ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
sudo ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
fi
fi
else
if [[ -z "$SKANSIBLE_CONN_HOST" ]]; then
echo "When not doing staging, chosen or preferred host must be made explicit"
if [[ -z "$SKANSIBLE_CONN_HOST" ]] && [[ -z "$SKANSIBLE_FQDN" ]]; then
echo "When not doing staging, chosen or preferred host must be made explicit as well as desired FQDN"
exit 1
else
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=prod" "init@${SKANSIBLE_PLAY_HOST}.yml"
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=prod" --extra-vars "fqdn=${SKANSIBLE_FQDN}" "init@${SKANSIBLE_PLAY_HOST}.yml"
fi
fi
@@ -125,7 +126,7 @@ fi
if [[ "$1" == "bootstrap" ]]; then
shift 1
source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
if [[ "$1" == "vps" ]]; then
SKANSIBLE_PLAY_HOST="$1"
@@ -138,7 +139,7 @@ if [[ "$1" == "bootstrap" ]]; then
exit 1
fi
while getopts "htm:s:n:v:u:" opt; do
while getopts "htd:m:s:n:v:u:" opt; do
case $opt in
h) Help "bootstrap";;
s) SKANSIBLE_STAGE="$OPTARG";;
@@ -147,6 +148,7 @@ if [[ "$1" == "bootstrap" ]]; then
t) SKANSIBLE_UNITTEST=True;;
u) export ANSIBLE_REMOTE_USER="$OPTARG";;
m) SKANSIBLE_MODE="$OPTARG";;
d) SKANSIBLE_FQDN="$OPTARG";;
*) echo "Err: Invalid option set"; exit 1;;
esac
done
@@ -155,23 +157,23 @@ if [[ "$1" == "bootstrap" ]]; then
# SKANSIBLE_CONN_HOST=staging${SKANSIBLE_STAGE}.test
if [[ "$SKANSIBLE_STAGE" == 0 ]]; then
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
else
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
fi
elif [[ "$SKANSIBLE_STAGE" == 1 ]]; then
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
else
ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
fi
fi
else
if [[ -z "$SKANSIBLE_CONN_HOST" ]]; then
echo "When not doing staging, chosen or preferred host must be made explicit"
echo "When not doing staging, chosen or preferred host must be made explicit as well as desired FQDN"
exit 1
else
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=prod" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=prod" --extra-vars "fqdn=${SKANSIBLE_FQDN}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
fi
fi
+7 -1
View File
@@ -1,6 +1,12 @@
Vagrant.configure("2") do |config|
config.vm.box = "debian/trixie64"
config.vm.network "public_network", ip: "192.168.122.234", network_name: virbr0
config.vm.hostname = "staging0.test"
config.vm.network "private_network", ip: "192.168.122.234", bridge: "virbr0", ipv6: true
config.vm.network "forwarded_port", guest: 51820, host: 51820
config.vm.network "forwarded_port", guest: 80, host: 80
config.vm.network "forwarded_port", guest: 443, host: 443
config.ssh.username = "root"
config.ssh.password = "vagrant"
config.vm.provider "libvirt" do |lv|
lv.memory = 2048
lv.cpus = 3
+7 -1
View File
@@ -1,6 +1,12 @@
Vagrant.configure("2") do |config|
config.vm.box = "debian/trixie64"
config.vm.network "public_network", ip: "192.168.200.201", network_name: virbr1
config.vm.hostname = "staging0.test"
config.vm.network "private_network", ip: "192.168.200.201", bridge: "virbr0", ipv6: true
config.vm.network "forwarded_port", guest: 51820, host: 51820
# config.vm.network "forwarded_port", guest: 80, host: 80
# config.vm.network "forwarded_port", guest: 443, host: 443
config.ssh.username = "root"
config.ssh.password = "vagrant"
config.vm.provider "libvirt" do |lv|
lv.memory = 2048
lv.cpus = 3
+2 -2
View File
@@ -5,6 +5,6 @@ certbot:
port: ~
email: ajt95@prole.biz
domains:
- "{{ inventory_hostname }}"
- "*.{{ inventory_hostname }}"
- "{{ fqdn | default(inventory_hostname) }}"
- "*.{{ fqdn | default(inventory_hostname) }}"
cron: "2 6 24 1 *"
+2 -2
View File
@@ -5,6 +5,6 @@ certbot:
port: 53
email: ajt95@prole.biz
domains:
- "{{ inventory_hostname }}"
- "*.{{ inventory_hostname }}"
- "{{ fqdn | default(inventory_hostname) }}"
- "*.{{ fqdn | default(inventory_hostname) }}"
cron: ~