Compare commits

...

31 Commits

Author SHA1 Message Date
a3b772c543 fix risky-shell-pipe 2024-10-28 18:47:31 +01:00
adde811f47 Fix risky-file-permissions because of unpecified mode 2024-10-28 18:37:44 +01:00
f788767839 Fix line-length 2024-10-28 18:26:54 +01:00
8b773d2304 Adjust literal-compare to use correct bool comparison 2024-10-28 17:17:24 +01:00
c988ab8f9a dont use ignore-errors 2024-07-11 22:31:13 +02:00
8864db253b add missing task name 2024-07-11 22:22:43 +02:00
06ca8d8787 ansible-lint fixes 2024-07-11 22:20:45 +02:00
374b5fc7ef use correct boolean values 2024-07-11 22:09:58 +02:00
6bfd530c90 fix jinja formating 2024-07-11 22:03:15 +02:00
b077e549db remove btrfs quota limits 2024-05-21 14:20:28 +02:00
43ce280d11 correct README 2024-04-17 14:38:47 +02:00
a6b51b4cb4 Add supported distro to the README 2024-04-17 14:37:47 +02:00
6dd31cc95f fix cis support for all distros 2024-04-17 14:09:32 +02:00
4b98ec1434 add ubuntu-lts support 2024-04-17 12:17:19 +02:00
2444c5d7af add ubuntu support 2024-04-17 10:53:09 +02:00
ec6ca49265 fix fedora boot issue 2024-04-17 06:02:32 +02:00
fe43bf6733 add essential almalinux packages 2024-04-17 05:06:45 +02:00
31c155ce92 install dnf if {{ os }} is fedora 2024-04-17 04:47:33 +02:00
0c75114b94 add rocky to README example 2024-04-17 04:39:29 +02:00
cd9ed65c91 Add essential rockylinux packages 2024-04-17 04:32:11 +02:00
9986d19ed6 Add en and de langauge support for rockylinux 2024-04-17 04:19:32 +02:00
d73e78c5f2 Add cloud-init support 2024-04-16 01:17:48 +02:00
b6f620fb70 Add RockyLinux support 2024-04-16 01:14:12 +02:00
cc40bae858 Add RockyLinux support 2024-04-16 01:14:05 +02:00
344753fa5b Add RockyLinux Repo file 2024-04-15 21:30:04 +02:00
6be464a0e2 move assertion list to main playbook 2024-04-15 21:23:32 +02:00
48b5f602fa Enable systemd-resolved and systemd-timesyncd services for ArchLinux 2024-03-28 03:50:04 +01:00
cc118274a3 Update gitignore 2024-03-22 12:48:49 +01:00
sandwich
d733513e29 Delete vars_libvirt.yml 2024-03-22 12:46:31 +01:00
sandwich
402f2b9bc0 Delete inventory_libvirt.yml 2024-03-22 12:46:22 +01:00
4ec5432989 Add inventory example in yaml 2024-03-22 12:43:13 +01:00
21 changed files with 693 additions and 406 deletions

3
.gitignore vendored
View File

@@ -1,5 +1,8 @@
inventory.yml
inventory.yaml
inventory_libvirt.yml
vars.yml
vars.yaml
vars_kvm.yml
vars_libvirt.yml

View File

@@ -9,6 +9,22 @@ Most of the roles are adaptable for use with systems beyond ArchLinux, requiring
- RHEL Systems are not currently supported due to restricted access to their repositories.
A workaround could involve using an ISO as a local repository or setting up a proxy repository to facilitate access.
# Supported Distributions
This playbook supports multiple Linux distributions with specific versions tailored to each. Below is a list of supported distributions:
| `os` | Distribution |
|------------|------------------------------------|
| archlinux | ArchLinux (Latest rolling release) |
| almalinux | AlmaLinux 9.x |
| debian11 | Debian 11 (Bullseye) |
| debian12 | Debian 12 (Bookworm) |
| fedora | Fedora 40 |
| rocky | Rocky Linux 9.x |
| ubuntu | Ubuntu 23.10 (Mantic Minotaur) |
| ubuntu-lts | Ubuntu 22.04 LTS (Jammy Jellyfish) |
# Documentation
## Table of Contents
@@ -52,7 +68,7 @@ Inventory variables are defined for individual hosts or VMs in the inventory fil
| `cis` (optional) | Adjusts the installation to be CIS level 3 conformant. | `true`, `false` |
| `filesystem` | Filesystem type for the VM's primary storage. | `btrfs`, `ext4`, `xfs` |
| `hostname` | The hostname assigned to the virtual machine or system. | `vm01` |
| `os` | Operating system to be installed on the VM. | `archlinux`, `almalinux`, `debian11`, `debian12`, `fedora` |
| `os` | Operating system to be installed on the VM. | `archlinux`, `almalinux`, `debian11`, `debian12`, `fedora`, `rocky`, `ubuntu`, `ubuntu-lts` |
| `root_password` | Root password for the VM or system, used for initial setup or secure access. | `SecurePass123` |
| `user_name` | Username for a user account within the VM, often used with cloud-init. | `adminuser` |
| `user_password` | Password for the user account within the VM. | `UserPass123` |

28
inventory_example.yml Normal file
View File

@@ -0,0 +1,28 @@
all:
children:
promox-kvm:
hosts:
192.168.122.10:
hostname: proxy
vm_id: 100
os: archlinux
filesystem: btrfs
vm_memory: "2048"
vm_ballo: "1024"
vm_cpus: "2"
vm_size: "5"
vm_nif: vmbr1
vm_gw: 192.168.122.1
vm_dns: 1.1.1.1
192.168.122.11:
hostname: database
vm_id: 101
os: archlinux
filesystem: btrfs
vm_memory: "6144"
vm_ballo: "3072"
vm_cpus: "4"
vm_size: "40"
vm_nif: vmbr1
vm_gw: 192.168.122.1
vm_dns: 1.1.1.1

View File

@@ -27,36 +27,35 @@
- proxmox
- vmware
private: false
default: "proxmox"
default: proxmox
- name: install_drive
prompt: |
"Enter the drive to install the system (default: /dev/sda)"
confirm: true
private: false
default: "/dev/sda"
default: /dev/sda
vars_files: vars.yml
pre_tasks:
- name: Set ansible_python_interpreter
when: os | lower in ["almalinux", "rhel9", "rhel8"]
set_fact:
when: os | lower in ["almalinux", "rhel9", "rhel8", "rocky"]
ansible.builtin.set_fact:
ansible_python_interpreter: /usr/bin/python3
- name: Validate variables
assert:
ansible.builtin.assert:
that:
- hypervisor in hypervisor_list
- filesystem in filesystem_list
- os in os_list
fail_msg: "Invalid input specified, please try again"
- hypervisor in ["libvirt", "proxmox", "vmware", "none"]
- filesystem in ["btrfs", "ext4", "xfs"]
- os in ["archlinux", "almalinux", "debian11", "debian12", "fedora", "rocky", "ubuntu", "ubuntu-lts"]
fail_msg: Invalid input specified, please try again
- name: Set connection
when: hypervisor == "vmware"
set_fact:
ansible.builtin.set_fact:
ansible_connection: vmware_tools
roles:
- role: virtualization
when: install_type == "virtual"
become: false
@@ -87,5 +86,5 @@
tasks:
- name: Reboot system
when: hypervisor != "libvirt"
command: reboot
ansible.builtin.command: reboot
ignore_errors: true

View File

@@ -1,6 +1,6 @@
---
- name: Include Packages
include_vars:
ansible.builtin.include_vars:
file: packages.yml
name: role_packages
@@ -8,36 +8,58 @@
block:
- name: Bootstrap ArchLinux
when: os | lower == 'archlinux'
command: pacstrap /mnt {{ role_packages.archlinux | join(' ') }} --asexplicit
ansible.builtin.command: pacstrap /mnt {{ role_packages.archlinux | join(' ') }} --asexplicit
- name: Bootstrap Debian System
when: os | lower in ['debian11', 'debian12']
shell: "{{ item }}"
ansible.builtin.command: "{{ item }}"
with_items:
- debootstrap --include={{ role_packages[os].base | join(',') }} {{ 'bullseye' if os == 'debian11' else 'bookworm' }} /mnt http://deb.debian.org/debian/
- |
debootstrap --include={{ role_packages[os].base | join(',') }} {{ 'bullseye' if os == 'debian11' else 'bookworm' }} \
/mnt http://deb.debian.org/debian/
- arch-chroot /mnt apt install -y {{ role_packages[os].extra | join(' ') }}
- arch-chroot /mnt apt remove -y libcups2 libavahi-common3 libavahi-common-data
- name: Bootstrap Ubuntu System
when: os | lower in ['ubuntu', 'ubuntu-lts']
ansible.builtin.command: "{{ item }}"
with_items:
- |
debootstrap --include={{ role_packages[os].base | join(',') }} {{ 'mantic' if os == 'ubuntu' else 'jammy' }} \
/mnt http://archive.ubuntu.com/ubuntu/
- arch-chroot /mnt sed -i '1s|$| universe|' /etc/apt/sources.list
- arch-chroot /mnt apt update -y
- arch-chroot /mnt apt install -y {{ role_packages[os].extra | join(' ') }}
- name: Bootstrap AlmaLinux 9
when: os | lower == 'almalinux'
shell: "{{ item }}"
ansible.builtin.command: "{{ item }}"
with_items:
- dnf --releasever=9 --best --repo=alma-baseos --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y base core
- echo "nameserver 1.0.0.1" > /mnt/etc/resolv.conf
- arch-chroot /mnt dnf --releasever=9 --setopt=install_weak_deps=False install -y {{ role_packages.almalinux | join(' ') }}
- name: Bootstrap Fedora 39
- name: Bootstrap Fedora 40
when: os | lower == 'fedora'
shell: "{{ item }}"
ansible.builtin.command: "{{ item }}"
with_items:
- dnf --releasever=39 --best --repo=fedora --repo=fedora-updates --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y critical-path-base core
- arch-chroot /mnt dnf --releasever=39 --setopt=install_weak_deps=False install -y {{ role_packages.fedora | join(' ') }}
- arch-chroot /mnt dnf reinstall -y grub2-efi-x64 kernel
- |
dnf --releasever=40 --best --repo=fedora --repo=fedora-updates \
--installroot=/mnt --setopt=install_weak_deps=False groupinstall -y critical-path-base core
- arch-chroot /mnt dnf --releasever=40 --setopt=install_weak_deps=False install -y {{ role_packages.fedora | join(' ') }}
- arch-chroot /mnt dnf reinstall -y kernel-core
- name: Bootstrap RockyLinux 9
when: os | lower == 'rocky'
ansible.builtin.command: "{{ item }}"
with_items:
- dnf --releasever=9 --best --repo=rocky-baseos --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y base core
- echo "nameserver 1.0.0.1" > /mnt/etc/resolv.conf
- arch-chroot /mnt dnf --releasever=9 --setopt=install_weak_deps=False install -y {{ role_packages.rocky | join(' ') }}
- name: Bootstrap RHEL System
when: os | lower in ['rhel8', 'rhel9']
shell: "{{ item }}"
ansible.builtin.command: "{{ item }}"
with_items:
- "dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y base core"
- "echo 'nameserver 1.0.0.1' > /mnt/etc/resolv.conf"
- "arch-chroot /mnt dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --setopt=install_weak_deps=False install -y {{ role_packages[os] | join(' ') }}"
- dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y base core
- echo 'nameserver 1.0.0.1' > /mnt/etc/resolv.conf
- arch-chroot /mnt dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --setopt=install_weak_deps=False install -y {{ role_packages[os] | join(' ') }}

View File

@@ -1,7 +1,31 @@
---
almalinux:
- bind-utils
- cloud-init
- dbus-daemon
- dhcp-client
- efibootmgr
- glibc-langpack-de
- glibc-langpack-en
- grub2
- grub2-efi
- lrzsz
- lvm2
- nc
- nfs-utils
- nfsv4-client-utils
- open-vm-tools
- ppp
- shim
- telnet
- vim
- wget
- zstd
archlinux:
- base
- btrfs-progs
- cloud-init
- cronie
- dhcpcd
- efibootmgr
@@ -9,6 +33,7 @@ archlinux:
- fish
- grub
- htop
- libpwquality
- linux
- logrotate
- lrzsz
@@ -20,6 +45,7 @@ archlinux:
- nfs-utils
- openssh
- open-vm-tools
- ppp
- prometheus-node-exporter
- python-psycopg2
- qemu-guest-agent
@@ -34,13 +60,12 @@ debian11:
base:
- apparmor-utils
- btrfs-progs
- xfsprogs
- chrony
- cron
- gnupg
- grub-efi
- grub-efi-amd64-signed
- grub2-common
- gnupg
- linux-image-amd64
- locales
- logrotate
@@ -49,98 +74,107 @@ debian11:
- openssh-server
- python3
- sudo
- xfsprogs
extra:
- cloud-init
- curl
- firewalld
- fish
- htop
- network-manager
- screen
- open-vm-tools
- python-is-python3
- libpam-pwquality
- lrzsz
- ncdu
- neofetch
- lrzsz
- libpam-pwquality
- network-manager
- open-vm-tools
- python-is-python3
- rsync
- screen
- software-properties-common
- syslog-ng
- tcpd
- fish
- vim
- wget
- zstd
debian12:
base:
- btrfs-progs
- xfsprogs
- cron
- gnupg
- grub-efi
- grub-efi-amd64-signed
- grub2-common
- gnupg
- linux-image-amd64
- locales
- logrotate
- lvm2
- xfsprogs
extra:
- apparmor-utils
- chrony
- cloud-init
- curl
- firewalld
- fish
- htop
- network-manager
- screen
- open-vm-tools
- python-is-python3
- ncdu
- neofetch
- libpam-pwquality
- logrotate
- lrzsz
- libpam-pwquality
- ncdu
- neofetch
- net-tools
- network-manager
- open-vm-tools
- openssh-server
- python-is-python3
- python3
- rsync
- screen
- software-properties-common
- sudo
- syslog-ng
- tcpd
- net-tools
- openssh-server
- python3
- vim
- wget
- zstd
fedora:
- bind-utils
- btrfs-progs
- cloud-init
- cronie
- dhcp-client
- efibootmgr
- glibc-langpack-de
- glibc-langpack-en
- grub2
- grub2-efi-x64-modules
- grub2-efi
- logrotate
- lrzsz
- lvm2
- nc
- nfs-utils
- nfsv4-client-utils
- open-vm-tools
- polkit
- ppp
- shim
- telnet
- vim-default-editor
- zstd
almalinux:
- dhcp-client
- efibootmgr
- grub2
- grub2-efi-x64-modules
- lrzsz
- nfs-utils
- open-vm-tools
- shims
- telnet
- vim
- wget
- zstd
rhel8:
- cloud-init
- dhcp-client
- efibootmgr
- grub2
- grub2-efi-x64-modules
- grub2-efi
- lrzsz
- lvm2
- nfs-utils
- open-vm-tools
- shim
@@ -148,13 +182,127 @@ rhel8:
- zstd
rhel9:
- cloud-init
- dhcp-client
- efibootmgr
- grub2
- grub2-efi-x64-modules
- grub2-efi
- lrzsz
- lvm2
- nfs-utils
- open-vm-tools
- shim
- telnet
- zstd
rocky:
- bind-utils
- cloud-init
- dbus-daemon
- dhcp-client
- efibootmgr
- glibc-langpack-de
- glibc-langpack-en
- grub2
- grub2-efi
- lrzsz
- lvm2
- nc
- nfs-utils
- nfsv4-client-utils
- open-vm-tools
- ppp
- shim
- telnet
- util-linux-core
- vim
- wget
- zstd
ubuntu:
base:
- btrfs-progs
- cron
- gnupg
- grub-efi
- grub-efi-amd64-signed
- grub2-common
- initramfs-tools
- linux-image-generic
- locales
- lvm2
- xfsprogs
extra:
- apparmor-utils
- bash-completion
- chrony
- cloud-init
- curl
- dnsutils
- firewalld
- fish
- htop
- libpam-pwquality
- logrotate
- lrzsz
- ncdu
- net-tools
- network-manager
- open-vm-tools
- openssh-server
- python-is-python3
- python3
- rsync
- screen
- software-properties-common
- sudo
- syslog-ng
- tcpd
- vim
- wget
- zstd
ubuntu-lts:
base:
- btrfs-progs
- cron
- gnupg
- grub-efi
- grub-efi-amd64-signed
- grub2-common
- initramfs-tools
- linux-image-generic
- locales
- lvm2
- xfsprogs
extra:
- apparmor-utils
- bash-completion
- chrony
- cloud-init
- curl
- dnsutils
- firewalld
- fish
- htop
- libpam-pwquality
- logrotate
- lrzsz
- ncdu
- net-tools
- network-manager
- open-vm-tools
- openssh-server
- python-is-python3
- python3
- rsync
- screen
- software-properties-common
- sudo
- syslog-ng
- tcpd
- vim
- wget
- zstd

View File

@@ -1,8 +1,10 @@
---
- name: Configurationg System for CIS conformity
block:
- name: Disable Kernel Modules
copy:
ansible.builtin.copy:
dest: /mnt/etc/modprobe.d/cis.conf
mode: '0644'
content: |
CIS LVL 3 Restrictions
install freevxfs /bin/true
@@ -19,8 +21,9 @@
install tipc /bin/true
- name: Create USB Rules
copy:
ansible.builtin.copy:
dest: /mnt/etc/udev/rules.d/10-cis_usb_devices.sh
mode: '0644'
content: |
By default, disable all.
ACTION=="add", SUBSYSTEMS=="usb", TEST=="authorized_default", ATTR{authorized_default}="0"
@@ -35,8 +38,9 @@
ACTION=="add", ATTR{product}=="*Thinnet TM*", TEST=="authorized", ATTR{authorized}="1"
- name: Create a consolidated sysctl configuration file
copy:
ansible.builtin.copy:
dest: /mnt/etc/sysctl.d/10-cis.conf
mode: '0644'
content: |
## CIS Sysctl configurations
net.ipv4.conf.all.log_martians = 1
@@ -65,111 +69,118 @@
# - { regexp: '^PASS_MIN_DAYS.*', replace: 'PASS_MIN_DAYS 7' }
# - { regexp: '^UMASK.*', replace: 'UMASK 027' }
- name: Create allow files
file:
- name: Ensure files exist
ansible.builtin.file:
path: "{{ item }}"
state: touch
mode: '0600'
mode: "0600"
loop:
- /mnt/etc/at.allow
- /mnt/etc/cron.allow
- /mnt/etc/hosts.allow
- /mnt/etc/hosts.deny
- name: Add Security related lines into config files
lineinfile:
ansible.builtin.lineinfile:
path: "{{ item.path }}"
line: "{{ item.content }}"
loop:
- { path: '/mnt/etc/security/limits.conf', content: '* hard core 0' }
- { path: '/mnt/etc/security/pwquality.conf', content: 'minlen = 14' }
- { path: '/mnt/etc/security/pwquality.conf', content: 'dcredit = -1' }
- { path: '/mnt/etc/security/pwquality.conf', content: 'ucredit = -1' }
- { path: '/mnt/etc/security/pwquality.conf', content: 'ocredit = -1' }
- { path: '/mnt/etc/security/pwquality.conf', content: 'lcredit = -1' }
- { path: '/mnt/etc/bash.bashrc', content: 'umask 077' }
- { path: '/mnt/etc/bash.bashrc', content: 'export TMOUT=3000' }
- { path: '/mnt/etc/systemd/journald.conf', content: 'Storage=persistent' }
- { path: '/mnt/etc/sudoers', content: 'Defaults logfile="/var/log/sudo.log"' }
- { path: '/mnt/etc/pam.d/su', content: 'auth required pam_wheel.so' }
- { path: '/mnt/etc/pam.d/common-auth', content: 'auth required pam_faillock.so onerr=fail audit silent deny=5 unlock_time=900' }
- { path: '/mnt/etc/pam.d/common-account', content: 'account required pam_faillock.so' }
- { path: '/mnt/etc/pam.d/common-password', content: 'password [success=1 default=ignore] pam_unix.so obscure sha512 remember=5' }
- { path: '/mnt/etc/hosts.deny', content: 'ALL: ALL' }
- { path: '/mnt/etc/hosts.allow', content: 'sshd: ALL' }
- { path: /mnt/etc/security/limits.conf, content: "* hard core 0" }
- { path: /mnt/etc/security/pwquality.conf, content: minlen = 14 }
- { path: /mnt/etc/security/pwquality.conf, content: dcredit = -1 }
- { path: /mnt/etc/security/pwquality.conf, content: ucredit = -1 }
- { path: /mnt/etc/security/pwquality.conf, content: ocredit = -1 }
- { path: /mnt/etc/security/pwquality.conf, content: lcredit = -1 }
- { path: '/mnt/etc/{{ "bashrc" if os in ["almalinux", "fedora", "rocky"] else "bash.bashrc" }}', content: umask 077 }
- { path: '/mnt/etc/{{ "bashrc" if os in ["almalinux", "fedora", "rocky"] else "bash.bashrc" }}', content: export TMOUT=3000 }
- { path: '/mnt/{{ "usr/lib/systemd/journald.conf" if os == "fedora" else "etc/systemd/journald.conf" }}', content: Storage=persistent }
- { path: /mnt/etc/sudoers, content: Defaults logfile="/var/log/sudo.log" }
- { path: /mnt/etc/pam.d/su, content: auth required pam_wheel.so }
- { path: '/mnt/etc/{{ "pam.d/common-auth" if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
else "authselect/system-auth" if os == "fedora" else "pam.d/system-auth" }}',
content: auth required pam_faillock.so onerr=fail audit silent deny=5 unlock_time=900 }
- { path: '/mnt/etc/{{ "pam.d/common-account" if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"] else "authselect/system-auth"
if os == "fedora" else "pam.d/system-auth" }}', content: account required pam_faillock.so }
- { path: '/mnt/etc/pam.d/{{ "common-password" if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"] else "passwd" }}',
content: "password [success=1 default=ignore] pam_unix.so obscure sha512 remember=5" }
- { path: /mnt/etc/hosts.deny, content: "ALL: ALL" }
- { path: /mnt/etc/hosts.allow, content: "sshd: ALL" }
- name: Set permissions for various files and directories
file:
ansible.builtin.file:
path: "{{ item.path }}"
owner: "{{ item.owner | default(omit) }}"
group: "{{ item.group | default(omit) }}"
mode: "{{ item.mode }}"
loop:
- { path: '/mnt/etc/ssh/sshd_config', mode: '0600' }
- { path: '/mnt/etc/cron.hourly', mode: '0700' }
- { path: '/mnt/etc/cron.daily', mode: '0700' }
- { path: '/mnt/etc/cron.weekly', mode: '0700' }
- { path: '/mnt/etc/cron.monthly', mode: '0700' }
- { path: '/mnt/etc/cron.d', mode: '0700' }
- { path: '/mnt/etc/crontab', mode: '0600' }
- { path: '/mnt/etc/logrotate.conf', mode: '0644' }
- { path: '/mnt/usr/sbin/pppd', mode: '754' }
- { path: '/mnt/usr/lib/dbus-1.0/dbus-daemon-launch-helper', mode: '754' }
- { path: '/mnt/usr/libexec/polkit-agent-helper-1', mode: '755' }
- { path: '/mnt/usr/bin/{{ "fusermount" if os == "debian11" else "fusermount3" }}', mode: '755' }
- { path: '/mnt/usr/bin/{{ "write.ul" if os == "debian11" else "write" }}', mode: '755' }
- { path: '/mnt/usr/lib/x86_64-linux-gnu/utempter/utempter', mode: '755' }
- { path: '/mnt/home/svcansible', mode: '750' }
- { path: /mnt/etc/ssh/sshd_config, mode: "0600" }
- { path: /mnt/etc/cron.hourly, mode: "0700" }
- { path: /mnt/etc/cron.daily, mode: "0700" }
- { path: /mnt/etc/cron.weekly, mode: "0700" }
- { path: /mnt/etc/cron.monthly, mode: "0700" }
- { path: /mnt/etc/cron.d, mode: "0700" }
- { path: /mnt/etc/crontab, mode: "0600" }
- { path: /mnt/etc/logrotate.conf, mode: "0644" }
- { path: /mnt/usr/sbin/pppd, mode: "754" }
- { path: '/mnt/usr/bin/{{ "fusermount3" if os in ["archlinux", "debian12", "fedora"] else "fusermount" }}', mode: "755" }
- { path: '/mnt/usr/bin/{{ "write.ul" if os == "debian11" else "write" }}', mode: "755" }
- name: Adjust SSHD config
lineinfile:
ansible.builtin.lineinfile:
path: /mnt/etc/ssh/sshd_config
regexp: '^\s*#?{{ item.option }}\s+.*$'
line: '{{ item.option }} {{ item.value }}'
regexp: ^\s*#?{{ item.option }}\s+.*$
line: "{{ item.option }} {{ item.value }}"
with_items:
- {option: 'LogLevel', value: 'VERBOSE'}
- {option: 'LoginGraceTime', value: '60'}
- {option: 'PermitRootLogin', value: 'no'}
- {option: 'StrictModes', value: 'yes'}
- {option: 'MaxAuthTries', value: '4'}
- {option: 'MaxSessions', value: '10'}
- {option: 'MaxStartups', value: '10:30:60'}
- {option: 'PubkeyAuthentication', value: 'yes'}
- {option: 'HostbasedAuthentication', value: 'no'}
- {option: 'IgnoreRhosts', value: 'yes'}
- {option: 'PasswordAuthentication', value: 'no'}
- {option: 'PermitEmptyPasswords', value: 'no'}
- {option: 'KerberosAuthentication', value: 'no'}
- {option: 'GSSAPIAuthentication', value: 'no'}
- {option: 'GSSAPIKeyExchange', value: 'no'}
- {option: 'AllowAgentForwarding', value: 'no'}
- {option: 'AllowTcpForwarding', value: 'no'}
- {option: 'ChallengeResponseAuthentication', value: 'no'}
- {option: 'GatewayPorts', value: 'no'}
- {option: 'X11Forwarding', value: 'no'}
- {option: 'PermitUserEnvironment', value: 'no'}
- {option: 'ClientAliveInterval', value: '300'}
- {option: 'ClientAliveCountMax', value: '0'}
- {option: 'PermitTunnel', value: 'no'}
- {option: 'Banner', value: '/etc/issue.net'}
- { option: LogLevel, value: VERBOSE }
- { option: LoginGraceTime, value: "60" }
- { option: PermitRootLogin, value: "no" }
- { option: StrictModes, value: "yes" }
- { option: MaxAuthTries, value: "4" }
- { option: MaxSessions, value: "10" }
- { option: MaxStartups, value: 10:30:60 }
- { option: PubkeyAuthentication, value: "yes" }
- { option: HostbasedAuthentication, value: "no" }
- { option: IgnoreRhosts, value: "yes" }
- { option: PasswordAuthentication, value: "no" }
- { option: PermitEmptyPasswords, value: "no" }
- { option: KerberosAuthentication, value: "no" }
- { option: GSSAPIAuthentication, value: "no" }
- { option: GSSAPIKeyExchange, value: "no" }
- { option: AllowAgentForwarding, value: "no" }
- { option: AllowTcpForwarding, value: "no" }
- { option: ChallengeResponseAuthentication, value: "no" }
- { option: GatewayPorts, value: "no" }
- { option: X11Forwarding, value: "no" }
- { option: PermitUserEnvironment, value: "no" }
- { option: ClientAliveInterval, value: "300" }
- { option: ClientAliveCountMax, value: "0" }
- { option: PermitTunnel, value: "no" }
- { option: Banner, value: /etc/issue.net }
- name: Append CIS Specific configurations to sshd_config
lineinfile:
ansible.builtin.lineinfile:
path: /mnt/etc/ssh/sshd_config
line: |
line: |2-
## CIS Specific
Protocol 2
### Ciphers and keying ###
RekeyLimit 512M 6h
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,
diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,
diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,
ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,
aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,
hmac-sha2-512,hmac-sha2-256
###########################
AllowStreamLocalForwarding no
PermitUserRC no
AllowUsers svcansible
AllowUsers *
AllowGroups *
DenyUsers nobody
DenyGroups nobody

View File

@@ -1,3 +1,4 @@
---
- name: Setup Cleanup
when: hypervisor == "proxmox"
delegate_to: localhost
@@ -20,17 +21,17 @@
when: hypervisor == "vmware"
delegate_to: localhost
ignore_errors: true
vmware_guest:
community.vmware.vmware_guest:
hostname: "{{ hypervisor_url }}"
username: "{{ hypervisor_username }}"
password: "{{ hypervisor_password }}"
validate_certs: no
validate_certs: false
datacenter: "{{ hypervisor_cluster }}"
name: "{{ hostname }}"
cdrom:
- controller_number: 0
unit_number: 0
controller_type: "sata"
controller_type: sata
type: iso
iso_path: "{{ boot_iso }}"
state: absent
@@ -46,22 +47,22 @@
state: shutdown
- name: Remove cloud-init disk
file:
ansible.builtin.file:
path: "{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}-cloudinit.iso"
state: absent
- name: Get list of CD-ROM devices
shell: virsh --connect qemu:///system domblklist {{ hostname }} --details | grep 'cdrom' | awk '{print $3}'
ansible.builtin.shell: set -o pipefail && virsh --connect qemu:///system domblklist {{ hostname }} --details | grep 'cdrom' | awk '{print $3}'
changed_when: false
register: cdrom_devices
- name: Wait for VM to spin down
wait_for:
ansible.builtin.wait_for:
timeout: 15
- name: Remove CD-ROM devices
when: cdrom_devices.stdout_lines | length > 0
command: virsh --connect qemu:///system detach-disk {{ hostname }} {{ item }} --persistent
ansible.builtin.command: virsh --connect qemu:///system detach-disk {{ hostname }} {{ item }} --persistent
with_items: "{{ cdrom_devices.stdout_lines }}"
- name: Start the VM
@@ -71,5 +72,5 @@
- name: Wait for VM to boot up
delegate_to: "{{ inventory_hostname }}"
wait_for_connection:
ansible.builtin.wait_for_connection:
timeout: 300

View File

@@ -1,165 +1,192 @@
---
- name: Configuration
block:
- name: Generate fstab
shell: genfstab -LU /mnt > /mnt/etc/fstab
ansible.builtin.shell: genfstab -LU /mnt > /mnt/etc/fstab
- name: Append TempFS to fstab
lineinfile:
ansible.builtin.lineinfile:
path: /mnt/etc/fstab
line: "{{ item }}"
insertafter: EOF
with_items:
- ""
- "# TempFS"
- "tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec 0 0"
- "tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec 0 0"
- "tmpfs /dev/shm tmpfs defaults,noexec 0 0"
- tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec 0 0
- tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec 0 0
- tmpfs /dev/shm tmpfs defaults,noexec 0 0
- name: Set local timezone
command: '{{ item }}'
ansible.builtin.command: "{{ item }}"
with_items:
- systemctl daemon-reload
- arch-chroot /mnt ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
- name: Generate adjtime file
command: arch-chroot /mnt /usr/sbin/hwclock --systohc
- name: Setup locales
block:
- name: Configure locale.gen
lineinfile:
when: os | lower not in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rocky']
ansible.builtin.lineinfile:
dest: /mnt/etc/locale.gen
regexp: '{{ item.regex }}'
line: '{{ item.line }}'
regexp: "{{ item.regex }}"
line: "{{ item.line }}"
loop:
- { regex: en_US\.UTF-8 UTF-8, line: en_US.UTF-8 UTF-8 }
- name: Generate locales
command: arch-chroot /mnt /usr/sbin/locale-gen
- name: Generate locales\
when: os | lower not in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rocky']
ansible.builtin.command: arch-chroot /mnt /usr/sbin/locale-gen
- name: Set hostname
copy:
ansible.builtin.copy:
content: "{{ hostname }}"
dest: /mnt/etc/hostname
mode: '0644'
- name: Add host entry to /etc/hosts
lineinfile:
ansible.builtin.lineinfile:
path: /mnt/etc/hosts
line: "{{ ansible_host }} {{ hostname }}"
state: present
- name: Create vconsole.conf
copy:
content: "KEYMAP=de-latin1-nodeadkeys"
ansible.builtin.copy:
content: KEYMAP=us
dest: /mnt/etc/vconsole.conf
mode: '0644'
- name: Create locale.conf
copy:
content: "LANG=en_US.UTF-8"
ansible.builtin.copy:
content: LANG=en_US.UTF-8
dest: /mnt/etc/locale.conf
mode: '0644'
- name: SSH permit Password
replace:
ansible.builtin.replace:
path: /mnt/etc/ssh/sshd_config
regexp: '#PasswordAuthentication yes'
replace: 'PasswordAuthentication yes'
regexp: "#PasswordAuthentication yes"
replace: PasswordAuthentication yes
- name: Enable Systemd Services
block:
- name: Enable sshd
when: os | lower == "archlinux"
command: arch-chroot /mnt systemctl enable sshd NetworkManager logrotate
ansible.builtin.command: arch-chroot /mnt systemctl enable sshd logrotate systemd-resolved systemd-timesyncd NetworkManager
- name: Configure grub
when: os | lower != "fedora" and os | lower != "almalinux" and os | lower != "rhel8" and os | lower != "rhel9"
when: os | lower not in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rocky']
block:
- name: Add commandline information to grub config
lineinfile:
ansible.builtin.lineinfile:
dest: /mnt/etc/default/grub
regexp: ^GRUB_CMDLINE_LINUX_DEFAULT=
line: 'GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3"'
line: GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3"
- name: Change Grub time
lineinfile:
ansible.builtin.lineinfile:
dest: /mnt/etc/default/grub
regexp: ^GRUB_TIMEOUT=
line: 'GRUB_TIMEOUT=0'
line: GRUB_TIMEOUT=1
- name: Configure Bootloader
block:
- name: Install Bootloader
command: arch-chroot /mnt {% if os | lower != "archlinux" and os | lower != "debian11" and os | lower != "debian12" %}/usr/sbin/efibootmgr -c -L '{{ os }}' -d "{{ install_drive }}" -wwp 1 -l '\efi\EFI\{{ os }}\shimx64.efi'{% else %}/usr/sbin/grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id={{ os }}{% endif %}
ansible.builtin.command: arch-chroot /mnt
{% if os | lower not in ["archlinux", "debian11", "debian12", "ubuntu", "ubuntu-lts"] %} /usr/sbin/efibootmgr
-c -L '{{ os }}' -d "{{ install_drive }}" -p 1 -l '\efi\EFI\{{ os }}\shimx64.efi'
{% else %}/usr/sbin/grub-install --target=x86_64-efi --efi-directory={{ "/boot/efi" if os | lower in ["ubuntu", "ubuntu-lts"] else "/boot" }}
--bootloader-id={{ "ubuntu" if os | lower in ["ubuntu", "ubuntu-lts"] else os }}
{% endif %}
- name: Generate grub config
command: arch-chroot /mnt {% if os | lower != "archlinux" and os | lower != "debian11" and os | lower != "debian12" %}/usr/sbin/grub2-mkconfig -o /boot/efi/EFI/{{ os }}/grub.cfg{% else %}/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg{% endif %}
ansible.builtin.command: arch-chroot /mnt
{% if os | lower not in ["archlinux", "debian11", "debian12", "ubuntu", "ubuntu-lts"] %} /usr/sbin/grub2-mkconfig
-o /boot/efi/EFI/{{ os }}/grub.cfg
{% else %}/usr/sbin/grub-mkconfig -o
{{ "/boot/efi/EFI/ubuntu/grub.cfg" if os | lower in ["ubuntu", "ubuntu-lts"] else "/boot/grub/grub.cfg" }}
{% endif %}
- name: Regenerate initramfs
when: os | lower not in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
ansible.builtin.command: arch-chroot /mnt
{% if os | lower == "archlinux" %} /usr/sbin/mkinitcpio -P
{% elif os | lower not in ["debian11", "debian12", "ubuntu", "ubuntu-lts", "archlinux"] %} /usr/bin/dracut --regenerate-all --force
{% else %} echo "Skipping initramfs regeneration"
{% endif %}
- name: Extra Configuration
when: os | lower != "archlinux"
block:
- name: Append lines to vimrc
lineinfile:
path: "{{ '/mnt/etc/vim/vimrc' if os|lower == 'debian11' or os|lower == 'debian12' else '/mnt/etc/vimrc' }}"
ignore_errors: true
ansible.builtin.lineinfile:
path: "{{ '/mnt/etc/vim/vimrc' if os | lower in ['debian11', 'debian12', 'ubuntu', 'ubuntu-lts'] else '/mnt/etc/vimrc' }}"
line: "{{ item }}"
insertafter: EOF
with_items:
- "set encoding=utf-8"
- "set number"
- "set autoindent"
- "set smartindent"
- "set mouse=a"
- set encoding=utf-8
- set number
- set autoindent
- set smartindent
- set mouse=a
- name: Copy FirstRun Script
template:
when: os | lower != "archlinux"
ansible.builtin.template:
src: firstrun.sh.j2
dest: /mnt/root/firstrun.sh
mode: '0755'
mode: "0755"
- name: Copy Custom Shell config
template:
ansible.builtin.template:
src: custom.sh.j2
dest: /mnt/etc/profile.d/custom.sh
mode: '0644'
- name: Setup Network
block:
- name: Generate UUID for Network Profile
command: "uuidgen"
ansible.builtin.command: uuidgen
register: net_uuid
- name: Retrieve Network Interface Name
shell: "ip r | awk 'NR==1 {print $5}'"
ansible.builtin.shell: set -o pipefail && ip r | awk 'NR==1 {print $5}'
register: net_inf
- name: Copy NetworkManager keyfile
template:
ansible.builtin.template:
src: network.j2
dest: /mnt/etc/NetworkManager/system-connections/LAN.nmconnection
mode: '0600'
mode: "0600"
- name: Setup user account
block:
- name: Create user account
command: '{{ item }}'
ansible.builtin.command: "{{ item }}"
with_items:
- arch-chroot /mnt /usr/sbin/useradd --create-home --user-group --groups {{ "sudo" if os|lower == "debian11" or os|lower == "debian12" else "wheel" }} {{ user_name }} --password {{ user_password | password_hash('sha512') }} --shell /bin/bash
- arch-chroot /mnt /usr/sbin/useradd --create-home --user-group --groups
{{ "sudo" if os | lower in ["debian11", "debian12", "ubuntu", "ubuntu-lts"] else "wheel" }}
{{ user_name }} --password {{ user_password | password_hash('sha512') }} --shell /bin/bash
- arch-chroot /mnt /usr/sbin/usermod --password '{{ root_password | password_hash('sha512') }}' root --shell /bin/bash
- name: Add SSH public key to authorized_keys
when: user_public_key is defined
lineinfile:
path: "/mnt/home/{{ user_name }}/.ssh/authorized_keys"
ansible.builtin.lineinfile:
path: /mnt/home/{{ user_name }}/.ssh/authorized_keys
line: "{{ user_public_key }}"
owner: 1000
group: 1000
mode: "0600"
create: yes
create: true
- name: Give sudo access to wheel group
copy:
content: "{{ '%sudo ALL=(ALL) ALL' if os|lower == 'debian11' or os|lower == 'debian12' else '%wheel ALL=(ALL) ALL' }}"
ansible.builtin.copy:
content: "{{ '%sudo ALL=(ALL) ALL' if os | lower in ['debian11', 'debian12', 'ubuntu', 'ubuntu-lts'] else '%wheel ALL=(ALL) ALL' }}"
dest: /mnt/etc/sudoers.d/01-wheel
mode: 0440
mode: "0440"
validate: /usr/sbin/visudo --check --file=%s
- name: Fix SELinux
when: (os | lower == "almalinux" or os | lower == "fedora" or os | lower == "rhel8" or os | lower == "rhel9")
command: touch /mnt/.autorelabel
block:
- name: Relabel the filesystem
when: os | lower in ['almalinux', 'rhel8', 'rhel9', 'rocky']
ansible.builtin.command: touch /mnt/.autorelabel
- name: Disable SELinux
when: os | lower == "fedora"
ansible.builtin.lineinfile:
path: /mnt/etc/selinux/config
regexp: ^SELINUX=
line: SELINUX=permissive

View File

@@ -1,74 +1,75 @@
---
- name: Configre work environment
become: true
block:
- name: Wait for connection
wait_for_connection:
ansible.builtin.wait_for_connection:
timeout: 300
delay: 5
- name: Gather facts
setup:
ansible.builtin.setup:
- name: Check if host is booted from the Arch install media
stat:
ansible.builtin.stat:
path: /run/archiso
register: archiso_stat
- name: Abort if the host is not booted from the Arch install media
fail:
msg: "This host is not booted from the Arch install media!"
ansible.builtin.fail:
msg: This host is not booted from the Arch install media!
when: not archiso_stat.stat.exists
- name: Setect Interface
when: hypervisor == "vmware"
shell: "ip l | awk -F': ' '!/lo/{print $2; exit}'"
ansible.builtin.shell: "set -o pipefail && ip l | awk -F': ' '!/lo/{print $2; exit}'"
register: interface_name
- name: Set IP-Address
when: hypervisor == "vmware"
command: ip addr replace {{ ansible_host }}/24 dev {{ interface_name.stdout }}
ansible.builtin.command: ip addr replace {{ ansible_host }}/24 dev {{ interface_name.stdout }}
- name: Set Default Gateway
when: hypervisor == "vmware"
command: ip route replace default via {{ vm_gw }}
ansible.builtin.command: ip route replace default via {{ vm_gw }}
- name: Synchronize clock via NTP
command: timedatectl set-ntp true
ansible.builtin.command: timedatectl set-ntp true
- name: Speed-up Bootstrap process
lineinfile:
ansible.builtin.lineinfile:
path: /etc/pacman.conf
regexp: '^#ParallelDownloads ='
line: 'ParallelDownloads = 20'
regexp: ^#ParallelDownloads =
line: ParallelDownloads = 20
- name: Wait for Pacman
wait_for:
ansible.builtin.wait_for:
timeout: 15
- name: Setup Pacman
pacman:
community.general.pacman:
update_cache: true
force: true
name: "{{ item.name }}"
state: latest
loop:
- { name: 'glibc' }
- { name: 'dnf', os: ['almalinux', 'rhel9', 'rhel8'] }
- { name: 'debootstrap', os: ['debian11', 'debian12'] }
- { name: 'debian-archive-keyring', os: ['debian11', 'debian12'] }
- { name: glibc }
- { name: dnf, os: [almalinux, fedora, rhel9, rhel8, rocky] }
- { name: debootstrap, os: [debian11, debian12, ubuntu, ubuntu-lts] }
- { name: debian-archive-keyring, os: [debian11, debian12] }
- { name: ubuntu-keyring, os: [ubuntu, ubuntu-lts] }
when: "'os' not in item or os in item.os"
retries: 4
delay: 15
- name: Configure RHEL Repos for installation
when: os | lower == "almalinux" or os | lower == "fedora"
when: os | lower in ["almalinux", "fedora", "rocky"]
block:
- name: Create directories for repository files and RPM GPG keys
file:
ansible.builtin.file:
path: /etc/yum.repos.d
state: directory
mode: '0755'
- name: Create RHEL repository file
template:
src: '{{ os | lower }}.repo.j2'
dest: '/etc/yum.repos.d/{{ os | lower }}.repo'
ansible.builtin.template:
src: "{{ os | lower }}.repo.j2"
dest: /etc/yum.repos.d/{{ os | lower }}.repo
mode: '0644'

View File

@@ -2,25 +2,25 @@
- name: Setup BTRFS
block:
- name: Create btrfs filesystem in main volume
filesystem:
dev: '{{ install_drive }}{{ main_partition_suffix }}'
community.general.filesystem:
dev: "{{ install_drive }}{{ main_partition_suffix }}"
fstype: btrfs
force: yes
force: true
- name: Prepare BTRFS Subvolume
mount:
ansible.posix.mount:
path: /mnt
src: '{{ install_drive }}{{ main_partition_suffix }}'
src: "{{ install_drive }}{{ main_partition_suffix }}"
fstype: btrfs
opts: rw,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async
state: mounted
- name: Enable quotas on Btrfs filesystem
command: btrfs quota enable /mnt
ansible.builtin.command: btrfs quota enable /mnt
- name: Make root subvolumes
when: cis == true or item.subvol not in ['var_log', 'var_log_audit']
command: btrfs su cr /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
when: cis | bool or item.subvol not in ['var_log', 'var_log_audit']
ansible.builtin.command: btrfs su cr /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
loop:
- { subvol: root }
- { subvol: home }
@@ -29,18 +29,14 @@
- { subvol: var_log_audit }
- name: Set quotas for subvolumes
when: cis == true or item.subvol not in ['var_log', 'var_log_audit']
command: btrfs qgroup limit {{ item.quota }} /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
when: cis | bool or item.subvol not in ['var_log', 'var_log_audit']
ansible.builtin.command: btrfs qgroup limit {{ item.quota }} /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
loop:
- { subvol: root, quota: '12G' }
- { subvol: home, quota: '2G' }
- { subvol: var, quota: '2G' }
- { subvol: var_log, quota: '2G' }
- { subvol: var_log_audit, quota: '1536M' }
- { subvol: home, quota: 2G }
- name: Unmount Partition
mount:
ansible.posix.mount:
path: /mnt
src: '{{ install_drive }}{{ main_partition_suffix }}'
src: "{{ install_drive }}{{ main_partition_suffix }}"
fstype: btrfs
state: unmounted

View File

@@ -1,10 +1,10 @@
---
- name: Create and format ext4 logical volumes
when: cis == true or item.lv not in ['var_log', 'var_log_audit']
filesystem:
dev: '/dev/sys/{{ item.lv }}'
when: cis | bool or item.lv not in ['var_log', 'var_log_audit']
community.general.filesystem:
dev: /dev/sys/{{ item.lv }}
fstype: ext4
force: yes
force: true
loop:
- { lv: root }
- { lv: home }
@@ -13,8 +13,8 @@
- { lv: var_log_audit }
- name: Remove Unsupported features for older Systems
when: (os | lower == 'debian11') and (cis == true or item.lv not in ['var_log', 'var_log_audit'])
command: tune2fs -O "^orphan_file,^metadata_csum_seed" "/dev/sys/{{ item.lv }}"
when: (os | lower in ['almalinux', 'debian11', 'rhel8', 'rhel9', 'rocky', 'ubuntu-lts']) and (cis | bool or item.lv not in ['var_log', 'var_log_audit'])
ansible.builtin.command: tune2fs -O "^orphan_file,^metadata_csum_seed" "/dev/sys/{{ item.lv }}"
loop:
- { lv: root }
- { lv: home }

View File

@@ -3,16 +3,16 @@
block:
- name: Prepare partitions
ignore_errors: true
command: "{{ item.cmd }}"
ansible.builtin.command: "{{ item.cmd }}"
loop:
- { cmd: "umount -l /mnt" }
- { cmd: "vgremove -f sys" }
- { cmd: "find /dev -wholename \"{{ install_drive }}*\" -exec wipefs --force --all {} \\;" }
- { cmd: umount -l /mnt }
- { cmd: vgremove -f sys }
- { cmd: 'find /dev -wholename "{{ install_drive }}*" -exec wipefs --force --all {} \;' }
loop_control:
label: "{{ item.cmd }}"
- name: Define partitions
parted:
community.general.parted:
device: "{{ install_drive }}"
label: gpt
number: "{{ item.number }}"
@@ -22,56 +22,56 @@
flags: "{{ item.flags | default(omit) }}"
state: present
loop:
- { number: 1, part_end: '500MiB', name: 'boot', flags: ['boot', 'esp'] }
- { number: 2, part_start: '500MiB', name: 'root' }
- { number: 1, part_end: 500MiB, name: boot, flags: [boot, esp] }
- { number: 2, part_start: 500MiB, name: root }
- name: Create LVM logical volumes
when: filesystem != 'btrfs'
block:
- name: Create LVM volume group
lvg:
community.general.lvg:
vg: sys
pvs: '{{ install_drive }}{{ main_partition_suffix }}'
pvs: "{{ install_drive }}{{ main_partition_suffix }}"
- name: Create LVM logical volumes
when: cis or (not cis and item.lv != 'var_log' and item.lv != 'var_log_audit')
lvol:
community.general.lvol:
vg: sys
lv: "{{ item.lv }}"
size: "{{ item.size }}"
state: present
loop:
- { lv: 'root', size: '12G' }
- { lv: 'home', size: '2G' }
- { lv: 'var', size: '2G' }
- { lv: 'var_log', size: '2G' }
- { lv: 'var_log_audit', size: '1.5G' }
- { lv: root, size: 12G }
- { lv: home, size: 2G }
- { lv: var, size: 2G }
- { lv: var_log, size: 2G }
- { lv: var_log_audit, size: 1.5G }
- name: Create filesystems
block:
- name: Create FAT32 filesystem in boot partition
filesystem:
dev: '{{ install_drive }}{{ boot_partition_suffix }}'
community.general.filesystem:
dev: "{{ install_drive }}{{ boot_partition_suffix }}"
fstype: vfat
opts: -F32
force: yes
force: true
- name: Create filesystem
include_tasks: "{{ filesystem }}.yml"
ansible.builtin.include_tasks: "{{ filesystem }}.yml"
- name: Get UUID for boot filesystem
command: blkid -s UUID -o value '{{ install_drive }}{{ boot_partition_suffix }}'
ansible.builtin.command: blkid -s UUID -o value '{{ install_drive }}{{ boot_partition_suffix }}'
changed_when: false
register: boot_uuid
- name: Get UUID for main filesystem
command: blkid -s UUID -o value '{{ install_drive }}{{ main_partition_suffix }}'
ansible.builtin.command: blkid -s UUID -o value '{{ install_drive }}{{ main_partition_suffix }}'
changed_when: false
register: main_uuid
- name: Get UUIDs for LVM filesystems
when: filesystem != 'btrfs' and (cis == true or item not in ['var_log', 'var_log_audit'])
command: blkid -s UUID -o value /dev/sys/{{ item }}
when: filesystem != 'btrfs' and (cis | bool or item not in ['var_log', 'var_log_audit'])
ansible.builtin.command: blkid -s UUID -o value /dev/sys/{{ item }}
changed_when: false
register: uuid_result
loop:
@@ -81,7 +81,8 @@
- var_log
- var_log_audit
- set_fact:
- name: Assign UUIDs to Variables
ansible.builtin.set_fact:
uuid_root: "{{ uuid_result.results[0].stdout_lines }}"
uuid_home: "{{ uuid_result.results[1].stdout_lines }}"
uuid_var: "{{ uuid_result.results[2].stdout_lines }}"
@@ -92,34 +93,48 @@
- name: Mount filesystems
block:
- name: Mount filesystems and subvolumes
when: "cis or (not cis and item.path != '/var/log' and item.path != '/var/log/audit')"
mount:
path: "/mnt{{ item.path }}"
when: cis | bool or (not cis and item.path != '/var/log' and item.path != '/var/log/audit')
ansible.posix.mount:
path: /mnt{{ item.path }}
src: "{{ 'UUID=' + (main_uuid.stdout if filesystem == 'btrfs' else item.uuid) }}"
fstype: "{{ filesystem }}"
opts: "{{ item.opts }}"
state: mounted
loop:
- { path: '', uuid: "{{ uuid_root[0] | default(omit) }}", opts: "{{ 'defaults' if filesystem != 'btrfs' else 'rw,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@' }}" }
- { path: '/home', uuid: "{{ uuid_home[0] | default(omit) }}", opts: "{{ 'defaults,nosuid,nodev' if filesystem != 'btrfs' else 'rw,nosuid,nodev,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@home' }}" }
- { path: '/var', uuid: "{{ uuid_var[0] | default(omit) }}", opts: "{{ 'defaults,nosuid,nodev' if filesystem != 'btrfs' else 'rw,nosuid,nodev,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@var' }}" }
- { path: '/var/log', uuid: "{{ uuid_var_log[0] | default(omit) }}", opts: "{{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs' else 'rw,nosuid,nodev,noexec,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@var_log' }}" }
- { path: '/var/log/audit', uuid: "{{ uuid_var_log_audit[0] | default(omit) }}", opts: "{{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs' else 'rw,nosuid,nodev,noexec,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@var_log_audit' }}" }
- path: ""
uuid: "{{ uuid_root[0] | default(omit) }}"
opts: "{{ 'defaults' if filesystem != 'btrfs' else 'rw,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@' }}"
- path: /home
uuid: "{{ uuid_home[0] | default(omit) }}"
opts: "{{ 'defaults,nosuid,nodev' if filesystem != 'btrfs'
else 'rw,nosuid,nodev,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@home' }}"
- path: /var
uuid: "{{ uuid_var[0] | default(omit) }}"
opts: "{{ 'defaults,nosuid,nodev' if filesystem != 'btrfs'
else 'rw,nosuid,nodev,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@var' }}"
- path: /var/log
uuid: "{{ uuid_var_log[0] | default(omit) }}"
opts: "{{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs'
else 'rw,nosuid,nodev,noexec,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@var_log' }}"
- path: /var/log/audit
uuid: "{{ uuid_var_log_audit[0] | default(omit) }}"
opts: "{{ 'defaults,nosuid,nodev,noexec' if filesystem != 'btrfs'
else 'rw,nosuid,nodev,noexec,relatime,compress=zstd:15,ssd,space_cache=v2,discard=async,subvol=@var_log_audit' }}"
- name: Mount tmp and var_tmp filesystems
mount:
path: "/mnt{{ item.path }}"
ansible.posix.mount:
path: /mnt{{ item.path }}
src: tmpfs
fstype: tmpfs
opts: defaults,nosuid,nodev,noexec
state: mounted
loop:
- { path: '/tmp' }
- { path: '/var/tmp' }
- { path: /tmp }
- { path: /var/tmp }
- name: Mount boot filesystem
mount:
path: /mnt/boot
ansible.posix.mount:
path: "{{ '/mnt/boot/efi' if os | lower in ['ubuntu', 'ubuntu-lts'] else '/mnt/boot' }}"
src: UUID={{ boot_uuid.stdout }}
fstype: vfat
state: mounted

View File

@@ -1,10 +1,10 @@
---
- name: Create and format XFS logical volumes
when: cis == true or item.lv not in ['var_log', 'var_log_audit']
filesystem:
dev: '/dev/sys/{{ item.lv }}'
when: cis | bool or item.lv not in ['var_log', 'var_log_audit']
community.general.filesystem:
dev: /dev/sys/{{ item.lv }}
fstype: xfs
force: yes
force: true
loop:
- { lv: root }
- { lv: home }

View File

@@ -1,32 +1,37 @@
---
- name: Check if VM disk exists
delegate_to: localhost
stat:
ansible.builtin.stat:
path: "{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2"
register: vm_disk_stat
- name: Create VM disk
when: not vm_disk_stat.stat.exists
delegate_to: localhost
command: "qemu-img create -f qcow2 {{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2 {{ vm_size }}G"
ansible.builtin.command: qemu-img create -f qcow2 {{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}.qcow2 {{ vm_size }}G
- name: Generate Random MAC Address
delegate_to: localhost
shell: openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | sed 's/^/02:/'
ansible.builtin.shell: set -o pipefail && openssl rand -hex 5 | sed 's/\(..\)/\1:/g; s/.$//' | sed 's/^/02:/'
changed_when: false
register: mac_address_output
- name: Render cloud config templates
delegate_to: localhost
template:
ansible.builtin.template:
src: "{{ item.src }}"
dest: "/tmp/{{ item.dest_prefix }}-{{ hostname }}.yml"
dest: /tmp/{{ item.dest_prefix }}-{{ hostname }}.yml
mode: '0644'
loop:
- { src: "cloud-user-data.yml.j2", dest_prefix: "cloud-user-data" }
- { src: "cloud-network-config.yml.j2", dest_prefix: "cloud-network-config" }
- { src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data }
- { src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config }
- name: Create cloud-init disk
delegate_to: localhost
command: "cloud-localds {{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}-cloudinit.iso /tmp/cloud-user-data-{{ hostname }}.yml -N /tmp/cloud-network-config-{{ hostname }}.yml"
ansible.builtin.command: cloud-localds
{{ vm_path | default('/var/lib/libvirt/images/') }}
{{ hostname }}-cloudinit.iso /tmp/cloud-user-data-{{ hostname }}.yml
-N /tmp/cloud-network-config-{{ hostname }}.yml
- name: Create VM using libvirt
delegate_to: localhost
@@ -34,7 +39,7 @@
command: define
xml: "{{ lookup('template', 'vm.xml.j2') }}"
- name: start vm
- name: Start vm
delegate_to: localhost
community.libvirt.virt:
name: "{{ hostname }}"

View File

@@ -1,2 +1,3 @@
---
- name: Create Virtual Machine
include_tasks: "{{ hypervisor }}.yml"
ansible.builtin.include_tasks: "{{ hypervisor }}.yml"

View File

@@ -1,6 +1,7 @@
---
- name: Deploy VM on Proxmox
delegate_to: localhost
proxmox_kvm:
community.general.proxmox_kvm:
api_host: "{{ hypervisor_url }}"
api_user: "{{ hypervisor_username }}"
api_password: "{{ hypervisor_password }}"
@@ -9,36 +10,36 @@
node: "{{ hypervisor_node }}" # Proxmox node name
vmid: "{{ vm_id }}" # Unique ID for the VM
name: "{{ hostname }}" # Name of the VM
cpu: "host"
cpu: host
cores: "{{ vm_cpus }}" # Number of CPU cores
memory: "{{ vm_memory }}" # Memory size in MB
balloon: "{{ vm_ballo | default(omit) }}" # Minimum Memory size in MB
numa_enabled: true
hotplug: "network,disk"
hotplug: network,disk
bios: ovmf
boot: "ac"
scsihw: "virtio-scsi-single"
boot: ac
scsihw: virtio-scsi-single
scsi:
scsi0: "{{ hypervisor_storage }}:{{ vm_size }}" # Disk configuration
efidisk0:
efitype: "4m"
format: "raw"
efitype: 4m
format: raw
pre_enrolled_keys: false
storage: "{{ hypervisor_storage }}"
ide:
ide0: "{{ boot_iso }},media=cdrom"
ide1: "{{ hypervisor_storage }}:cloudinit"
net:
net0: "virtio,bridge={{ vm_nif }}{% if vlan_name is defined and vlan_name %},tag={{ vlan_name }}{% endif %}"
net0: virtio,bridge={{ vm_nif }}{% if vlan_name is defined and vlan_name %},tag={{ vlan_name }}{% endif %}
ipconfig:
ipconfig0: "ip={{ vm_ip }},gw={{ vm_gw }}"
ipconfig0: ip={{ vm_ip }},gw={{ vm_gw }}
nameservers: "{{ vm_dns }}"
onboot: true # Start the VM on boot
state: present # Ensure the VM is present
- name: Start VM on Proxmox
delegate_to: localhost
proxmox_kvm:
community.general.proxmox_kvm:
api_host: "{{ hypervisor_url }}"
api_user: "{{ hypervisor_username }}"
api_password: "{{ hypervisor_password }}"

View File

@@ -1,15 +1,16 @@
---
- name: Create VM in vCenter
delegate_to: localhost
vmware_guest:
community.vmware.vmware_guest:
hostname: "{{ hypervisor_url }}"
username: "{{ hypervisor_username }}"
password: "{{ hypervisor_password }}"
validate_certs: no
validate_certs: false
datacenter: "{{ hypervisor_cluster }}"
cluster: "{{ hypervisor_node }}"
folder: "{{ vm_path }}"
name: "{{ hostname }}"
guest_id: "otherGuest64"
guest_id: otherGuest64
state: poweredon
disk:
- size_gb: "{{ vm_size }}"
@@ -18,16 +19,21 @@
hardware:
memory_mb: "{{ vm_memory }}"
num_cpus: "{{ vm_cpus }}"
boot_firmware: "efi"
boot_firmware: efi
secure_boot: false
cdrom:
- controller_number: 0
unit_number: 0
controller_type: "sata"
controller_type: sata
state: present
type: iso
iso_path: "{{ boot_iso }}"
networks:
- vlan: "{{ vlan_name }}"
type: dhcp
ignore_errors: yes
register: vmware_guest_result
failed_when:
- vmware_guest_result.failed
- "'error' in vmware_guest_result"
- "'failed' in vmware_guest_result"
- vmware_guest_result.rc is defined and vmware_guest_result.rc != 0

10
templates/rocky.repo.j2 Normal file
View File

@@ -0,0 +1,10 @@
[rocky-baseos]
name=Rocky Linux $releasever - BaseOS
mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever
#baseurl=http://dl.rockylinux.org/$contentdir/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
countme=1
gpgkey=https://dl.rockylinux.org/pub/rocky/RPM-GPG-KEY-Rocky-$releasever
metadata_expire=86400
enabled_metadata=1

View File

@@ -4,9 +4,6 @@ ansible_become_password: "{{ user_password }}"
ansible_ssh_extra_args: '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
vm_ip: "{{ inventory_hostname }}/24"
hypervisor_list: ["libvirt", "proxmox", "vmware", "none"]
filesystem_list: ["btrfs", "ext4", "xfs"]
os_list: ["archlinux", "almalinux", "debian11", "debian12", "fedora"]
install_type: "virtual"
cis: false