Skip to content

Instantly share code, notes, and snippets.

@unicornware
Last active March 27, 2023 05:49
Show Gist options
  • Save unicornware/34d6f4678232ee4bd99cad861209577b to your computer and use it in GitHub Desktop.
Save unicornware/34d6f4678232ee4bd99cad861209577b to your computer and use it in GitHub Desktop.
Virtual Machine Setup - Ubuntu LTS
#! /bin/sh
# Virtual Machine - Initialization Workflow
#
# Reserves a static IP address and creates a virtual machine instance.
#
# Creates record sets for $TLD, *.$TLD, and *.dev.$TLD afterwards.
#
# Prerequisites:
#
# brew install --cask google-cloud-sdk
# export CLOUDSDK_CORE_PROJECT=<project-name>
# export CLOUDSDK_CORE_ACCOUNT=$CLOUDSDK_CORE_PROJECT@$CLOUDSDK_CORE_PROJECT.iam.gserviceaccount.com
# gcloud iam service-accounts create $CLOUDSDK_CORE_PROJECT
# gcloud dns managed-zones create $CLOUDSDK_CORE_PROJECT --description="" --dns-name=$TLD
#
# Usage:
#
# export CLOUDSDK_COMPUTE_REGION=<region>
# export CLOUDSDK_COMPUTE_ZONE=<zone>
# export CLOUDSDK_CORE_PROJECT=<project-name>
# export CLOUDSDK_CORE_ACCOUNT=$CLOUDSDK_CORE_PROJECT@$CLOUDSDK_CORE_PROJECT.iam.gserviceaccount.com
# export NETWORK_TIER=[network-tier]
# export TLD=<top-level-domain>
# bash ./scripts/vm/init.sh <vm-name>
#
# References:
#
# - https://cloud.google.com/compute/docs/containers/configuring-options-to-run-containers#publishing_container_ports
# - https://cloud.google.com/sdk/gcloud/reference
# - https://cloud.google.com/sdk/gcloud/reference/dns/managed-zones/create
# - https://formulae.brew.sh/cask/google-cloud-sdk
# ensure CLOUDSDK_CORE_ACCOUNT is set and non-empty
[[ -z "${CLOUDSDK_CORE_ACCOUNT}" ]] && echo "\$CLOUDSDK_CORE_ACCOUNT required." && exit 1
# ensure CLOUDSDK_CORE_PROJECT is set and non-empty
[[ -z "${CLOUDSDK_CORE_PROJECT}" ]] && echo "\$CLOUDSDK_CORE_PROJECT required." && exit 1
# ensure CLOUDSDK_COMPUTE_REGION is set and non-empty
[[ -z "${CLOUDSDK_COMPUTE_REGION}" ]] && echo "\$CLOUDSDK_COMPUTE_REGION required." && exit 1
# ensure CLOUDSDK_COMPUTE_ZONE is set and non-empty
[[ -z "${CLOUDSDK_COMPUTE_ZONE}" ]] && echo "\$CLOUDSDK_COMPUTE_ZONE required." && exit 1
# ensure TLD is set and non-empty
[[ -z "${TLD}" ]] && echo "\$TLD required." && exit 1
# ensure virtual machine name was passed
[[ -z "$1" ]] && echo "virtual machine name required." && exit 1
# network tier to configure instance and assign to the reserved ip addresses
NETWORK_TIER=${NETWORK_TIER:-STANDARD}
# reserve static ip address
# https://cloud.google.com/sdk/gcloud/reference/compute/addresses/create
gcloud compute addresses create $1 --network-tier=$NETWORK_TIER
# static ip address
IP_ADDRESS=$(gcloud compute addresses list --filter="name=$1" --format="value(address_range())")
# create virtual machine
# https://cloud.google.com/sdk/gcloud/reference/compute/instances/create
gcloud compute instances create $1 \
--create-disk=auto-delete=yes,boot=yes,device-name=$1,image=projects/ubuntu-os-cloud/global/images/ubuntu-2204-jammy-v20230302,mode=rw,size=10,type=projects/$CLOUDSDK_CORE_PROJECT/zones/us-east4-a/diskTypes/pd-balanced \
--deletion-protection \
--enable-display-device \
--hostname=$TLD \
--labels=ec-src=vm_add-gcloud \
--machine-type=e2-micro \
--maintenance-policy=MIGRATE \
--metadata=hostname=$TLD,google-logging-enabled=true,google-monitoring-enabled=true,enable-oslogin=TRUE \
--metadata-from-file=startup-script=./scripts/vm/startup-script.sh \
--network-interface=address=$IP_ADDRESS,network-tier=$NETWORK_TIER,subnet=default \
--provisioning-model=STANDARD \
--reservation-affinity=any \
--scopes=cloud-platform,compute-rw,default,monitoring,sql-admin,storage-full \
--service-account=$CLOUDSDK_CORE_ACCOUNT \
--shielded-integrity-monitoring \
--shielded-secure-boot \
--shielded-vtpm \
--tags=http-server,https-server
# upsert record sets for top level domain and subdomains
# https://cloud.google.com/sdk/gcloud/reference/dns/record-sets/create
# https://cloud.google.com/sdk/gcloud/reference/dns/record-sets/update
# https://linuxize.com/post/how-to-check-if-string-contains-substring-in-bash
for domain in $(echo "$TLD,*.$TLD,*.dev.$TLD" | tr "," "\n"); do
RECORD_SETS=$(gcloud dns record-sets list --name=$domain --type=A --zone=$CLOUDSDK_CORE_PROJECT)
if [[ $RECORD_SETS == *$domain* ]]; then
gcloud dns record-sets update $domain \
--rrdatas=$IP_ADDRESS \
--type=A \
--zone=$CLOUDSDK_CORE_PROJECT
else
gcloud dns record-sets create $domain \
--rrdatas=$IP_ADDRESS \
--ttl=300 \
--type=A \
--zone=$CLOUDSDK_CORE_PROJECT
fi
done
# restart virtual machine
# https://cloud.google.com/sdk/gcloud/reference/compute/instances/start
# https://cloud.google.com/sdk/gcloud/reference/compute/instances/stop
gcloud compute instances stop $1
gcloud compute instances start $1
#! /bin/sh
# Virtual Machine - Startup Script
#
# Prerequisites:
#
# export CLOUDSDK_CORE_PROJECT=<project-name>
# export CLOUDSDK_PYTHON=python2
# export IAM_POLICY_MEMBER=serviceAccount:$CLOUDSDK_CORE_ACCOUNT
# gcloud projects add-iam-policy-binding --member=$IAM_POLICY_MEMBER --role=roles/storage.admin
# gcloud storage buckets create gs://$(gcloud config get project)
# gcloud storage cp .env.vm gs://$(gcloud config get project)/etc/profile.d/env.sh
# gcloud storage cp docker-cloud.yml gs://$(gcloud config get project)/app/docker-compose.yml
#
# References:
#
# - https://cloud.google.com/sdk/gcloud/reference/projects/add-iam-policy-binding
# - https://cloud.google.com/sdk/gcloud/reference/storage/buckets/create
# - https://cloud.google.com/sdk/gcloud/reference/storage/cp
# - https://cloud.google.com/storage/docs/access-control/iam-permissions
# - https://docs.docker.com/engine/reference/commandline/compose_up
# - https://mkyong.com/linux/how-to-set-environment-variable-in-ubuntu
# - https://webdock.io/en/docs/how-guides/docker-guides/how-to-install-and-run-docker-containers-using-docker-compose
WORKDIR=app
CLOUDSDK_CORE_PROJECT=$(gcloud config get project)
DOCKER_COMPOSE_FILE=$WORKDIR/docker-compose.yml
DOCKER_DOWNLOAD_URL=https://download.docker.com/linux/ubuntu
ENVIRONMENT_FILE=/etc/profile.d/env.sh
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install ca-certificates -y
sudo apt-get install curl -y
sudo apt-get install gnupg -y
sudo apt-get install lsb-release -y
mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL $DOCKER_DOWNLOAD_URL/gpg | sudo gpg --dearmor --output /etc/apt/keyrings/docker.gpg --yes
echo deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] $DOCKER_DOWNLOAD_URL $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt-get update
sudo apt-get install containerd.io -y
sudo apt-get install docker-buildx-plugin -y
sudo apt-get install docker-ce -y
sudo apt-get install docker-ce-cli -y
sudo apt-get install docker-compose-plugin -y
sudo chmod 666 /var/run/docker.sock
sudo usermod -aG docker $USER
grep docker /etc/group
sudo gcloud storage cp gs://$CLOUDSDK_CORE_PROJECT$ENVIRONMENT_FILE $ENVIRONMENT_FILE
sudo chmod 666 $ENVIRONMENT_FILE
cp $ENVIRONMENT_FILE $WORKDIR/.env
echo "DOCKER_COMPOSE_FILE=$DOCKER_COMPOSE_FILE" >>$ENVIRONMENT_FILE
echo "ENVIRONMENT_FILE=$ENVIRONMENT_FILE" >>$ENVIRONMENT_FILE
echo "IP=$(dig +short myip.opendns.com @resolver1.opendns.com)" >>$ENVIRONMENT_FILE
echo "WORKDIR=$WORKDIR" >>$ENVIRONMENT_FILE
gcloud storage cp gs://$CLOUDSDK_CORE_PROJECT/$DOCKER_COMPOSE_FILE $DOCKER_COMPOSE_FILE
touch $WORKDIR/acme.json
chmod 600 $WORKDIR/acme.json
docker compose --project-directory $WORKDIR up --detach
@unicornware
Copy link
Author

unicornware commented Jan 26, 2022

ssh configuration example:

# ~/.ssh/config

Include config.vscode

Host bitbucket.org
  HostName bitbucket.org
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes
  User git

Host github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes
  User git
# ~/.ssh/config.vscode

Host <DOMAIN_NAME>
  HostName <VM_IP_ADDRESS>
  IdentityFile ~/.ssh/ubuntu_rsa
  IdentitiesOnly yes
  User ubuntu

@unicornware
Copy link
Author

clear local dns cache (macOS): sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder

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