Skip to content

Instantly share code, notes, and snippets.

@asafamr
Last active January 28, 2020 08:37
Show Gist options
  • Save asafamr/77ac61a42aea6dbdaa8650fafcbfe4d8 to your computer and use it in GitHub Desktop.
Save asafamr/77ac61a42aea6dbdaa8650fafcbfe4d8 to your computer and use it in GitHub Desktop.
Clone GCP instance using gcloud cli. google cloud, clone instance, create similar, programatically, script. --- creates a snapshot and an instance template from an instance, then creates new instances using them
#!/usr/bin/env bash
if [ $# -lt 2 ]
then
cat << EOF
usage: `basename "$0"` [-g <group-name> ] <source-instance-name> <cloned-instance-name1> [<cloned-instance-name2>... N]
Clone the source instance in the same region N+1 times and possbliy put all cones into a new unmanaged instance group
-g <group name>(optional)- use this flag to put all newly created instnaces into
a new unmanged instance group named <group-name>
<source-instance-name> - the name of the instance to be cloned, followed by the clones names
EOF
exit 0
fi
# exit when any command fails
set -e
# keep track of the last executed command
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
# echo an error message before exiting
trap 'echo "\"${last_command}\" command filed with exit code $?."' EXIT
export LC_CTYPE=C
RANDGUID=`cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 10 | head -n 1`
if [ $1 = "-g" ]
then
GROUP_NAME=$2
shift 2
else
GROUP_NAME=
fi
INSTANCE_NAME=$1
shift 1
CLONE_NAMES=$@
INSTANCE_INFO=`gcloud compute instances list --filter="name=$INSTANCE_NAME" | tail -n 1`
INSTANCE_ZONE=`echo $INSTANCE_INFO | awk '{print $2}'`
INSTANCE_REGION=`echo $INSTANCE_ZONE| cut -d'-' -f -2`
INSTANCE_STATUS=`echo $INSTANCE_INFO | awk '{print $NF}'`
INSTANCE_DISK_INFO=`gcloud compute disks list --filter="name=$INSTANCE_NAME"| tail -n 1`
INSTANCE_DISK_SIZE=`echo $INSTANCE_DISK_INFO | awk '{print $4}'`
INSTANCE_DISK_TYPE=`echo $INSTANCE_DISK_INFO | awk '{print $5}'`
echo - Instance name:$INSTANCE_NAME, Zone:$INSTANCE_ZONE \(Region:$INSTANCE_REGION\), Status:$INSTANCE_STATUS
echo - Creating an instance template...
if gcloud compute disks describe $INSTANCE_NAME --zone $INSTANCE_ZONE | grep sourceImage
then
gcloud compute instance-templates create $INSTANCE_NAME-$RANDGUID --source-instance $INSTANCE_NAME --source-instance-zone $INSTANCE_ZONE
else
# a cloned machine does not have a source image and throws here unless this workaround is used
gcloud compute instance-templates create $INSTANCE_NAME-$RANDGUID --source-instance $INSTANCE_NAME --source-instance-zone $INSTANCE_ZONE \
--configure-disk=device-name=$INSTANCE_NAME,instantiate-from=custom-image,auto-delete=true,custom-image=projects/debian-cloud/global/images/debian-9-stretch-v20191210
fi
echo - Cloning boot disk \(NOTE: only the boot disk is cloned into new instances!\)...
gcloud compute disks snapshot $INSTANCE_NAME --description 'Cloned by script' --zone $INSTANCE_ZONE --snapshot-names $INSTANCE_NAME-$RANDGUID --storage-location $INSTANCE_REGION
for CLONE_NAME in $CLONE_NAMES; do
echo - Creating $CLONE_NAME...
gcloud compute instances create $CLONE_NAME --source-instance-template $INSTANCE_NAME-$RANDGUID \
--source-snapshot $INSTANCE_NAME-$RANDGUID --boot-disk-size $INSTANCE_DISK_SIZE \
--boot-disk-type $INSTANCE_DISK_TYPE --boot-disk-device-name $CLONE_NAME \
--zone $INSTANCE_ZONE --async
done
sleep 3
if [ ! -z "$GROUP_NAME" ]
then
echo - Adding newly created instances to the unmanaged group: $GROUP_NAME...
gcloud compute instance-groups unmanaged create "$GROUP_NAME" --zone $INSTANCE_ZONE
COMMA_SEP_INSTS=${CLONE_NAMES// /,}
gcloud compute instance-groups unmanaged add-instances "$GROUP_NAME" --instances $COMMA_SEP_INSTS --zone $INSTANCE_ZONE
fi
echo - Waiting for all instnaces to be ready
while `gcloud compute instances list --filter "name=($CLONE_NAMES)" | grep -q STAGING`
do
printf '.'
sleep 5
done
echo ...Ready!
echo - Cleaning up...
gcloud compute instance-templates delete --quiet $INSTANCE_NAME-$RANDGUID
gcloud compute snapshots delete --quiet $INSTANCE_NAME-$RANDGUID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment