Skip to content

Instantly share code, notes, and snippets.

@Knappek
Last active December 12, 2024 09:35
Show Gist options
  • Select an option

  • Save Knappek/bafe131d694c497af484a5d7f67c1615 to your computer and use it in GitHub Desktop.

Select an option

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
#!/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."
@Knappek
Copy link
Author

Knappek commented Nov 6, 2024

  1. adapt environment variables if needed
  2. run it: ./deploy-ubuntu-on-vcenter.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment