Last active
December 12, 2024 09:35
-
-
Save Knappek/bafe131d694c497af484a5d7f67c1615 to your computer and use it in GitHub Desktop.
deploy ubuntu VM on vCenter with public ssh key distributed and a static IP address
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -e | |
| set -u | |
| set -o pipefail | |
| # Prompt for GOVC environment variables if not already set | |
| : "${GOVC_URL:?ESX or vCenter URL (e.g., https://1.2.3.4:443): }" | |
| : "${GOVC_USERNAME:[email protected]}" | |
| : "${GOVC_PASSWORD:=VMware1!}" | |
| : "${GOVC_INSECURE:=1}" # Default to 1 (ignore SSL warnings) if not set | |
| export GOVC_URL GOVC_USERNAME GOVC_PASSWORD GOVC_INSECURE | |
| : "${DNS_SERVER:=192.168.178.1}" | |
| : "${INTERFACE_NAME:=ens192}" | |
| : "${DATASTORE:=datastore-esx1}" | |
| : "${OVA_URL:=https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.ova}" | |
| : "${SOFTWARE_DIR:=$HOME/workspace/vmware-products}" | |
| : "${NETWORK:=infra-seg}" | |
| : "${SSH_KEY_FILE:=$HOME/.ssh/id_rsa.pub}" | |
| : "${DISK_SIZE_GB:=10}" | |
| read -p "Please enter the static IP for the VM with netmask (e.g., 192.168.1.100/24): " static_ip | |
| read -p "Please enter the gateway IP for the network (e.g., 192.168.1.1): " gateway | |
| read -p "Please enter the name for the new VM: " vm_name | |
| if [[ ! -f "$SSH_KEY_FILE" ]]; then | |
| echo "Error: SSH public key not found at $SSH_KEY_FILE" | |
| echo "Please generate an SSH key pair using 'ssh-keygen' or specify the correct path." | |
| exit 1 | |
| fi | |
| SSH_KEY=$(<"$SSH_KEY_FILE") | |
| local_ova_file="$SOFTWARE_DIR/$(basename "$OVA_URL")" | |
| if [[ ! -f "$local_ova_file" ]]; then | |
| echo "Downloading OVA from $OVA_URL..." | |
| curl -L -o "$local_ova_file" "$OVA_URL" | |
| if [[ $? -ne 0 ]]; then | |
| echo "Error: Failed to download OVA file." | |
| exit 1 | |
| fi | |
| fi | |
| # TODO: figure out how to import an ova from the datastore | |
| # # Upload the OVA to the datastore if it's not already there | |
| # ova_basename=$(basename "$OVA_URL") | |
| # ova_path="${OVA_PATH:-$ova_basename}" | |
| # if ! govc datastore.ls -ds "$datastore" "$ova_path" > /dev/null 2>&1; then | |
| # echo "Uploading OVA to datastore at $ova_path..." | |
| # govc datastore.upload -ds "$datastore" "$local_ova_file" "$ova_path" | |
| # if [[ $? -ne 0 ]]; then | |
| # echo "Error: Failed to upload OVA file to datastore." | |
| # exit 1 | |
| # fi | |
| # fi | |
| USER_DATA=$(cat <<EOF | |
| #cloud-config | |
| write_files: | |
| - path: /etc/cloud/cloud.cfg.d/99-custom-networking.cfg | |
| permissions: '0644' | |
| content: | | |
| network: {config: disabled} | |
| - path: /etc/netplan/custom-static-ip-config.yaml | |
| permissions: '0644' | |
| content: | | |
| network: | |
| version: 2 | |
| ethernets: | |
| $INTERFACE_NAME: | |
| dhcp4: false | |
| dhcp6: false | |
| addresses: | |
| - $static_ip | |
| routes: | |
| - to: default | |
| via: $gateway | |
| nameservers: | |
| addresses: [$DNS_SERVER] | |
| runcmd: | |
| - rm /etc/netplan/50-cloud-init.yaml | |
| - netplan generate | |
| - netplan apply | |
| EOF | |
| ) | |
| CLOUD_CONFIG_BASE64=$(echo "$USER_DATA" | base64 -w 0) | |
| govc import.ova -ds "$DATASTORE" -name "$vm_name" -options <(cat <<EOF | |
| { | |
| "DiskProvisioning": "thin", | |
| "IPAllocationPolicy": "fixedPolicy", | |
| "IPProtocol": "IPv4", | |
| "PropertyMapping": [ | |
| { | |
| "Key": "instance-id", | |
| "Value": "id-ovf" | |
| }, | |
| { | |
| "Key": "hostname", | |
| "Value": "ubuntuguest" | |
| }, | |
| { | |
| "Key": "seedfrom", | |
| "Value": "" | |
| }, | |
| { | |
| "Key": "public-keys", | |
| "Value": "$SSH_KEY" | |
| }, | |
| { | |
| "Key": "user-data", | |
| "Value": "${CLOUD_CONFIG_BASE64}" | |
| }, | |
| { | |
| "Key": "password", | |
| "Value": "" | |
| } | |
| ], | |
| "NetworkMapping": [ | |
| { | |
| "Name": "VM Network", | |
| "Network": "$NETWORK" | |
| } | |
| ], | |
| "MarkAsTemplate": false, | |
| "PowerOn": false, | |
| "InjectOvfEnv": false, | |
| "WaitForIP": false, | |
| "Name": null | |
| } | |
| EOF | |
| ) "$local_ova_file" | |
| if ! govc vm.disk.change -vm "$vm_name" -disk.label "Hard disk 1" -size "${DISK_SIZE_GB}GB"; then | |
| echo "Error: Failed to resize VM disk." | |
| exit 1 | |
| fi | |
| govc vm.power -on "$vm_name" | |
| static_ip_without_mask=$(echo "$static_ip" | cut -d'/' -f1) | |
| echo "Waiting for VM $vm_name to be reachable at IP $static_ip_without_mask..." | |
| until nc -z -w 5 "$static_ip_without_mask" 22; do | |
| echo "VM is not reachable yet. Retrying in 10 seconds..." | |
| sleep 10 | |
| done | |
| echo "VM $vm_name has been deployed and powered on with static IP $static_ip_without_mask and SSH key configured." |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
./deploy-ubuntu-on-vcenter.sh