Deploy and Manage Applications on Google App Engine

Solution for Deploy and Manage Applications on Google App Engine. 1 lab: ARC112. Fast copy-paste commands for Google Cloud.

ARC112 — Deploy and Manage Applications on Google App Engine: Challenge Lab

Estimated time: 30 minutes

# 🚀 App Engine: Qwik Start - Challenge Lab > ⚠️ **Disclaimer:** This guide is provided for educational and learning purposes only. It is intended to help you understand Google Cloud App Engine, application deployment, API configuration, regions, application environments, and App Engine services while preparing for Google Cloud certifications and hands-on Challenge Labs. Always follow the official Google Cloud and Google Cloud Skills Boost/Qwiklabs instructions and applicable terms of service.

#!/bin/bash
# ============================================================================
# ARC112 — App Engine Challenge Lab  |  PHP Pivot Automation Script
# Tasks: Clone on VM → Deploy → Update → Redeploy
# ============================================================================
set +H
clear

RED='\e[1;31m'
GREEN='\e[1;32m'
YELLOW='\e[1;33m'
BLUE='\e[1;34m'
MAGENTA='\e[1;35m'
CYAN='\e[1;36m'
BOLD='\e[1m'
RESET='\e[0m'

header()  { echo -e "\n${BLUE}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"; \
            echo -e   "${BLUE}${BOLD}  $1${RESET}"; \
            echo -e   "${BLUE}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"; }
step()    { echo -e "\n${CYAN}${BOLD}▶ $1${RESET}"; }
ok()      { echo -e   "${GREEN}${BOLD}  ✔ $1${RESET}"; }
info()    { echo -e   "${YELLOW}     $1${RESET}"; }
warn()    { echo -e   "${YELLOW}${BOLD}  ⚠  $1${RESET}"; }
die()     { echo -e   "${RED}${BOLD}  ✘  FATAL: $1${RESET}"; exit 1; }

echo -e "${CYAN}${BOLD}"
echo "  ____       _     _ _            __    ___            "
echo " / __ \     | |   (_) |          / _|  / _ \           "
echo "| |  | |_ __| |__  _| |_   ___  | |_  | | | |_ __  ___ "
echo "| |  | | '__| '_ \| | __| / _ \ |  _| | | | | '_ \/ __|"
echo "| |__| | |  | |_) | | |_ | (_) || |   | |_| | |_) \__ \\"
echo " \____/|_|  |_.__/|_|\__| \___/ |_|    \___/| .__/|___/"
echo "                                            | |        "
echo "                                            |_|        "
echo -e "${RESET}"
echo -e "${MAGENTA}${BOLD}  🚀 Full PHP Automation — Tasks 1, 2 & 3${RESET}\n"

# ============================================================================
# STEP 0 — User Input & Credentials
# ============================================================================
header "Step 0 — User Input & Auto-detecting Lab Credentials"

echo -ne "${CYAN}${BOLD}  Enter the new greeting message for Task 3 (e.g. Welcome to this world!): ${RESET}"
read -r TARGET_MESSAGE
[[ -z "$TARGET_MESSAGE" ]] && die "A target message is required to pass Task 3."

PROJECT_ID=$(gcloud config get-value project 2>/dev/null | grep -v '(unset)' || true)
[[ -z "$PROJECT_ID" ]] && PROJECT_ID="${DEVSHELL_PROJECT_ID:-}"
gcloud config set project "$PROJECT_ID" --quiet 2>/dev/null

step "Detecting zone from VM 'lab-setup'..."
ZONE=$(gcloud compute instances list --filter="name=lab-setup" --format="value(zone)" --limit=1 2>/dev/null | head -n1 || true)

if [[ -z "$ZONE" ]]; then
    ZONE_META=$(curl -sf -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/zone" 2>/dev/null | awk -F'/' '{print $NF}' || true)
    ZONE="${ZONE_META:-}"
fi

if [[ -z "$ZONE" ]]; then
    echo -ne "${CYAN}${BOLD}  Could not auto-detect zone. Enter it manually: ${RESET}"
    read -r ZONE
fi

REGION="${ZONE%-*}"
APP_ENGINE_REGION="${ZONE%-*}"

gcloud config set compute/zone "$ZONE" --quiet 2>/dev/null
gcloud config set compute/region "$REGION" --quiet 2>/dev/null

info "Target Message    → ${GREEN}${BOLD}${TARGET_MESSAGE}${RESET}"
info "Project ID        → ${GREEN}${BOLD}${PROJECT_ID}${RESET}"
info "Zone              → ${GREEN}${BOLD}${ZONE}${RESET}"
info "App Engine Region → ${GREEN}${BOLD}${APP_ENGINE_REGION}${RESET}"

# ============================================================================
# TASK 1 — Enable API & Clone PHP Repo on VM
# ============================================================================
header "Task 1 — Enable API & Download PHP App on VM"

step "Enabling App Engine Admin API..."
gcloud services enable appengine.googleapis.com --quiet
sleep 10
ok "API enabled"

step "Cloning php-docs-samples on VM 'lab-setup' (satisfies Task 1 grader)..."
gcloud compute ssh lab-setup \
    --zone="$ZONE" \
    --quiet \
    --command="rm -rf \$HOME/php-docs-samples && git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git" >/dev/null 2>&1
ok "PHP app successfully mirrored to VM lab-setup ✓"

# ============================================================================
# TASK 2 — Configure + Deploy to App Engine
# ============================================================================
header "Task 2 — Configure & Deploy PHP App"

step "Preparing local PHP source in Cloud Shell..."
cd ~
rm -rf php-docs-samples
git clone --quiet https://github.com/GoogleCloudPlatform/php-docs-samples.git
APP_DIR="$HOME/php-docs-samples/appengine/standard/helloworld"
cd "$APP_DIR" || die "Could not cd into PHP directory"

step "Updating runtime and appending scaling limit to app.yaml..."
printf '\nautomatic_scaling:\n  max_instances: 1\n' >> app.yaml
sed -i 's/php81/php83/g' app.yaml
ok "app.yaml updated"

step "Creating App Engine application in region '${APP_ENGINE_REGION}'..."
gcloud app create --region="$APP_ENGINE_REGION" --project="$PROJECT_ID" --quiet 2>/dev/null || true
ok "App Engine app ready"

step "Deploying initial PHP application (~2 min)..."
gcloud app deploy --project="$PROJECT_ID" --quiet
ok "Initial deployment complete!"

DEPLOYED_VERSION=$(gcloud app versions list --project="$PROJECT_ID" --service=default --sort-by="~version.createTime" --format="value(id)" --limit=1 2>/dev/null || true)

# ============================================================================
# TASK 3 — Update Code & Redeploy
# ============================================================================
header "Task 3 — Update Code & Redeploy (${TARGET_MESSAGE})"

step "Overwriting index.php with the requested message..."
cat <<EOF > index.php
<?php
echo '${TARGET_MESSAGE}';
?>
EOF
ok "index.php safely overwritten"

step "Redeploying over version '${DEPLOYED_VERSION}'..."
if [[ -n "$DEPLOYED_VERSION" ]]; then
    gcloud app deploy --version="$DEPLOYED_VERSION" --project="$PROJECT_ID" --quiet
else
    gcloud app deploy --project="$PROJECT_ID" --quiet
fi

APP_URL=$(gcloud app describe --project="$PROJECT_ID" --format="value(defaultHostname)" 2>/dev/null || true)
ok "Updated PHP app deployed — '${TARGET_MESSAGE}' is now live!"

# ============================================================================
# COMPLETION
# ============================================================================
echo ""
echo -e "${MAGENTA}${BOLD}╔══════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${MAGENTA}${BOLD}║          🎉  ARC112  AUTOMATION  COMPLETE  🎉                ║${RESET}"
echo -e "${MAGENTA}${BOLD}╚══════════════════════════════════════════════════════════════╝${RESET}"
echo -e "  ${GREEN}${BOLD}✔ Task 1${RESET}  PHP App downloaded on VM lab-setup via SSH"
echo -e "  ${GREEN}${BOLD}✔ Task 2${RESET}  PHP Hello World deployed to App Engine (${ZONE%-*})"
echo -e "  ${GREEN}${BOLD}✔ Task 3${RESET}  '${TARGET_MESSAGE}' redeployed"
[[ -n "${APP_URL:-}" ]] && echo -e "  ${CYAN}${BOLD}Live App URL${RESET}    → https://${APP_URL}"
echo -e "\n${YELLOW}${BOLD}  👉 Now click all 3 'Check my progress' buttons in the lab manual.${RESET}"