diff --git a/.gitignore b/.gitignore index 496ee2c..555bba8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +alpine-iso \ No newline at end of file diff --git a/bolt_vm_automation/inventory.yaml b/bolt_vm_automation/inventory.yaml index eae709b..4a333c4 100644 --- a/bolt_vm_automation/inventory.yaml +++ b/bolt_vm_automation/inventory.yaml @@ -1,20 +1,13 @@ groups: - name: remote-host targets: - - name: roscoe + - name: vortex config: transport: ssh ssh: host: 100.40.223.136 user: root host-key-check: false - - name: siderack - config: - transport: ssh - ssh: - host: 100.40.223.138 - user: root - host-key-check: false - name: astrocore config: transport: ssh diff --git a/bolt_vm_automation/plans/create_alpine.yaml b/bolt_vm_automation/plans/create_alpine.yaml new file mode 100644 index 0000000..ef5ee79 --- /dev/null +++ b/bolt_vm_automation/plans/create_alpine.yaml @@ -0,0 +1,122 @@ +--- +parameters: + target: + type: String + description: "Target host to create the VM on" + default: "vortex" + iso_path: + type: String + description: "Path to the ISO file" + default: "/mnt/nfs/kvm-isos/iso-build/alpine-autoinstall.iso" + vm_name: + type: String + description: "Name of the VM" + default: "vm-template-staging" + ram: + type: Integer + description: "Amount of RAM in MB" + default: 8192 + vcpus: + type: Integer + description: "Number of virtual CPUs" + default: 4 + disk_size: + type: Integer + description: "Size of the disk in GB" + default: 100 + disk_path: + type: String + description: "Base path for disk images" + default: "/mnt/nfs/kvm-images" + network: + type: String + description: "Network to connect the VM to" + default: "wan-verizon" + os_variant: + type: String + description: "OS variant for the VM" + default: "alpinelinux3.20" + ip_with_cidr: + type: String + description: "Public IP of the VM" + staging_ip: + type: String + description: "Staging IP" + default: "100.40.223.190" + hostname: + type: String + description: "Hostname of the VM" + default: "vm-template-staging" + dhcp: + type: Boolean + description: "Enable DHCP on the VM" + default: false + gateway: + type: String + description: "Gateway for the VM" + default: "100.40.223.1" + nameserver1: + type: String + description: "Primary nameserver for the VM" + default: "8.8.8.8" + nameserver2: + type: String + description: "Secondary nameserver for the VM" + default: "8.8.4.4" + nameserver3: + type: String + description: "Tertiary nameserver for the VM" + default: "1.1.1.1" + +steps: + - name: create_vm + task: bolt_vm_automation::create_alpine + targets: $target + parameters: + iso_path: $iso_path + vm_name: $vm_name + ram: $ram + vcpus: $vcpus + disk_size: $disk_size + disk_path: "${disk_path}/${vm_name}.qcow2" + network: $network + os_variant: $os_variant + + - name: install_alpine + description: Install Alpine OS on the VM + task: bolt_vm_automation::install_alpine + targets: localhost + parameters: + vm_name: $vm_name + disk_path: "${disk_path}/${vm_name}.qcow2" + staging_ip: $staging_ip + + - name: install_packages + description: Install Packages on the VM + task: bolt_vm_automation::install_packages_alpine + targets: localhost + parameters: + staging_ip: $staging_ip + + - name: install_docker + description: Install Docker on the VM + task: bolt_vm_automation::install_docker_alpine + targets: localhost + parameters: + staging_ip: $staging_ip + + - name: system_setup + task: bolt_vm_automation::system_setup_alpine + targets: localhost + parameters: + ip_with_cidr: $ip_with_cidr + hostname: $hostname + dhcp: $dhcp + gateway: $gateway + nameserver1: $nameserver1 + nameserver2: $nameserver2 + nameserver3: $nameserver3 + staging_ip: $staging_ip + +return: + message: "VM ${vm_name} created and updated successfully!" diff --git a/bolt_vm_automation/plans/create_vm.yaml b/bolt_vm_automation/plans/create_ubuntu.yaml similarity index 88% rename from bolt_vm_automation/plans/create_vm.yaml rename to bolt_vm_automation/plans/create_ubuntu.yaml index f0d92cc..2cedac7 100644 --- a/bolt_vm_automation/plans/create_vm.yaml +++ b/bolt_vm_automation/plans/create_ubuntu.yaml @@ -3,7 +3,7 @@ parameters: target: type: String description: "Target host to create the VM on" - default: "roscoe" + default: "vortex" iso_path: type: String description: "Path to the ISO file" @@ -32,6 +32,10 @@ parameters: type: String description: "Network to connect the VM to" default: "wan-verizon" + os_variant: + type: String + description: "OS variant for the VM" + default: "ubuntu22.04" ip_with_cidr: type: String description: "Public IP of the VM" @@ -63,7 +67,7 @@ parameters: steps: - name: create_vm - task: bolt_vm_automation::create_vm + task: bolt_vm_automation::create_ubuntu targets: $target parameters: iso_path: $iso_path @@ -73,14 +77,15 @@ steps: disk_size: $disk_size disk_path: "${disk_path}/${vm_name}.qcow2" network: $network + os_variant: $os_variant - name: install_docker description: Install Docker on the VM - task: bolt_vm_automation::install_docker + task: bolt_vm_automation::install_docker_ubuntu targets: vm-template-staging - name: system_setup - task: bolt_vm_automation::system_setup + task: bolt_vm_automation::system_setup_ubuntu targets: vm-template-staging parameters: ip_with_cidr: $ip_with_cidr diff --git a/bolt_vm_automation/tasks/create_alpine.sh b/bolt_vm_automation/tasks/create_alpine.sh new file mode 100644 index 0000000..b3a4cb4 --- /dev/null +++ b/bolt_vm_automation/tasks/create_alpine.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Input Variables +ISO_PATH=$PT_iso_path +VM_NAME=$PT_vm_name +RAM=$PT_ram +VCPUS=$PT_vcpus +DISK_SIZE=$PT_disk_size +DISK_PATH=$PT_disk_path +NETWORK=$PT_network +OS_VARIANT=$PT_os_variant + +# Create VM disk if not already exists +if [ ! -f "$DISK_PATH" ]; then + qemu-img create -f qcow2 "$DISK_PATH" "$DISK_SIZE"G > /dev/null 2>&1 +fi + +# Create VM +virt-install \ + --name "$VM_NAME" \ + --ram "$RAM" \ + --vcpus "$VCPUS" \ + --os-variant "$OS_VARIANT" \ + --disk path="$DISK_PATH",format=qcow2 \ + --cdrom "$ISO_PATH" \ + --network network="$NETWORK" \ + --graphics vnc \ + --noautoconsole \ + --autostart \ + --wait -1 \ + > /dev/null 2>&1 & + +sleep 25 \ No newline at end of file diff --git a/bolt_vm_automation/tasks/create_vm.json b/bolt_vm_automation/tasks/create_ubuntu.json similarity index 91% rename from bolt_vm_automation/tasks/create_vm.json rename to bolt_vm_automation/tasks/create_ubuntu.json index 02fcc99..058dfd9 100644 --- a/bolt_vm_automation/tasks/create_vm.json +++ b/bolt_vm_automation/tasks/create_ubuntu.json @@ -35,6 +35,10 @@ "type": "String", "description": "Network to connect the VM to", "default": "wan-verizon" + }, + "os_variant": { + "type": "String", + "description": "OS variant for the VM" } } } \ No newline at end of file diff --git a/bolt_vm_automation/tasks/create_vm.sh b/bolt_vm_automation/tasks/create_ubuntu.sh similarity index 91% rename from bolt_vm_automation/tasks/create_vm.sh rename to bolt_vm_automation/tasks/create_ubuntu.sh index 9b3cca3..b19add7 100644 --- a/bolt_vm_automation/tasks/create_vm.sh +++ b/bolt_vm_automation/tasks/create_ubuntu.sh @@ -8,6 +8,7 @@ VCPUS=$PT_vcpus DISK_SIZE=$PT_disk_size DISK_PATH=$PT_disk_path NETWORK=$PT_network +OS_VARIANT=$PT_os_variant # Create VM disk if not already exists if [ ! -f "$DISK_PATH" ]; then @@ -19,7 +20,7 @@ virt-install \ --name "$VM_NAME" \ --ram "$RAM" \ --vcpus "$VCPUS" \ - --os-variant ubuntu22.04 \ + --os-variant "$OS_VARIANT" \ --disk path="$DISK_PATH",format=qcow2 \ --cdrom "$ISO_PATH" \ --network network="$NETWORK" \ diff --git a/bolt_vm_automation/tasks/install_alpine.sh b/bolt_vm_automation/tasks/install_alpine.sh new file mode 100644 index 0000000..7586057 --- /dev/null +++ b/bolt_vm_automation/tasks/install_alpine.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Input Variables +VM_NAME="${PT_vm_name}" +DISK_PATH="${PT_disk_path}" +STAGING_IP="${PT_staging_ip}" + +# Wait for VM to be accessible via SSH +while ! ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@${STAGING_IP} "echo 'VM is accessible'"; do + sleep 5 +done + +# Create autoinstall answer file directly on VM +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "cat > /tmp/alpine-answers << 'EOF' +KEYMAPOPTS=\"us us\" +HOSTNAMEOPTS=\"-n vm-template-staging\" +INTERFACESOPTS=\"auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet static + address 100.40.223.190 + netmask 255.255.255.0 + gateway 100.40.223.1 +\" +DNSOPTS=\"-n 8.8.8.8 8.8.4.4\" +TIMEZONEOPTS=\"-z UTC\" +PROXYOPTS=\"none\" +APKREPOSOPTS=\"-1\" +USEROPTS=\"-a -u moeny\" +USERSSHKEY=\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCRMJNdI/n/7xYN65zHFN8hlRSDg5OPJ12AwOsUyP8OmKCQTapoVQ/suvjaUTCtt8o28QNIQm1vAD03hFNzVJn6F6FJu9vUbR+YqlmzmzGJXB6sWWTEnc9/GsVvLoculuzFYfa2qU9xFbuUTtqFRu6qor82TPAhy/yVWzIvRxlfuxKLpdU9paKiV+WtCkSpVoBgIH6soBE1swMX4ILIOGeFTrmCdBac4K1Bs0OarKtShR6PHdNiqPlwpCeQQDZD8ops69yBMc0t6poFZC9FYSj7arJEWvZN9YtUr+PJiYZQc+gIG4enPW1Zf4FEkXXvH/t6RaYMq9w/P5lIUNOVe169\" +ROOTSSHKEY=\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCRMJNdI/n/7xYN65zHFN8hlRSDg5OPJ12AwOsUyP8OmKCQTapoVQ/suvjaUTCtt8o28QNIQm1vAD03hFNzVJn6F6FJu9vUbR+YqlmzmzGJXB6sWWTEnc9/GsVvLoculuzFYfa2qU9xFbuUTtqFRu6qor82TPAhy/yVWzIvRxlfuxKLpdU9paKiV+WtCkSpVoBgIH6soBE1swMX4ILIOGeFTrmCdBac4K1Bs0OarKtShR6PHdNiqPlwpCeQQDZD8ops69yBMc0t6poFZC9FYSj7arJEWvZN9YtUr+PJiYZQc+gIG4enPW1Zf4FEkXXvH/t6RaYMq9w/P5lIUNOVe169\" +SSHDOPTS=\"-c openssh\" +NTPOPTS=\"-c chrony\" +DISKOPTS=\"-m sys /dev/vda\" +EOF" + +# Run installation commands over SSH +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "echo 'y' | setup-alpine -e -f /tmp/alpine-answers" + +# Wait for installation to complete +sleep 45 + +# Reboot via SSH +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "reboot" + +# Wait for VM to come back up +sleep 30 + +# Verify installation by trying to SSH +if ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@${STAGING_IP} "echo 'VM is running'"; then + echo "Alpine installation completed successfully" + exit 0 +else + echo "Failed to install Alpine" + exit 1 +fi \ No newline at end of file diff --git a/bolt_vm_automation/tasks/install_docker_alpine.sh b/bolt_vm_automation/tasks/install_docker_alpine.sh new file mode 100644 index 0000000..0945314 --- /dev/null +++ b/bolt_vm_automation/tasks/install_docker_alpine.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Input Variables +STAGING_IP="${PT_staging_ip}" + +# Update package list and install Docker +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "apk update && apk add --no-cache docker docker-cli docker-cli-compose" + +# Add current user to docker group +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "addgroup moeny docker" + +# Start and enable Docker service +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "rc-service docker start && rc-update add docker default" + +# Verify installation +if ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "docker --version" > /dev/null 2>&1; then + echo "Docker installed successfully" + exit 0 +else + echo "Docker installation failed" + exit 1 +fi \ No newline at end of file diff --git a/bolt_vm_automation/tasks/install_docker.sh b/bolt_vm_automation/tasks/install_docker_ubuntu.sh similarity index 100% rename from bolt_vm_automation/tasks/install_docker.sh rename to bolt_vm_automation/tasks/install_docker_ubuntu.sh diff --git a/bolt_vm_automation/tasks/install_packages_alpine.sh b/bolt_vm_automation/tasks/install_packages_alpine.sh new file mode 100644 index 0000000..797aff9 --- /dev/null +++ b/bolt_vm_automation/tasks/install_packages_alpine.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Input Variables +STAGING_IP="${PT_staging_ip}" + +# Uncomment to enable community repository +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "sed -i '3s/^#//' /etc/apk/repositories" + +# Install required packages +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "apk update && apk add --no-cache vim fping htop sudo bash mtr" + +# Change default shell to bash +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "sed -i -E '/^(root|moeny):/ s:/bin/sh$:/bin/bash:' /etc/passwd" + +# Set mouse for vim +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "sed -i '1i let skip_defaults_vim = 1\nset mouse=' /etc/vim/vimrc" + +# Add moeny user to sudo group +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "addgroup sudo;addgroup moeny sudo" + +# Set no password to sudo group +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "echo '%sudo ALL=(ALL) NOPASSWD: ALL' | tee -a /etc/sudoers.d/nopasswd_sudo_group" diff --git a/bolt_vm_automation/tasks/system_setup_alpine.json b/bolt_vm_automation/tasks/system_setup_alpine.json new file mode 100644 index 0000000..efdf498 --- /dev/null +++ b/bolt_vm_automation/tasks/system_setup_alpine.json @@ -0,0 +1,45 @@ +{ + "description": "Configures system network settings using Alpine Linux network configuration", + "parameters": { + "ip_with_cidr": { + "type": "String", + "description": "IP address for the VM", + "default": "100.40.223.190/24" + }, + "hostname": { + "type": "String", + "description": "Hostname for the VM", + "default": "vm-template-staging" + }, + "dhcp": { + "type": "Boolean", + "description": "Whether to use DHCP for network configuration", + "default": false + }, + "gateway": { + "type": "String", + "description": "Gateway IP address", + "default": "100.40.223.1" + }, + "nameserver1": { + "type": "String", + "description": "Primary DNS nameserver", + "default": "8.8.8.8" + }, + "nameserver2": { + "type": "String", + "description": "Secondary DNS nameserver", + "default": "8.8.4.4" + }, + "nameserver3": { + "type": "String", + "description": "Tertiary DNS nameserver", + "default": "1.1.1.1" + }, + "staging_ip": { + "type": "String", + "description": "Staging IP address", + "default": "100.40.223.190" + } + } +} \ No newline at end of file diff --git a/bolt_vm_automation/tasks/system_setup_alpine.sh b/bolt_vm_automation/tasks/system_setup_alpine.sh new file mode 100644 index 0000000..f185d12 --- /dev/null +++ b/bolt_vm_automation/tasks/system_setup_alpine.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Using Bolt's environment variables +IP="${PT_ip_with_cidr}" +HOSTNAME="${PT_hostname}" +DHCP="${PT_dhcp}" +GATEWAY="${PT_gateway}" +NAMESERVER1="${PT_nameserver1}" +NAMESERVER2="${PT_nameserver2}" +NAMESERVER3="${PT_nameserver3}" +STAGING_IP="${PT_staging_ip}" + +# Check if all required parameters are provided +if [ -z "$IP" ] || [ -z "$HOSTNAME" ] || [ -z "$DHCP" ] || [ -z "$GATEWAY" ] || [ -z "$NAMESERVER1" ] || [ -z "$NAMESERVER2" ] || [ -z "$NAMESERVER3" ]; then + echo "Missing required parameters. All parameters must be provided." + exit 1 +fi + +# Install required packages +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "apk add --no-cache iptables" + +# Configure iptables rules +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "iptables -A INPUT -p tcp --dport 22 -s 100.40.223.128/26 -j ACCEPT && \ + iptables -A INPUT -p tcp --dport 22 -s 173.62.109.73/32 -j ACCEPT && \ + iptables -A INPUT -p tcp --dport 22 -j DROP" + +# Save iptables rules +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "rc-service iptables save" + +# Configure network +if [ "$DHCP" = "false" ]; then + # Create network configuration directly on VM + ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "cat > /etc/network/interfaces << 'EOF' +auto eth0 +iface eth0 inet static + address ${IP} + gateway ${GATEWAY} +EOF" +fi + +# Configure DNS directly on VM +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "cat > /etc/resolv.conf << 'EOF' +nameserver ${NAMESERVER1} +nameserver ${NAMESERVER2} +nameserver ${NAMESERVER3} +EOF" + +# Set hostname +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "echo '${HOSTNAME}' > /etc/hostname" + +# Update /etc/hosts +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "sed -i 's/127.0.0.1.*/127.0.0.1\t${HOSTNAME}/' /etc/hosts" + +# Enable and start iptables service +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "rc-update add iptables default && rc-service iptables start" + +echo "System configuration completed successfully" + +# Reboot the system +ssh -o StrictHostKeyChecking=no root@${STAGING_IP} "nohup sh -c '(sleep 2 && reboot) &' > /dev/null 2>&1" +exit 0 \ No newline at end of file diff --git a/bolt_vm_automation/tasks/system_setup.json b/bolt_vm_automation/tasks/system_setup_ubuntu.json similarity index 84% rename from bolt_vm_automation/tasks/system_setup.json rename to bolt_vm_automation/tasks/system_setup_ubuntu.json index d8f0ade..3700ed7 100644 --- a/bolt_vm_automation/tasks/system_setup.json +++ b/bolt_vm_automation/tasks/system_setup_ubuntu.json @@ -1,10 +1,9 @@ { - "description": "Configures system network settings using netplan", + "description": "Configures system network settings using Ubuntu netplan", "parameters": { "ip_with_cidr": { "type": "String", - "description": "IP address for the VM", - "default": "100.40.223.190/24" + "description": "IP address for the VM" }, "hostname": { "type": "String", diff --git a/bolt_vm_automation/tasks/system_setup.sh b/bolt_vm_automation/tasks/system_setup_ubuntu.sh similarity index 100% rename from bolt_vm_automation/tasks/system_setup.sh rename to bolt_vm_automation/tasks/system_setup_ubuntu.sh