From 23c9fd55aff6e4c3925e712259572ef79a4f91b8 Mon Sep 17 00:00:00 2001 From: Zalim Date: Sun, 26 Jul 2026 22:31:48 +0300 Subject: [PATCH] Initial Ansible scenarios --- .gitignore | 3 ++ README.md | 33 ++++++++++++++++++++++ ansible | 21 ++++++++++++++ ansible.cfg | 4 +++ inventory/credentials.example.yml | 6 ++++ inventory/hosts.example.yml | 6 ++++ playbooks/site.yml | 25 +++++++++++++++++ scenarios/docker-pull.yml | 46 +++++++++++++++++++++++++++++++ scenarios/reboot.yml | 5 ++++ scenarios/soft.yml | 17 ++++++++++++ scenarios/update.yml | 6 ++++ 11 files changed, 172 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 ansible create mode 100644 ansible.cfg create mode 100644 inventory/credentials.example.yml create mode 100644 inventory/hosts.example.yml create mode 100644 playbooks/site.yml create mode 100644 scenarios/docker-pull.yml create mode 100644 scenarios/reboot.yml create mode 100644 scenarios/soft.yml create mode 100644 scenarios/update.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4ff5f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/err.txt +/inventory/hosts.yml +/inventory/credentials.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d4f6ce --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Ansible scenarios + +Inventory is stored in `inventory/hosts.yml`. Each host has a name; the first +one is `localhost`. Each scenario is a separate file in `scenarios/`. + +`inventory/hosts.yml` and `inventory/credentials.yml` are local files and are +not committed to Git. Use the matching `*.example.yml` files as templates. + +Run one scenario on one host: + +```bash +./ansible localhost update +``` + +The first argument selects the host or host group, and the second selects one +or more scenarios. For example, after adding a `backup` scenario: + +```bash +./ansible localhost update,backup +``` + +The full Ansible command remains available when required: + +```bash +ansible-playbook playbooks/site.yml --limit localhost --tags update +``` + +The `update` scenario updates all installed system packages. The `reboot` +scenario restarts the selected host. The `soft` scenario installs common +utilities. The `docker-pull` scenario updates only running Compose projects: +it pulls their images and recreates containers when an image has changed. Add +new hosts to `inventory/hosts.yml` and new scenarios to `scenarios/`, then +import each new scenario into `playbooks/site.yml` with its own tag. diff --git a/ansible b/ansible new file mode 100755 index 0000000..d33b968 --- /dev/null +++ b/ansible @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -lt 2 ]]; then + echo "Usage: ./ansible [extra ansible-playbook options]" >&2 + exit 2 +fi + +host="$1" +scenarios="$2" +shift 2 + +ansible_runtime_dir="${TMPDIR:-/tmp}/ansible-${UID}" +mkdir -p "$ansible_runtime_dir/local" "$ansible_runtime_dir/cp" +export ANSIBLE_LOCAL_TEMP="$ansible_runtime_dir/local" +export ANSIBLE_SSH_CONTROL_PATH_DIR="$ansible_runtime_dir/cp" + +exec ansible-playbook playbooks/site.yml \ + --limit "$host" \ + --tags "$scenarios" \ + "$@" diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..84d5a39 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +inventory = inventory/hosts.yml,inventory/credentials.yml +host_key_checking = False +interpreter_python = auto_silent diff --git a/inventory/credentials.example.yml b/inventory/credentials.example.yml new file mode 100644 index 0000000..03eaf50 --- /dev/null +++ b/inventory/credentials.example.yml @@ -0,0 +1,6 @@ +--- +all: + hosts: + example: + ansible_password: change-me + ansible_become_password: change-me diff --git a/inventory/hosts.example.yml b/inventory/hosts.example.yml new file mode 100644 index 0000000..1f84fe6 --- /dev/null +++ b/inventory/hosts.example.yml @@ -0,0 +1,6 @@ +--- +all: + hosts: + example: + ansible_host: 192.0.2.10 + ansible_user: deploy diff --git a/playbooks/site.yml b/playbooks/site.yml new file mode 100644 index 0000000..d27ecf9 --- /dev/null +++ b/playbooks/site.yml @@ -0,0 +1,25 @@ +--- +- name: Run selected maintenance scenarios + hosts: all + become: true + gather_facts: true + tasks: + - name: Update system + ansible.builtin.import_tasks: ../scenarios/update.yml + tags: + - update + + - name: Reboot host + ansible.builtin.import_tasks: ../scenarios/reboot.yml + tags: + - reboot + + - name: Install common utilities + ansible.builtin.import_tasks: ../scenarios/soft.yml + tags: + - soft + + - name: Pull Docker Compose images + ansible.builtin.import_tasks: ../scenarios/docker-pull.yml + tags: + - docker-pull diff --git a/scenarios/docker-pull.yml b/scenarios/docker-pull.yml new file mode 100644 index 0000000..49ffbb2 --- /dev/null +++ b/scenarios/docker-pull.yml @@ -0,0 +1,46 @@ +--- +- name: List running Docker Compose projects + ansible.builtin.command: + argv: + - docker + - compose + - ls + - --format + - json + register: docker_compose_projects + changed_when: false + +- name: Select running Docker Compose projects + ansible.builtin.set_fact: + running_compose_projects: "{{ docker_compose_projects.stdout | from_json }}" + +- name: Pull images for each running Docker Compose project + ansible.builtin.command: + argv: + - docker + - compose + - -p + - "{{ item.Name }}" + - pull + environment: + COMPOSE_FILE: "{{ item.ConfigFiles | replace(',', ':') }}" + loop: "{{ running_compose_projects }}" + loop_control: + label: "{{ item.Name }}" + changed_when: true + +- name: Recreate Docker Compose containers with updated images + ansible.builtin.command: + argv: + - docker + - compose + - -p + - "{{ item.Name }}" + - up + - -d + environment: + COMPOSE_FILE: "{{ item.ConfigFiles | replace(',', ':') }}" + loop: "{{ running_compose_projects }}" + loop_control: + label: "{{ item.Name }}" + changed_when: true diff --git a/scenarios/reboot.yml b/scenarios/reboot.yml new file mode 100644 index 0000000..fdd2c55 --- /dev/null +++ b/scenarios/reboot.yml @@ -0,0 +1,5 @@ +--- +- name: Reboot host + ansible.builtin.reboot: + reboot_timeout: 600 + diff --git a/scenarios/soft.yml b/scenarios/soft.yml new file mode 100644 index 0000000..451a276 --- /dev/null +++ b/scenarios/soft.yml @@ -0,0 +1,17 @@ +--- +- name: Install common utilities + ansible.builtin.package: + name: + - mc + - htop + - iotop + - curl + - git + - bash-completion + - unzip + - ca-certificates + - gnupg + - net-tools + - btop + state: present + diff --git a/scenarios/update.yml b/scenarios/update.yml new file mode 100644 index 0000000..d6b89f1 --- /dev/null +++ b/scenarios/update.yml @@ -0,0 +1,6 @@ +--- +- name: Update all installed packages + ansible.builtin.package: + name: "*" + state: latest +