Build Google Cloud Infrastructure for AWS Professionals
Solution for Build Google Cloud Infrastructure for AWS Professionals. 1 lab: GSP511. Fast copy-paste commands for Google Cloud.
GSP511 — Build Google Cloud Infrastructure for AWS Professionals: Challenge Lab
Estimated time: 30 minutes
# ☁️ Build Google Cloud Infrastructure for AWS Professionals: Challenge Lab > ⚠️ **Disclaimer:** This is an independent, community-made walkthrough created to help you understand why each step works. Attempt the challenge yourself first. This guide is provided for educational purposes and is not intended to replace the official lab instructions or your own hands-on learning. It is not affiliated with or endorsed by Google Cloud or Google Cloud Skills Boost. Always follow the official Google Clo
GREEN='\e[1;32m'
CYAN='\e[1;36m'
YELLOW='\e[1;33m'
BLUE='\e[1;34m'
MAGENTA='\e[1;35m'
WHITE='\e[1;37m'
RESET='\e[0m'
BOLD='\e[1m'
clear
echo -e "${CYAN}${BOLD}"
cat << "EOF"
____ _ _ _ __ ___
/ __ \ | | (_) | / _| / _ \
| | | |_ __| |__ _| |_ ___ | |_ | | | |_ __ ___
| | | | '__| '_ \| | __| / _ \ | _| | | | | '_ \/ __|
| |__| | | | |_) | | |_ | (_) || | | |_| | |_) \__ \
\____/|_| |_.__/|_|\__| \___/ |_| \___/| .__/|___/
| |
|_|
EOF
echo -e "${RESET}"
echo -e "${BLUE}${BOLD}╔════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${BLUE}${BOLD}║ 🌊 WELCOME TO Orbit Of Ops ║${RESET}"
echo -e "${BLUE}${BOLD}║ 🚀 TARGET: GSP511 AWS PROFESSIONALS CHALLENGE LAB ║${RESET}"
echo -e "${BLUE}${BOLD}╚════════════════════════════════════════════════════════════╝${RESET}\n"
echo -e "${BOLD}${YELLOW}[Orbit of Ops] Auto-fetching Project, Zone, and Region...${RESET}"
export PROJECT_ID=$(gcloud config get-value project 2>/dev/null)
if [[ -z "$PROJECT_ID" ]]; then
export PROJECT_ID=$DEVSHELL_PROJECT_ID
fi
export ZONE=$(gcloud compute project-info describe --format="value(commonInstanceMetadata.items[google-compute-default-zone])" 2>/dev/null | tail -n 1)
if [[ -z "$ZONE" ]]; then
read -p "$(echo -e ${BOLD}${CYAN}"Please enter the lab Zone (e.g., us-east1-c): "${RESET})" ZONE
export ZONE
fi
export REGION=${ZONE%-*}
gcloud config set compute/zone $ZONE 2>/dev/null
gcloud config set compute/region $REGION 2>/dev/null
echo -e "✅ Project ID: ${GREEN}$PROJECT_ID${RESET}"
echo -e "✅ Zone: ${GREEN}$ZONE${RESET}"
echo -e "✅ Region: ${GREEN}$REGION${RESET}\n"
echo -e "${GREEN}${BOLD}▬▬▬▬▬▬ TASK 1 & 2: VPCs & SUBNETS ▬▬▬▬▬▬${RESET}"
echo -e "${YELLOW}[*] Creating griffin-dev-vpc & subnets...${RESET}"
gcloud compute networks create griffin-dev-vpc --subnet-mode=custom --quiet
gcloud compute networks subnets create griffin-dev-wp \
--network=griffin-dev-vpc --region=$REGION --range=192.168.16.0/20 --quiet
gcloud compute networks subnets create griffin-dev-mgmt \
--network=griffin-dev-vpc --region=$REGION --range=192.168.32.0/20 --quiet
echo -e "${YELLOW}[*] Creating griffin-prod-vpc & subnets...${RESET}"
gcloud compute networks create griffin-prod-vpc --subnet-mode=custom --quiet
gcloud compute networks subnets create griffin-prod-wp \
--network=griffin-prod-vpc --region=$REGION --range=192.168.48.0/20 --quiet
gcloud compute networks subnets create griffin-prod-mgmt \
--network=griffin-prod-vpc --region=$REGION --range=192.168.64.0/20 --quiet
echo -e "\n${GREEN}${BOLD}▬▬▬▬▬▬ TASK 3: BASTION HOST ▬▬▬▬▬▬${RESET}"
echo -e "${YELLOW}[*] Deploying Bastion Host (e2-medium)...${RESET}"
gcloud compute instances create bastion \
--zone=$ZONE \
--machine-type=e2-medium \
--network-interface=network=griffin-dev-vpc,subnet=griffin-dev-mgmt \
--network-interface=network=griffin-prod-vpc,subnet=griffin-prod-mgmt \
--tags=ssh --quiet
gcloud compute firewall-rules create fw-ssh-dev \
--network=griffin-dev-vpc --allow=tcp:22 --source-ranges=0.0.0.0/0 --target-tags=ssh --quiet
gcloud compute firewall-rules create fw-ssh-prod \
--network=griffin-prod-vpc --allow=tcp:22 --source-ranges=0.0.0.0/0 --target-tags=ssh --quiet
echo -e "\n${GREEN}${BOLD}▬▬▬▬▬▬ TASK 4: CLOUD SQL (Takes ~5-7 mins) ▬▬▬▬▬▬${RESET}"
gcloud sql instances create griffin-dev-db \
--region=$REGION \
--database-version=MYSQL_5_7 \
--root-password="OrbitOfOpsPassword123!" \
--tier=db-n1-standard-1 --quiet
gcloud sql databases create wordpress --instance=griffin-dev-db --quiet
gcloud sql users create wp_user --instance=griffin-dev-db --password=stormwind_rules --quiet
echo -e "\n${GREEN}${BOLD}▬▬▬▬▬▬ TASK 5: KUBERNETES CLUSTER (Takes ~5-7 mins) ▬▬▬▬▬▬${RESET}"
gcloud container clusters create griffin-dev \
--zone=$ZONE \
--machine-type=e2-standard-4 \
--num-nodes=2 \
--network=griffin-dev-vpc \
--subnetwork=griffin-dev-wp --quiet
echo -e "\n${CYAN}${BOLD}✓ PART 1 COMPLETE! Please run PART 2 to finish the workload deployment.${RESET}\n"GREEN='\e[1;32m'
CYAN='\e[1;36m'
YELLOW='\e[1;33m'
BLUE='\e[1;34m'
MAGENTA='\e[1;35m'
RESET='\e[0m'
BOLD='\e[1m'
export PROJECT_ID=$(gcloud config get-value project)
export ZONE=$(gcloud config get-value compute/zone)
echo -e "${BLUE}${BOLD}====================================================${RESET}"
echo -e "${BLUE}${BOLD} Orbit of Ops: Initiating Part 2 (Workloads) ${RESET}"
echo -e "${BLUE}${BOLD}====================================================${RESET}\n"
echo -e "${GREEN}${BOLD}▬▬▬▬▬▬ TASK 6: KUBERNETES SECRETS ▬▬▬▬▬▬${RESET}"
gcloud container clusters get-credentials griffin-dev --zone=$ZONE --project=$PROJECT_ID --quiet
mkdir -p ~/orbit-wp && cd ~/orbit-wp
gsutil cp -r gs://spls/gsp511/wp-k8s/* .
cat > wp-env.yaml <<EOF
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wordpress-volumeclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
---
apiVersion: v1
kind: Secret
metadata:
name: database
type: Opaque
stringData:
username: wp_user
password: stormwind_rules
EOF
kubectl apply -f wp-env.yaml
echo -e "${YELLOW}[*] Creating Cloud SQL Service Account Key...${RESET}"
gcloud iam service-accounts keys create key.json \
--iam-account=cloud-sql-proxy@$PROJECT_ID.iam.gserviceaccount.com
kubectl create secret generic cloudsql-instance-credentials --from-file key.json
echo -e "\n${GREEN}${BOLD}▬▬▬▬▬▬ TASK 7: WORDPRESS DEPLOYMENT ▬▬▬▬▬▬${RESET}"
INSTANCE_CONNECTION_NAME=$(gcloud sql instances describe griffin-dev-db --format='value(connectionName)')
cat > wp-deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: 127.0.0.1:3306
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: database
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: database
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.33.2
command: ["/cloud_sql_proxy",
"-instances=$INSTANCE_CONNECTION_NAME=tcp:3306",
"-credential_file=/secrets/cloudsql/key.json"]
securityContext:
runAsUser: 2 # non-root user
allowPrivilegeEscalation: false
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress-volumeclaim
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
EOF
kubectl apply -f wp-deployment.yaml
kubectl apply -f wp-service.yaml
echo -e "\n${GREEN}${BOLD}▬▬▬▬▬▬ TASK 8: ENABLE MONITORING ▬▬▬▬▬▬${RESET}"
echo -e "${YELLOW}[*] Waiting for WordPress External IP (Takes ~60 seconds)...${RESET}"
sleep 45
EXTERNAL_IP=""
while [ -z "$EXTERNAL_IP" ]; do
EXTERNAL_IP=$(kubectl get services wordpress -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
if [ -z "$EXTERNAL_IP" ]; then
echo "Still waiting for IP..."
sleep 15
fi
done
echo -e "${CYAN}WordPress IP detected: $EXTERNAL_IP${RESET}"
gcloud monitoring uptime create "Orbit of Ops WP Uptime" \
--resource-type=uptime-url \
--resource-labels=host=$EXTERNAL_IP,path=/,port=80 > /dev/null 2>&1
echo -e "\n${GREEN}${BOLD}▬▬▬▬▬▬ TASK 9: PROVIDE ACCESS TO ADDITIONAL ENGINEER ▬▬▬▬▬▬${RESET}"
CURRENT_USER=$(gcloud config get-value account)
USER_2=$(gcloud projects get-iam-policy $PROJECT_ID --format=json | jq -r '.bindings[] | select(.role == "roles/viewer").members[]' | grep "user:" | grep -v "$CURRENT_USER" | head -n 1)
if [[ -n "$USER_2" ]]; then
echo -e "${CYAN}Auto-detected additional engineer: $USER_2${RESET}"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="$USER_2" \
--role="roles/editor" --quiet
else
echo -e "${MAGENTA}⚠️ Could not automatically detect the second user.${RESET}"
read -p "$(echo -e ${BOLD}${CYAN}"Please enter 'Username 2' from the Qwiklabs panel (Email): "${RESET})" USER_2_MANUAL
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="user:$USER_2_MANUAL" \
--role="roles/editor" --quiet
fi
echo -e "\n${MAGENTA}${BOLD}╔════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${MAGENTA}${BOLD}║ 🎉 AUTOMATION COMPLETED SUCCESSFULLY 🎉 ║${RESET}"
echo -e "${MAGENTA}${BOLD}╚════════════════════════════════════════════════════════════╝${RESET}"