aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspmfox <spmfox@foxwd.com>2023-06-10 22:50:30 -0400
committerspmfox <spmfox@foxwd.com>2023-06-10 22:50:30 -0400
commit843ad6659cc0bd6b8baaf2033e680d32a0531b2d (patch)
tree1f421307396ce3805a07b33a2cb6d82ee0fbc300
parenta93e04656b8dc9bfbce998d0ec2ca299f4120629 (diff)
adding tags, adding guest configuration
-rw-r--r--README.md13
-rw-r--r--docs/sample-environment.yml9
-rw-r--r--roles/guest-configure/tasks/main.yml17
-rw-r--r--roles/guest-configure/tasks/packages.yml5
-rw-r--r--roles/guest-configure/tasks/services.yml6
-rw-r--r--roles/guest-configure/tasks/update.yml4
-rw-r--r--roles/guest-configure/tasks/user.yml52
-rw-r--r--roles/guest-configure/vars/main.yml6
-rw-r--r--roles/libvirt/vars/main.yml8
-rw-r--r--roles/zfs/vars/main.yml2
-rw-r--r--vm-create.yml48
-rw-r--r--vm-delete.yml30
12 files changed, 179 insertions, 21 deletions
diff --git a/README.md b/README.md
index baa7577..be4abaa 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,12 @@ all:
parent_dataset: "zfs-parent-dataset/zfs-child-dataset"
network: "bridge:vm-bridge"
root_password: "{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}"
- root_ssh_key: ""
+ user: "admin"
+ ssh_key: ""
+ packages:
+ - qemu-guest-agent
+ services:
+ - qemu-guest-agent
```
An example with multiple VMs is located in the ```docs``` directory.
@@ -48,6 +53,12 @@ An example with multiple VMs is located in the ```docs``` directory.
- Kickstart files and compatible distros are required
- The delete play will completely remove any VMs or datasets defined in your inventory
+## Known Issues
+- Currently cannot delete VMs with libvirt snapshots
+ - community.libvirt.virt module has upstream code to do this, but it has not been released yet
+ - Workaround is to manually delete snapshots from VM before deletion
+ - Does NOT apply to ZFS snapshots
+
## Architecture
The KVM and ZFS tasks are split into different roles, ```libvirt``` and ```zfs```. These roles contain all the needed tasks and variables for each feature.
Variables for libvirt tasks start with ```libvirt_``` and zfs ones start with ```zfs_```. These are the "real" variables that are used in the tasks,
diff --git a/docs/sample-environment.yml b/docs/sample-environment.yml
index 959f2f5..b04c051 100644
--- a/docs/sample-environment.yml
+++ b/docs/sample-environment.yml
@@ -26,5 +26,12 @@ all:
parent_dataset: "zfs-parent-dataset/zfs-child-dataset"
network: "bridge:vm-bridge"
root_password: "{{ lookup('password', '/dev/null length=32 chars=ascii_letters,digits') }}" #Random root password
- root_ssh_key: |
+ user: "admin" #Regular user with sudo rights
+ # SSH key for root and regular user
+ ssh_key: |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDFyY+3A07lMnHkyQ6bMez/BEi9j2vh4sotxQdqEMlCS+EJCta8G/CCj54kBvFKrrkiPMs0Jj1Od02ZjWZqGf+W/stZ+KLh97M0EM/69zbRbQJZ7xuCQKng7U87bbopbXcx9Mu9DUCC1pjNJ5Bb7nG6z51hk7mh3mF8QGHJ6qp03FrK+Eiud/2d9Zbn4lNH/E5W7iZ3J7zZHU16nLQH1Tsbx2LFUDkVhz/A4/7sqRmWT/mpwSCVgxN9cFgs1KMHsqb4Z1XXtbb//SWj+bmPvcfbfDUkTnb8Z+KTOd1OViKjDH1owgymxZtDML5S7OOZ2AX0/c5JaDplLRhji7gpVTRLZJE5XHvfVqwJCkxVrxoc4sbcZb9I/G+clJ3CBzSMZXh7p85J4OLVP5GmfOh0o93pakWVsTZBrPgO3EjhOyj0pGay3qUHiQfPqIlU+q92Mku5iijsbFDv28HdUlz5e69igg7E8Hr2/SruZuDijxOqkkHkmW0pnM8kXQpvU5dvW0U= pubkey@box
+ packages: # Packages to install on guest
+ - qemu-guest-agent
+ services: # Services to enable on guest
+ - qemu-guest-agent
+
diff --git a/roles/guest-configure/tasks/main.yml b/roles/guest-configure/tasks/main.yml
new file mode 100644
index 0000000..4e4b429
--- /dev/null
+++ b/roles/guest-configure/tasks/main.yml
@@ -0,0 +1,17 @@
+- name: Wait for guest connectivity
+ ansible.builtin.wait_for_connection:
+
+- name: Gather facts
+ ansible.builtin.setup:
+
+- name: Import user creation task
+ ansible.builtin.import_tasks: user.yml
+
+- name: Import update task
+ ansible.builtin.import_tasks: update.yml
+
+- name: Import packages task
+ ansible.builtin.import_tasks: packages.yml
+
+- name: Import services task
+ ansible.builtin.import_tasks: services.yml
diff --git a/roles/guest-configure/tasks/packages.yml b/roles/guest-configure/tasks/packages.yml
new file mode 100644
index 0000000..cffd690
--- /dev/null
+++ b/roles/guest-configure/tasks/packages.yml
@@ -0,0 +1,5 @@
+- name: Install packages
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: present
+ loop: "{{ guest_configure_packages }}"
diff --git a/roles/guest-configure/tasks/services.yml b/roles/guest-configure/tasks/services.yml
new file mode 100644
index 0000000..56a5626
--- /dev/null
+++ b/roles/guest-configure/tasks/services.yml
@@ -0,0 +1,6 @@
+- name: Enable and start services
+ ansible.builtin.service:
+ name: "{{ item }}"
+ enabled: yes
+ state: started
+ loop: "{{ guest_configure_services }}"
diff --git a/roles/guest-configure/tasks/update.yml b/roles/guest-configure/tasks/update.yml
new file mode 100644
index 0000000..f74b190
--- /dev/null
+++ b/roles/guest-configure/tasks/update.yml
@@ -0,0 +1,4 @@
+- name: Update all packages
+ ansible.builtin.package:
+ name: "*"
+ state: latest
diff --git a/roles/guest-configure/tasks/user.yml b/roles/guest-configure/tasks/user.yml
new file mode 100644
index 0000000..c0e418b
--- /dev/null
+++ b/roles/guest-configure/tasks/user.yml
@@ -0,0 +1,52 @@
+- name: Create user
+ ansible.builtin.user:
+ name: "{{ guest_configure_user }}"
+
+- name: RedHat block
+ block:
+ - name: Add user to sudo group (RedHat)
+ ansible.builtin.user:
+ name: "{{ guest_configure_user }}"
+ groups: "wheel"
+ append: yes
+
+ - name: Allow wheel group nopasswd in sudoers (RedHat)
+ lineinfile:
+ path: /etc/sudoers
+ state: present
+ regexp: '^%wheel'
+ line: '%wheel ALL=(ALL) NOPASSWD: ALL'
+ validate: 'visudo -cf %s'
+ when: ansible_os_family == "RedHat"
+
+- name: Debian block
+ block:
+ - name: Add user to sudo group (Debian)
+ ansible.builtin.user:
+ name: "{{ guest_configure_user }}"
+ groups: "sudo"
+ append: yes
+
+ - name: Allow sudo group nopasswd in sudoers (Debian)
+ lineinfile:
+ path: /etc/sudoers
+ state: present
+ regexp: '^%sudo'
+ line: '%sudo ALL=(ALL) NOPASSWD: ALL'
+ validate: 'visudo -cf %s'
+ when: ansible_os_family == "Debian"
+
+- name: Create user .ssh folder
+ ansible.builtin.file:
+ path: "/home/{{ guest_configure_user }}/.ssh/"
+ state: directory
+ mode: "0700"
+ owner: "{{ guest_configure_user }}"
+
+- name: Copy root ssh authorized_keys key to new user
+ ansible.builtin.copy:
+ src: "/root/.ssh/authorized_keys"
+ dest: "/home/{{ guest_configure_user }}/.ssh/authorized_keys"
+ remote_src: yes
+ mode: "0600"
+ owner: "{{ guest_configure_user }}"
diff --git a/roles/guest-configure/vars/main.yml b/roles/guest-configure/vars/main.yml
new file mode 100644
index 0000000..10881fb
--- /dev/null
+++ b/roles/guest-configure/vars/main.yml
@@ -0,0 +1,6 @@
+ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ansible_user: root
+
+guest_configure_user: "{{ user }}"
+guest_configure_packages: "{{ packages }}"
+guest_configure_services: "{{ services }}"
diff --git a/roles/libvirt/vars/main.yml b/roles/libvirt/vars/main.yml
index 82140c5..54fd9e7 100644
--- a/roles/libvirt/vars/main.yml
+++ b/roles/libvirt/vars/main.yml
@@ -1,4 +1,4 @@
-libvirt_vm_name: "{{ vm_name }}"
+libvirt_vm_name: "{{ inventory_hostname }}"
libvirt_vm_memory: "{{ memory_mb }}"
libvirt_vm_vcpus: "{{ cpus }}"
libvirt_vm_disk_size: "{{ disk_gb }}"
@@ -6,10 +6,10 @@ libvirt_vm_disk_format: "{{ disk_format }}"
libvirt_vm_os: "{{ os }}"
libvirt_vm_kickstart_file: "{{ kickstart }}"
libvirt_vm_location_path: "{{ iso_path }}"
-libvirt_vm_destination: "{{ parent_dataset }}/{{ vm_name }}"
+libvirt_vm_destination: "{{ parent_dataset }}/{{ inventory_hostname }}"
libvirt_vm_network: "{{ network }}"
-libvirt_kickstart_hostname: "{{ vm_name }}"
+libvirt_kickstart_hostname: "{{ inventory_hostname }}"
libvirt_kickstart_timezone: "{{ timezone }}"
-libvirt_kickstart_root_ssh_key: "{{ root_ssh_key }}"
+libvirt_kickstart_root_ssh_key: "{{ ssh_key }}"
libvirt_kickstart_root_password: "{{ root_password }}"
diff --git a/roles/zfs/vars/main.yml b/roles/zfs/vars/main.yml
index a53eb98..825fd0b 100644
--- a/roles/zfs/vars/main.yml
+++ b/roles/zfs/vars/main.yml
@@ -1 +1 @@
-zfs_dataset: "{{ parent_dataset }}/{{ vm_name }}"
+zfs_dataset: "{{ parent_dataset }}/{{ inventory_hostname }}"
diff --git a/vm-create.yml b/vm-create.yml
index 7c03b30..1c7c98e 100644
--- a/vm-create.yml
+++ b/vm-create.yml
@@ -3,44 +3,76 @@
gather_facts: false
tasks:
- - ansible.builtin.include_role:
+ - name: Import zfs role for duplicate dataset check
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-check-duplicate.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs
- - ansible.builtin.include_role:
+ - name: Import libvirt role for duplicate VM check
+ ansible.builtin.include_role:
name: libvirt
tasks_from: vm-check-duplicate.yml
apply:
+ tags: libvirt
delegate_to: "{{ hypervisor_host }}"
+ tags: libvirt
- - ansible.builtin.include_role:
+ - name: Import zfs role for creating dataset
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-create.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs
- - block:
- - ansible.builtin.include_role:
+ - name: Block for VM creation and rescue for rolling back ZFS changes if creation fails
+ block:
+ - name: Import libvirt role for creating VM
+ ansible.builtin.include_role:
name: libvirt
tasks_from: vm-install.yml
apply:
+ tags: libvirt
delegate_to: "{{ hypervisor_host }}"
+ tags: libvirt
rescue:
- - ansible.builtin.debug:
+ - name: Print VM install failure message
+ ansible.builtin.debug:
msg: VM install failed, removing dataset
+ tags: always
- - ansible.builtin.include_role:
+ - name: Import zfs role for checking dataset before destroy
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-confirm-info.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs
- - ansible.builtin.include_role:
+ - name: Import zfs role for destroying dataset
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-destroy.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs
+ - name: Fail host
+ ansible.builtin.fail:
+ msg: Host failed build process
+ tags: always
+
+ - name: Import guest-configure role
+ ansible.builtin.include_role:
+ name: guest-configure
+ apply:
+ tags: guest-configure
+ tags: guest-configure
diff --git a/vm-delete.yml b/vm-delete.yml
index 6907c84..a76e73f 100644
--- a/vm-delete.yml
+++ b/vm-delete.yml
@@ -3,38 +3,56 @@
gather_facts: false
tasks:
- - ansible.builtin.include_role:
+ - name: Import zfs role to check if dataset exists
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-check-exists.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs
- - ansible.builtin.include_role:
+ - name: Import libvirt role to check if VM exists
+ ansible.builtin.include_role:
name: libvirt
tasks_from: vm-check-exists.yml
apply:
+ tags: libvirt
delegate_to: "{{ hypervisor_host }}"
+ tags: libvirt
- - ansible.builtin.include_role:
+ - name: Import libvirt role to confirm if VM has expected configuration
+ ansible.builtin.include_role:
name: libvirt
tasks_from: vm-confirm-info.yml
apply:
+ tags: libvirt
delegate_to: "{{ hypervisor_host }}"
+ tags: libvirt
- - ansible.builtin.include_role:
+ - name: Import zfs role to confirm if the dataset has expected configuration
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-confirm-info.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs
- - ansible.builtin.include_role:
+ - name: Import libvirt role to undefine VM
+ ansible.builtin.include_role:
name: libvirt
tasks_from: vm-undefine.yml
apply:
+ tags: libvirt
delegate_to: "{{ hypervisor_host }}"
+ tags: libvirt
- - ansible.builtin.include_role:
+ - name: Import zfs role to destroy the dataset
+ ansible.builtin.include_role:
name: zfs
tasks_from: dataset-destroy.yml
apply:
+ tags: zfs
delegate_to: "{{ hypervisor_host }}"
+ tags: zfs