Compare commits

...

10 Commits

17 changed files with 217 additions and 75 deletions
+3
View File
@@ -1,3 +1,6 @@
# ---> Ansible # ---> Ansible
*.retry *.retry
inventory/group_vars/secret/ inventory/group_vars/secret/
# Ignore python venv
.venv
+1 -1
View File
@@ -1,5 +1,5 @@
--- ---
physical: physical:
hosts: hosts:
192.168.0.40: 192.168.0.45:
ansible_become_password: "{{ ansible_become_passwd }}" ansible_become_password: "{{ ansible_become_passwd }}"
@@ -15,9 +15,3 @@
vars: vars:
ansible_user_passwd_hash: "{{ ansible_password | password_hash('sha512', 's3edscrj45e6r') }}" ansible_user_passwd_hash: "{{ ansible_password | password_hash('sha512', 's3edscrj45e6r') }}"
user_passwd_hash: "{{ user_password | password_hash('sha512', 's3ed6123jhgcr') }}" user_passwd_hash: "{{ user_password | password_hash('sha512', 's3ed6123jhgcr') }}"
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
+28
View File
@@ -0,0 +1,28 @@
---
- name: Deploy a virtual machine from a cloud init image
hosts: localhost
gather_facts: false
roles:
- ../roles/basic_proxmox_vm
- name: Basic Proxmox guest deployment
hosts: all
remote_user: ansible
roles:
- ../roles/basic_postinstall
vars_files:
../inventory/group_vars/all/secrets.yaml
vars:
ansible_user_passwd_hash: "{{ ansible_password | password_hash('sha512', 's3edscrj45e6r') }}"
user_passwd_hash: "{{ user_password | password_hash('sha512', 's3ed6123jhgcr') }}"
handlers:
- name: restart ssh-server
service:
name: ssh
state: restarted
- name: restart sshd-server
service:
name: sshd
state: restarted
+30
View File
@@ -0,0 +1,30 @@
ansible-compat==26.6.0
ansible-core==2.21.1
ansible-lint==26.6.0
attrs==26.1.0
black==26.5.1
bracex==3.0
cffi==2.1.0
click==8.4.2
cryptography==49.0.0
distro==1.9.0
filelock==3.29.7
Jinja2==3.1.6
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
MarkupSafe==3.0.3
mypy_extensions==1.1.0
packaging==26.2
pathspec==1.1.1
platformdirs==4.10.0
pycparser==3.0
pytokens==0.4.1
PyYAML==6.0.3
referencing==0.37.0
resolvelib==1.2.1
rpds-py==2026.6.3
ruamel.yaml==0.19.1
ruamel.yaml.clib==0.2.15
subprocess-tee==0.4.2
wcmatch==11.0
yamllint==1.38.0
@@ -1,7 +1,7 @@
--- ---
- name: Create a new user with a password, set shell - name: Create a new user with a password, set shell
remote_user: ansible remote_user: ansible
user: ansible.builtin.user:
name: max name: max
groups: sshusers,sudo groups: sshusers,sudo
password: "{{ user_passwd_hash }}" password: "{{ user_passwd_hash }}"
@@ -12,12 +12,12 @@
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: max user: max
state: present state: present
key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/ansible_key.pub') }}" key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/ansible_key.pub') }}"
- name: Copy omz installation wrapper script to the target machine - name: Copy omz installation wrapper script to the target machine
remote_user: ansible remote_user: ansible
copy: ansible.builtin.copy:
src: ../files/install_omz.sh src: "{{ role_path }}/files/install_omz.sh"
dest: /home/max/install_omz.sh dest: /home/max/install_omz.sh
owner: max owner: max
group: max group: max
@@ -26,13 +26,14 @@
# WARNING: UNPRIVILEGED USER (not ansible) COMMANDS # WARNING: UNPRIVILEGED USER (not ansible) COMMANDS
- name: Install oh my zsh - name: Install oh my zsh
remote_user: max remote_user: max
become: no become: false
command: /home/max/install_omz.sh ansible.builtin.command: /home/max/install_omz.sh
changed_when: true
- name: Configure oh my zsh, by pushing the config file - name: Configure oh my zsh, by pushing the config file
remote_user: ansible remote_user: ansible
copy: ansible.builtin.copy:
src: ../files/.zshrc src: "{{ role_path }}/files/.zshrc"
dest: /home/max/.zshrc dest: /home/max/.zshrc
owner: max owner: max
group: max group: max
@@ -40,8 +41,8 @@
- name: Configure vim, by pushing the config - name: Configure vim, by pushing the config
remote_user: ansible remote_user: ansible
copy: ansible.builtin.copy:
src: ../files/.vimrc src: "{{ role_path }}/files/.vimrc"
dest: /home/max/.vimrc dest: /home/max/.vimrc
owner: max owner: max
group: max group: max
@@ -55,11 +56,11 @@
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: max user: max
state: absent state: absent
key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/ansible_key.pub') }}" key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/ansible_key.pub') }}"
- name: Set authorized key taken from file - name: Set authorized key taken from file
remote_user: ansible remote_user: ansible
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: max user: max
state: present state: present
key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/max_regular_key.pub') }}" key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/max_regular_key.pub') }}"
+14 -2
View File
@@ -5,7 +5,6 @@
src: "{{ role_path }}/files/hardened_sshd.conf" src: "{{ role_path }}/files/hardened_sshd.conf"
dest: /etc/ssh/sshd_config.d/hardened_sshd.conf dest: /etc/ssh/sshd_config.d/hardened_sshd.conf
mode: u=rw,g=r,o=r mode: u=rw,g=r,o=r
notify: restart ssh-server
when: ansible_facts['distribution'] == 'Ubuntu' when: ansible_facts['distribution'] == 'Ubuntu'
- name: Configure ssh-server daemon - name: Configure ssh-server daemon
@@ -13,7 +12,6 @@
src: "{{ role_path }}/files/hardened_sshd.conf" src: "{{ role_path }}/files/hardened_sshd.conf"
dest: /etc/ssh/sshd_config.d/hardened_sshd.conf dest: /etc/ssh/sshd_config.d/hardened_sshd.conf
mode: u=rw,g=r,o=r mode: u=rw,g=r,o=r
notify: restart sshd-server
when: ansible_facts['distribution'] == 'Debian' when: ansible_facts['distribution'] == 'Debian'
- name: Configure ssh client - name: Configure ssh client
@@ -22,3 +20,17 @@
src: "{{ role_path }}/files/hardened_ssh.conf" src: "{{ role_path }}/files/hardened_ssh.conf"
dest: /etc/ssh/ssh_config.d/hardened_ssh.conf dest: /etc/ssh/ssh_config.d/hardened_ssh.conf
mode: u=rw,g=r,o=r mode: u=rw,g=r,o=r
- name: Restart ssh-server Debian
remote_user: ansible
ansible.builtin.service:
name: sshd
state: restarted
when: ansible_facts['distribution'] == 'Debian'
- name: Restart ssh-server Ubuntu
remote_user: ansible
ansible.builtin.service:
name: ssh
state: restarted
when: ansible_facts['distribution'] == 'Ubuntu'
@@ -37,6 +37,6 @@
- name: Update and install packages on Alpine - name: Update and install packages on Alpine
when: (ansible_facts['distribution'] == "Alpine") when: (ansible_facts['distribution'] == "Alpine")
community.general.apk: community.general.apk:
name: vim ranger zsh rsync git curl kitty name: vim ranger zsh rsync git curl kitty openssh
update_cache: true update_cache: true
remote_user: ansible remote_user: ansible
@@ -3,18 +3,18 @@
- name: Install sudo on apt systems - name: Install sudo on apt systems
when: (ansible_facts['distribution'] == "Debian") or when: (ansible_facts['distribution'] == "Debian") or
(ansible_facts['distribution'] == "Ubuntu") (ansible_facts['distribution'] == "Ubuntu")
apt: ansible.builtin.apt:
name: name:
- sudo - sudo
update-cache: yes update-cache: true
- name: Update Alpine packages # The same commands for Alpine
- name: Update and install packages on Alpine
when: (ansible_facts['distribution'] == "Alpine") when: (ansible_facts['distribution'] == "Alpine")
command: /sbin/apk update community.general.apk:
name: sudo
- name: Install sudo package on Alpine update_cache: true
when: (ansible_facts['distribution'] == "Alpine") remote_user: ansible
command: /sbin/apk add sudo
## Creating and setting up the ansible user ## Creating and setting up the ansible user
@@ -26,12 +26,12 @@
## Add the user to sshusers (for ssh access) and sudo (gain root access) ## Add the user to sshusers (for ssh access) and sudo (gain root access)
- name: Create a new user with a password for Ansible - name: Create a new user with a password for Ansible
user: ansible.builtin.user:
name: ansible name: ansible
password: "{{ ansible_user_passwd_hash }}" password: "{{ ansible_user_passwd_hash }}"
groups: sshusers,sudo groups: sshusers,sudo
append: yes append: true
## Since password authentication in SSH will be disabled, we need to add an authorized key ## Since password authentication in SSH will be disabled, we need to add an authorized key
- name: Set authorized key taken from file - name: Set authorized key taken from file
@@ -4,11 +4,11 @@
remote_user: ansible remote_user: ansible
when: (ansible_facts['distribution'] == "Debian") or when: (ansible_facts['distribution'] == "Debian") or
(ansible_facts['distribution'] == "Ubuntu") (ansible_facts['distribution'] == "Ubuntu")
apt: ansible.builtin.apt:
name: name:
- nano - nano
state: absent state: absent
become: yes become: true
# Clean up all orphaned packages # Clean up all orphaned packages
@@ -16,12 +16,16 @@
remote_user: ansible remote_user: ansible
when: (ansible_facts['distribution'] == "Debian") or when: (ansible_facts['distribution'] == "Debian") or
(ansible_facts['distribution'] == "Ubuntu") (ansible_facts['distribution'] == "Ubuntu")
apt: ansible.builtin.apt:
autoremove: yes autoremove: true
purge: yes purge: true
- name: Install sudo package on Alpine - name: Install sudo package on Alpine
remote_user: ansible remote_user: ansible
when: (ansible_facts['distribution'] == "Alpine") when: (ansible_facts['distribution'] == "Alpine")
command: /sbin/apk del nano community.general.apk:
name:
- nano
state: absent
become: true
@@ -1,9 +1,9 @@
--- ---
- name: Generate locales - name: Generate locales
ansible.builtin.locale_gen: community.general.locale_gen:
name: name:
- en_US.UTF-8 - en_US.UTF-8
- ru_RU.UTF-8 - ru_RU.UTF-8
state: present state: present
- name: Set locale - name: Set locale
@@ -15,5 +15,5 @@
LC_ALL=en_US.UTF-8 LC_ALL=en_US.UTF-8
- name: Set time - name: Set time
ansible.builtin.timezone: community.general.timezone:
name: Europe/Samara name: Europe/Samara
+15 -4
View File
@@ -1,31 +1,35 @@
--- ---
- name: Create new container with minimal options defining network interface with static ip - name: Create new container with minimal options defining network interface with static ip
become: no become: false
community.proxmox.proxmox: community.proxmox.proxmox:
validate_certs: false
node: proxmox-server node: proxmox-server
api_user: root@pam api_user: root@pam
api_host: 192.168.0.2 api_host: 192.168.0.2
api_token_id: ansible api_token_id: ansible
api_token_secret: "{{ proxmox_token_secret }}" api_token_secret: "{{ proxmox_token_secret }}"
cmode: "shell"
vmid: 1040 vmid: 1040
password: ansible-test password: ansible-test
hostname: "ansible-test" hostname: "ansible-test"
ostemplate: 'main:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst' # ostemplate: 'main:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst'
ostemplate: 'main:vztmpl/debian-13-golden-image.tar.gz'
memory: 2048 memory: 2048
cores: 5 cores: 5
state: present state: present
disk_volume: disk_volume:
size: 2 # 2GB rootfs size: 2 # 2GB rootfs
storage: local storage: local
pubkey: "{{ lookup('file', lookup('env','HOME') + '/.ssh/ansible_key.pub') }}" pubkey: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/ansible_key.pub') }}"
netif: netif:
net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.40/24,bridge=vmbr0" net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.40/24,bridge=vmbr0"
- name: Make sure the container has started - name: Make sure the container has started
become: no become: false
community.proxmox.proxmox: community.proxmox.proxmox:
validate_certs: false
node: proxmox-server node: proxmox-server
api_user: root@pam api_user: root@pam
api_host: 192.168.0.2 api_host: 192.168.0.2
@@ -34,3 +38,10 @@
vmid: 1040 vmid: 1040
state: started state: started
- name: Sleep for a minute to ensure that ssh is ready
become: false
ansible.builtin.wait_for:
timeout: 60
delegate_to: localhost
changed_when: false
+53
View File
@@ -0,0 +1,53 @@
---
- name: Create a new VM with minimal options
become: false
community.proxmox.proxmox_kvm:
validate_certs: false
node: proxmox-server
api_user: root@pam
api_host: 192.168.0.2
api_token_id: ansible
api_token_secret: "{{ proxmox_token_secret }}"
clone: debian-13-cloud-init-template
newid: 1041
name: ansible-ci-test
storage: main
format: qcow2
full: true
timeout: 500
- name: Tweak the hardware settings
become: false
community.proxmox.proxmox_kvm:
validate_certs: false
node: proxmox-server
api_user: root@pam
api_host: 192.168.0.2
api_token_id: ansible
api_token_secret: "{{ proxmox_token_secret }}"
vmid: 1041
cores: 4
memory: 4096 # Minimal value for debian based OS for smooth workflow
update: true
- name: Make sure the VM has started
become: false
community.proxmox.proxmox_kvm:
validate_certs: false
node: proxmox-server
api_user: root@pam
api_host: 192.168.0.2
api_token_id: ansible
api_token_secret: "{{ proxmox_token_secret }}"
vmid: 1041
state: started
- name: Sleep for 3 minutes to ensure that cloud-init's done its thing
become: false
ansible.builtin.wait_for:
timeout: 180
delegate_to: localhost
changed_when: false
+19 -13
View File
@@ -2,14 +2,14 @@
- name: Internet connection test block - name: Internet connection test block
block: block:
- name: Test reachability to ya.ru - name: Test reachability to ya.ru
become: yes # Usually it's not necessary, but sometimes there are some wierd issues with ping, especially on Alpine become: true # Usually it's not necessary, but sometimes there are some wierd issues with ping, especially on Alpine
shell: ping -c 5 ya.ru > /dev/null ansible.builtin.shell: ping -c 5 ya.ru > /dev/null
changed_when: false # This task does not change the system changed_when: false # This task does not change the system
rescue: rescue:
# This won't work for now. CA certificate reissuing is required!git # This won't work for now. CA certificate reissuing is required!
- name: Create a test file - name: Create a test file
become: no become: false
ansible.builtin.uri: ansible.builtin.uri:
url: "{{ ha_addr }}/api/webhook/{{ ha_webhook_token }}" url: "{{ ha_addr }}/api/webhook/{{ ha_webhook_token }}"
ca_path: ../files/ca.pem ca_path: ../files/ca.pem
@@ -20,19 +20,25 @@
- name: Disk free space test block - name: Disk free space test block
block: block:
- name: Test free disk space in root - name: Test free disk space in root
become: no become: false
shell: df -h / | tail -1 | awk '{gsub(/%/, "", $5); print $5}' ansible.builtin.shell: set -o pipefail && df -h / | tail -1 | awk '{gsub(/%/, "", $5); print $5}'
register: result register: common_healthcheck_result
failed_when: result.stdout | int > 85 failed_when: common_healthcheck_result.stdout | int > 85
changed_when: false # This task does not change the system changed_when: false # This task does not change the system
rescue: rescue:
- name: Notify with ntfy - name: Notify with ntfy
become: no become: false
ansible.builtin.command: | ansible.builtin.uri:
curl -H "Authorization: Bearer {{ ntfy_topic_token }}" \ url: "{{ ntfy_topic }}"
-d "{{ ansible_facts['hostname'] }}: Disk space is low" \ method: POST
{{ ntfy_topic }} body_format: json
status_code: [200, 202]
return_content: true
headers:
Authorization: "Bearer {{ ntfy_topic_token }}"
body:
- "{{ ansible_facts['hostname'] }}: Disk space is low"
delegate_to: 127.0.0.1 delegate_to: 127.0.0.1
failed_when: false failed_when: false
changed_when: false # This task does not change the system changed_when: false # This task does not change the system