Published

- 4 min read

มาลองสร้าง Cloud Workstations โดยใช้ gcloud CLI กัน

img of มาลองสร้าง Cloud Workstations โดยใช้ gcloud CLI กัน

เปิด blog ครั้งแรกก็ขออธิบาย steps สั้นๆ เกี่ยวกับการสร้าง Cloud Workstations เพื่อที่จะมาช่วยในการทำงานบน Google Cloud แทนการไป develop ที่ local machine ของตัวเองกันครับ

ประโยชน์ในการใช้ Cloud Workstations คือ บุคคลภายนอกจะไม่สามารถเข้ามาในเครื่อง VM ที่เรากำลังทำงานอยู่ได้ ยกเว้นแต่เพื่อนร่วมงานในบริษัทที่มีสิทธิ์ IAM policies ในการเข้าถึง Workstation นั้นๆ ครับ

ซึ่งเหมาะมากที่จะใช้เครื่อง VM ที่ถูก Cloud Workstations provision เครื่องขึ้นในการทำงานในสภาพแวดล้อมที่ปิดตัวไม่ให้คนนอกเข้าถึง และช่วยในการทำงานในระบบที่ root user ต้องการ run คำสั่ง gcloud บนเครื่อง VM แทนที่จะเป็นเครื่องคอมของตัวเอง เช่น เราอาจเก็บ source code shell scripts ต่างๆ ไว้บน Github ที่เป็น private repository ที่มีแต่เราที่เขาถึงได้คนเดียว (ซึ่งมันก็แล้วแต่ permissions ที่ตั้งไว้ เราอาจจะแชร์คนในทีมให้มีสิทธิ์ IAM เข้าเครื่อง VM อย่างเดียว แต่ไม่ต้องมีสิทธิ์ที่ Github ก็ได้ครับ)

ซึ่งโดย steps การที่เราจะไปถึงตรงนั้นได้เราก็ต้องเริ่มจากการสร้าง project บน GCP ก่อนครับ โดยผมจะเรียง steps ไว้ตามนี้เลย

   #!/bin/bash

echo "#### START ####"

echo "#### CREATE PROJECT ####" &&
. ./local/create-project.sh > /dev/null 2>&1 &&

echo "#### WAITING FOR PROJECT INITIALIZATION... ####" &&
sleep 60 &&

echo "#### SET GCLOUD CONFIG ####" &&
. ./local/set-gcloud-config.sh > /dev/null 2>&1 &&

echo "#### LINK BILLING ACCOUNT ####" &&
. ./local/link-billing-account.sh > /dev/null 2>&1 &&

echo "#### CREATE SERVICE ACCOUNT ####" &&
. ./local/create-service-account.sh > /dev/null 2>&1 &&

echo "#### DOWNLOAD SERVICE ACCOUNT ####" &&
. ./local/download-service-account.sh > /dev/null 2>&1 &&

echo "#### CREATE NETWORK ####" &&
. ./local/create-temp-network.sh > /dev/null 2>&1 &&

echo "#### CREATE FIREWALL ####" &&
. ./local/create-temp-firewall.sh > /dev/null 2>&1 &&

echo "#### CREATE NAT GATEWAY USING CLOUD ROUTER ####" &&
. ./local/create-nat-gateway-using-cloud-router.sh > /dev/null 2>&1 &&

echo "#### CREATE CLOUD WORKSTATION ####" &&
. ./local/create-cloud-workstation.sh > /dev/null 2>&1 &&

echo "#### DONE ####"

ต่อมาจะขอแปะคำสั่งของแต่ script เรียงลงไปนะครับ (ต้องไปแก้ variable ที่อยู่ใน script เอง)

ปล. ผมทำ environment variable เป็น script ตัวกลางในการที่ script อื่นๆ จะสามารถดึงไปใช้ได้นะครับ

create-project.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

gcloud projects create $GCP_PROJECT --name=$GCP_PROJECT_DES_NAME

set-gcloud-config.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# Set GCP default project
gcloud config set project $GCP_PROJECT

# Set GCP default zone
yes | gcloud config set compute/zone $GCP_ZONE

# Enable APIs
yes | gcloud services enable compute.googleapis.com &&
yes | gcloud services enable workstations.googleapis.com &&
yes | gcloud services enable container.googleapis.com &&
yes | gcloud services enable secretmanager.googleapis.com &&
sleep 120 && echo "Enabled APIs!"

link-billing-account.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# Link billing account
gcloud billing projects link $GCP_PROJECT \
  --billing-account=$(gcloud billing accounts list | awk 'NR > 1 {print $1}')

create-service-account.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# https://pnatraj.medium.com/how-to-run-gcloud-command-line-using-a-service-account-f39043d515b9

gcloud iam service-accounts create $GCP_SERVICE_ACCOUNT_NAME

gcloud projects add-iam-policy-binding $GCP_PROJECT --member serviceAccount:$GCP_SERVICE_ACCOUNT_FULL_NAME --role "roles/owner"

download-service-account.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

gcloud iam service-accounts keys create ./creds.json --iam-account $GCP_SERVICE_ACCOUNT_FULL_NAME

create-temp-network.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# Create a network
gcloud compute networks create $GKE_NETWORK_NAME \
  --subnet-mode custom

# Create a subnet and secondary range
gcloud compute networks subnets create $GKE_SUBNET_NAME \
  --region $GCP_REGION \
  --network $GKE_NETWORK_NAME \
  --range 192.168.0.0/20 \
  --secondary-range $GKE_CLUSTER_SECONDARY_RANGE_NAME=10.4.0.0/14,$GKE_SERVICES_SECONDARY_RANGE_NAME=10.0.32.0/20 \
  --enable-private-ip-google-access

create-temp-firewall.sh (ตามหลัก best practice ก็อย่า allow เป็น public อย่างนี้นะครับ ให้เรา allow IP ของ VPN แทน)

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# Create firewall rules
gcloud compute firewall-rules create $GKE_FIREWALL_ALLOW_SSH_RULES_NAME \
  --network $GKE_NETWORK_NAME \
  --source-ranges 0.0.0.0/0 \
  --allow tcp:22

gcloud compute firewall-rules create $GKE_FIREWALL_ALLOW_HTTP_RULES_NAME \
  --network $GKE_NETWORK_NAME \
  --source-ranges 0.0.0.0/0 \
  --allow tcp:80

gcloud compute firewall-rules create $GKE_FIREWALL_ALLOW_HTTPS_RULES_NAME \
  --network $GKE_NETWORK_NAME \
  --source-ranges 0.0.0.0/0 \
  --allow tcp:443

gcloud compute firewall-rules create $FIREWALL_ALLOW_ROOT_CA_NAME \
  --direction INGRESS \
  --priority 1000 \
  --network $GKE_NETWORK_NAME \
  --action ALLOW \
  --rules all \
  --source-service-accounts $GCP_SERVICE_ACCOUNT_FULL_NAME

create-nat-gateway-using-cloud-router.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# Create Cloud Router
gcloud compute routers create $GKE_NAT_CLOUD_ROUTER_NAME \
  --network $GKE_NETWORK_NAME_FULL_PATH \
  --region $GCP_REGION \
  --async

# Add a configuration to the router
gcloud compute routers nats create $GKE_NAT_GATEWAY_NAME \
  --router-region $GCP_REGION \
  --router $GKE_NAT_CLOUD_ROUTER_NAME \
  --nat-all-subnet-ip-ranges \
  --no-enable-dynamic-port-allocation \
  --enable-endpoint-independent-mapping \
  --udp-idle-timeout 30s \
  --tcp-established-idle-timeout 1200s \
  --tcp-transitory-idle-timeout 30s \
  --icmp-idle-timeout 30s \
  --tcp-time-wait-timeout 120s \
  --no-enable-logging \
  --auto-allocate-nat-external-ips \
  --async

create-cloud-workstation.sh

   #!/bin/bash

. $(pwd)/../base/env-vars.sh

# Create Workstation cluster
gcloud workstations clusters create $WORKSTATION_CLUSTER_NAME \
  --labels=workstation=$CONTROL_PLANE_NAME \
  --region=$GCP_REGION \
  --network=$GKE_NETWORK_NAME_FULL_PATH \
  --subnetwork=$GKE_SUBNET_NAME_FULL_PATH

# Create Workstation config
gcloud workstations configs create $WORKSTATION_CONFIG_NAME \
  --labels=workstation=$CONTROL_PLANE_NAME \
  --network-tags=$GKE_NETWORK_NAME \
  --cluster=$WORKSTATION_CLUSTER_NAME \
  --region=$GCP_REGION \
  --replica-zones=asia-southeast1-b,asia-southeast1-a
  --machine-type=e2-standard-4 \
  --container-predefined-image=codeoss \
  --pd-disk-type=pd-standard \
  --pd-disk-size=200 \
  --pd-reclaim-policy=delete \
  --pool-size=0 \
  --idle-timeout=7200 \
  --service-account="$GCP_SERVICE_ACCOUNT_FULL_NAME"

# Create Workstation
gcloud workstations create $WORKSTATION_NAME \
  --cluster=$WORKSTATION_CLUSTER_NAME \
  --config=$WORKSTATION_CONFIG_NAME \
  --region=$GCP_REGION \
  --labels=workstation=$CONTROL_PLANE_NAME

ผลลัพธ์ก็จะออกมาหน้าตาประมาณนี้ครับ

ต่อไปเราก็กดปุ่ม Start แล้วรอ Launch เครื่อง VM กันเลย แต่อาจจะรอนานหน่อยเพราะผมกำหนด Workstation configurations เป็นแบบ cost saving นะครับ (disabled quick start workstations)

พอรันขึ้นมาก็จะได้หน้าตาเครื่องทำงานบน Cloud ประมาณนี้ครับ (โดยทาง Google เลือก Code OSS ให้เป็น base editor นะครับ)

ส่วนนี่ก็จะเป็น Workstation Configuration กับ Workstation Cluster ที่เรา configure ให้มัน provision ขึ้นมาตามที่ได้กำหนดไปครับ

ทั้งหมดทั้งมวลก็น่าจะประมาณนี้ครับ ซึ่งบทความต่อไปน่าจะเป็นเกี่ยวกับเรื่อง Ingress-Nginx กับ ArgoCD และการใช้ cert manager บน GKE cluster ครับ

Ref: https://cloud.google.com/workstations/docs/quickstart-set-up-workstations-console