VM Deployment Automation
This repository provides helper functions for deploying a variable number of virtual machines. The included examples requires an ETO that is using v2.1 software or later for the initial installation, as older builds do not have cloud-init support.
The Ansible scripts generate necessary configurations for Netplan (Ubuntu) or Network Manager (RHEL) on the system. However, these configurations are basic examples and may need further customization. Refer to the VM GSG documentation for detailed instructions on creating more tailored configurations.
Getting Started
The deployment code provided is designed to run on any machine that meets the prerequisite of having Python and Docker installed. The Python script orchestrates the deployment process by executing commands through a Docker container. This container is pre-configured with all the necessary requirements, including Ansible. The Python script passes a configuration JSON file to the Docker container, which then utilizes it for the deployment process.
Prerequisites
Ensure that you have installed:
Installation
Generate a secure SSH key in the local folder
ssh-keys/ansible
, not in the root .ssh as to not interfere with other SSH keys:
ssh-keygen -t rsa -b 4096 -f ssh-keys/ansible
Note: If the user does not add this, the deploy.py script will automatically create it.
Then startup the ansible docker container using
docker compose up -d --build
If you encounter permission-related issues, you might want to try running the command with sudo, like this:
sudo docker compose up -d --build
Usage
Set up your deployment configuration using
build_config.template.json
as a template to build your own configuration file. Please look at the Template Fields for a description of the required fields and what each field represents.Once your configuration json file is ready, then run the deployment script:
python3 deploy.py --config <config>.json
Or with optional parameters:
sudo python3 deploy.py --config <config>.json --log-dir logs/ --log-level INFO --allow-enrollment True
Description
The deployment script performs the following tasks:
Parses deployment arguments.
Checks if Docker is running; if so, starts the ansible_automation container; if not, prompts the user to start Docker and exits.
Sets up logging, creating a log file path based on the current timestamp and specified log directory. Creates the log directory if it doesn’t exist.
Reads configuration data from a JSON file specified in the arguments.
Initiates deployment, displaying progress and storing logs in the specified log file.
Outputs messages indicating the start and end of deployment.
The deployment works as follows:
Template for Virtual Machine Deployment KVM
When filling out the build_config.template.json
template to deploy virtual machines, follow the guidelines below.
Template Fields
hypervisor_hostname (Required): The hostname of the hypervisor.
hypervisor_username (Required): Username for accessing the hypervisor.
hypervisor_password (Required): Password for accessing the hypervisor.
hypervisor_vm_image_loc (Required): Location of the image on the machine or URL.
hypervisor_dest_directory (Required): Destination location for storing the image.
vm_qcow_name (Required): Name of the QCOW image.
vm_vcpus (Optional): Number of virtual CPUs. (Default: 8)
vm_memory (Optional): Amount of memory in MB. (Default: 16384)
vm_os_variant (Optional): OS variant (Default: centos7.0).
vm_boot (Optional): Boot options (Default: hd,cdrom).
vm_cpu (Optional): CPU model (Default: host).
vm_source (Optional): Network source (Default: eno0).
vm_model (Optional): Network model (Default: virtio).
vm_source_mode (Optional): Source mode (Default: bridge).
vm_network_net_a (Required): Network bridge name to be created for for net-a.
vm_network_net_b (Required): Network bridge name to be created for for net-b.
vm_network_app_a (Required): Network bridge name to be created for for app-a.
vm_network_app_b (Required): Network bridge name to be created for for app-b.
vm_network_mir_a (Required): Network bridge name to be created for for mir-a.
vm_network_mir_b (Required): Network bridge name to be created for for mir-b.
vm_username (Required): Username for accessing the virtual machine.
vm_api_username (Optional): API username for the virtual machine (Default: mira).
vm_password (Required): Password for accessing the virtual machine.
vm_old_password (Required): Old/Default password for the virtual machine (if applicable).
vm_hostname (Required): New hostname of the virtual machine.
vm_static_ip_address (Optional): Static IP address for the virtual machine.
vm_ip_netmask (Optional): Subnet mask for the virtual machine’s IP address.
vm_ip_gateway (Optional): Gateway IP address for the virtual machine.
vm_dns_server_1 (Optional): Primary DNS server for the virtual machine.
vm_dns_server_2 (Optional): Secondary DNS server for the virtual machine.
vm_allow_enrollment (Optional): Boolean to allow the ETO to change it’s enrollment state.
Note: Fields marked as (Optional) are not mandatory for deployment but may be required depending on your specific setup.
ETO Setup via API
The deploy.py
file also changes the default password for the ‘admin’ user for the ETO API. Additionally, the setup_eto.py
file is responsible for modifying default settings and can be utilized independently. If vm_static_ip_address
is specified in the <config>.json
file, along with vm_ip_netmask
, vm_ip_gateway
, and vm_allow_enrollment
, then the enrollment state for the ETO can be altered. Otherwise, the default API settings will remain unchanged.
The script can be executed independently with the following command:
python3 setup_eto.py --ip=<vm_static_ip_address> --username=<vm_api_username> --old_password=<vm_old_password> --password=<vm_password> --allow-enrollment=<vm_allow_enrollment>
This command will update the default password for the ETO and adjust the enrollment state accordingly.
Cleanup
Should something go wrong, or the user wishes to remove the VM from the system the cleanup.py
is is made available. It requires the same configuration used for the deploy.py
file. It’s purpose is to remove and delete the VM and associated files from it, along with the network configurations setup by Netplan (Ubuntu) or NetworkManager (RedHat). None of the system packages are modified by this play.
The python file can be run with the following command:
python3 cleanup.py --config <config>.json --log-dir logs/ --log-level INFO
The following is the build_config.template.json:
[
{
"hypervisor_hostname": "<hostname>",
"hypervisor_username": "<username>",
"hypervisor_password": "<secret>",
"hypervisor_vm_image_loc": "<location_on_machine/url>",
"hypervisor_dest_directory": "/var/lib/libvirt/images/",
"vm_qcow_name": "",
"vm_vcpus": 8,
"vm_memory": 16384,
"vm_os_variant": "centos7.0",
"vm_boot": "hd,cdrom",
"vm_cpu": "host",
"vm_source": "<mgmt-interface>",
"vm_model": "virtio",
"vm_source_mode": "bridge",
"vm_network_net_a": "br-net-a<X>",
"vm_network_net_b": "br-net-b<X>",
"vm_network_app_a": "br-app-a<X>",
"vm_network_app_b": "br-app-b<X>",
"vm_network_mir_a": "br-mir-a<X>",
"vm_network_mir_b": "br-mir-b<X>",
"vm_username": "mira",
"vm_api_username": "admin",
"vm_password": "<password>",
"vm_old_password": "<password>",
"vm_hostname": "<hostname>",
"vm_static_ip_address": "<ip>",
"vm_ip_netmask": "<ip>",
"vm_ip_gateway": "<ip>",
"vm_dns_server_1": "<ip>",
"vm_dns_server_2": "<ip>",
"vm_allow_enrollment": false
}
]