Last active
January 28, 2020 08:37
-
-
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
This file contains 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 | |
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