vmcreator

main
gwen 5 months ago
parent e6dbf7caad
commit 3a71e5e75b

@ -0,0 +1 @@
ansible-playbook -i hosts create_vm.yml

@ -0,0 +1,169 @@
---
- name: Ensure multipass is installed and create a VM with cloud-init
hosts: localhost
gather_facts: yes
vars_prompt:
- name: vm_name
prompt: "What is the VM name (don't use spaces)?"
private: no
default: testvm
vars:
vm_image: 24.04
vm_disk: 15G
vm_memory: 4G
vm_cpus: 1
ssh_key_name: "{{ vm_name }}_ssh_key"
tasks:
- name: Check if VM already exists
command: multipass list --format json
register: vm_list_json
- name: Parse VM list
set_fact:
vm_exists: "{{ vm_name in ((vm_list_json.stdout | from_json).list | map(attribute='name') | list) }}"
- name: Output message if VM already exists
debug:
msg: "VM with name '{{ vm_name }}' already exists. No action will be taken."
when: vm_exists
- name: Gather OS facts
setup:
filter: "ansible_distribution"
when: not vm_exists
- name: Detect OS
set_fact:
os_type: "{{ ansible_facts['distribution'] }}"
- name: Check if Homebrew is installed (macOS)
command: brew --version
register: homebrew_check
ignore_errors: yes
when: os_type == "MacOSX" and not vm_exists
- name: Install Homebrew (macOS)
shell: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
when: os_type == "MacOSX" and homebrew_check.failed and not vm_exists
- name: Check if multipass is installed
shell: "command -v multipass || echo 'not found'"
register: multipass_check
changed_when: false
- name: Install multipass using Homebrew (macOS)
homebrew:
name: multipass
state: present
when:
- os_type == "MacOSX"
- multipass_check.stdout == "not found"
- not vm_exists
- name: Install multipass using snap (Ubuntu)
snap:
name: multipass
state: present
when:
- os_type == "Ubuntu"
- multipass_check.stdout == "not found"
- not vm_exists
- name: Generate SSH key pair
command: ssh-keygen -t rsa -b 2048 -f ./{{ ssh_key_name }} -N "" -C "ubuntu"
args:
creates: ./{{ ssh_key_name }}
when: not vm_exists
- name: Read the public SSH key
command: cat ./{{ ssh_key_name }}.pub
register: ssh_public_key
when: not vm_exists
- name: Create cloud-init.yaml file
copy:
dest: ./cloud-init.yaml
content: |
## cloud-init
users:
- name: ubuntu
ssh-authorized-keys:
- {{ ssh_public_key.stdout }}
sudo: ['ALL=(ALL) NOPASSWD:ALL']
groups: sudo
shell: /bin/bash
package_update: true
packages:
- python3-pip
- python3
- python-is-python3
- python3-venv
hostname: {{ vm_name }}
fqdn: {{ vm_name }}.local
final_message: "The instance is now up for $UPTIME seconds"
when: not vm_exists
- name: Verify cloud-init.yaml file exists
stat:
path: ./cloud-init.yaml
register: cloud_init_file
when: not vm_exists
- name: Fail if cloud-init.yaml does not exist
fail:
msg: "cloud-init.yaml file does not exist"
when:
- not vm_exists
- cloud_init_file is defined
- not cloud_init_file.stat.exists | default(false)
- name: Launch VM with multipass
command: multipass launch {{ vm_image }} --name {{ vm_name }} --disk {{ vm_disk }} -m {{ vm_memory }} --cloud-init ./cloud-init.yaml
register: vm_launch
when: not vm_exists
- name: Get VM info
command: multipass info {{ vm_name }} --format json
register: vm_info_json
when: not vm_exists
- name: Parse VM IP address
set_fact:
vm_ip: "{{ (vm_info_json.stdout | from_json).info[vm_name].ipv4[0] }}"
when: not vm_exists
- name: Generate inventory file
copy:
dest: ./inventory.yml
content: |
all:
hosts:
{{ vm_name }}:
ansible_host: {{ vm_ip }}
ansible_python_interpreter: /usr/bin/python3
vars:
ansible_user: ubuntu
ansible_ssh_private_key_file: ./{{ ssh_key_name }}
when: not vm_exists
- name: Add VM hostname to local /etc/hosts
become: yes
lineinfile:
path: /etc/hosts
line: "{{ vm_ip }} {{ vm_name }}.local"
state: present
when: not vm_exists
- name: Wait for VM to be ready
wait_for:
host: "{{ vm_ip }}"
port: 22
delay: 10
timeout: 300
when: not vm_exists

@ -0,0 +1 @@
localhost ansible_connection=local

@ -0,0 +1,43 @@
VM Creator
===========
Just another ansible tool that automates a VM creation whit multipass.
It reinforces the lauching of a manual script like this one::
multipass launch 24.04 --name XXX --cpus 8 --disk 100G -m 30G --cloud-init cloud-init.yaml
Because this script has dependencies. it needs:
- a cloud init file
- an ssh key
- a cloud init file
.. important:: Needs to be root to do such a thing
launch
---------
::
./create_vm.sh
Besides generating the VM, it generates:
- an inventory in YAML format
- a dedicated ssh key
usage
--------
verify that the `testvm` VM is ready, launch this command in a terminal::
multipass list | grep testvm
example output::
multipass list | grep testvm
testvm Running 10.190.208.122 Ubuntu 24.04 LTS
Loading…
Cancel
Save