######################################## 11.4 Compute Engine - Virtual Machines ######################################## .. note:: Google Compute Engine provides scalable, high-performance virtual machines (VMs) running on Google's infrastructure. Compute Engine offers predefined machine types, custom machine types, and the ability to run containers directly on VMs. It's Google Cloud's IaaS offering, equivalent to AWS EC2. ===================== Compute Engine Basics ===================== **Key Features:** - **Predefined Machine Types**: Pre-configured VM configurations for common workloads - **Custom Machine Types**: Create VMs with custom CPU and memory configurations - **Per-Second Billing**: Pay only for the compute time you use - **Sustained Use Discounts**: Automatic discounts for running workloads - **Committed Use Discounts**: Save up to 57% with 1-year or 3-year commitments - **Preemptible VMs**: Low-cost, short-lived instances (up to 80% discount) - **Spot VMs**: Similar to preemptible but with more features - **Live Migration**: No downtime for hardware maintenance - **Global Load Balancing**: Distribute traffic across regions **Machine Families:** 1. **General Purpose** (E2, N2, N2D, N1): - Balanced CPU and memory - Best for web servers, small databases, development environments 2. **Compute Optimized** (C2, C2D): - High CPU-to-memory ratio - Best for compute-intensive workloads, gaming, HPC 3. **Memory Optimized** (M2, M1): - High memory-to-CPU ratio - Best for in-memory databases, SAP HANA 4. **Accelerator Optimized** (A2): - GPU-attached VMs - Best for ML training, HPC, graphics workloads ========================================== Task 1: Create Instance from Cloud Console ========================================== This section walks through creating a VM using the Google Cloud Console. **Step 1: Access Compute Engine** 1. Open Google Cloud Console: https://console.cloud.google.com 2. Navigate to **Navigation menu (☰) → Compute Engine → VM instances** 3. Wait for the Compute Engine API to initialize (first-time setup may take a minute) **Step 2: Create a New Instance** 1. Click **Create Instance** button 2. Configure the instance with following settings: **Basic Configuration:** +------------------+------------------------+--------------------------------------------------------+ | Field | Value | Description | +==================+========================+========================================================+ | Name | gcelab | Name for the VM instance | +------------------+------------------------+--------------------------------------------------------+ | Region | us-central1 | Geographic location for the instance | +------------------+------------------------+--------------------------------------------------------+ | Zone | us-central1-a | Specific zone within the region | +------------------+------------------------+--------------------------------------------------------+ | Machine family | General-purpose | Type of workload the VM is optimized for | +------------------+------------------------+--------------------------------------------------------+ | Series | E2 | Latest generation general-purpose series | +------------------+------------------------+--------------------------------------------------------+ | Machine type | e2-medium | 2 vCPUs, 4 GB memory (customizable) | +------------------+------------------------+--------------------------------------------------------+ .. note:: **About Regions and Zones:** - **Region**: Geographic location (e.g., us-central1, europe-west1) - **Zone**: Isolated location within a region (e.g., us-central1-a, us-central1-b) - Resources in different zones are isolated from failures in other zones - Network latency between zones in the same region is typically < 1ms **Step 3: Configure Boot Disk** 1. Click **OS and storage** section 2. Click **Change** to configure boot disk: +------------------+------------------------+ | Field | Value | +==================+========================+ | Operating system | Debian | +------------------+------------------------+ | Version | Debian GNU/Linux 12 | | | (bookworm) | +------------------+------------------------+ | Boot disk type | Balanced persistent | | | disk | +------------------+------------------------+ | Size (GB) | 10 | +------------------+------------------------+ **Available Operating Systems:** - Debian, Ubuntu, CentOS, RHEL, Rocky Linux - Windows Server (2012, 2016, 2019, 2022) - Container-Optimized OS - Custom images **Boot Disk Types:** - **Standard persistent disk**: Lower cost, lower performance (HDD) - **Balanced persistent disk**: Balance of performance and cost (SSD) - **SSD persistent disk**: High performance, higher cost - **Extreme persistent disk**: Highest performance, highest cost **Step 4: Configure Networking** 1. Expand **Networking** section 2. Under **Firewall**: - ☑ **Allow HTTP traffic** - ☐ Allow HTTPS traffic (optional) .. note:: Selecting "Allow HTTP traffic" automatically creates a firewall rule to allow traffic on port 80. **Step 5: Advanced Options (Optional)** You can configure additional options: - **Management**: Startup scripts, metadata, availability policy - **Security**: Shielded VM options, SSH keys - **Disks**: Additional disks - **Networking**: Multiple network interfaces, IP forwarding **Step 6: Create the Instance** 1. Review your configuration 2. Click **Create** button 3. Wait approximately 1 minute for VM creation **Step 7: Connect via SSH** Once the instance is running: 1. In the VM instances list, find your instance **gcelab** 2. Click **SSH** button in the row 3. A browser-based SSH terminal will open Expected SSH terminal output: .. code-block:: text Linux gcelab 5.10.0-26-cloud-amd64 #1 SMP Debian 5.10.197-1 (2023-09-29) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. user@gcelab:~$ .. tip:: **SSH Connection Methods:** - Browser-based SSH (no SSH client needed) - gcloud command: `gcloud compute ssh gcelab --zone=us-central1-a` - Standard SSH with SSH keys - SSH from Cloud Shell - Third-party SSH clients (PuTTY, MobaXterm, etc.) ================================ Task 2: Install NGINX Web Server ================================ Now you'll install NGINX, a popular web server, on your VM. **Step 1: Update Package Lists** .. code-block:: bash sudo apt-get update Expected output: .. code-block:: text Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [30 B] Get:5 file:/etc/apt/mirrors/debian-security.list Mirrorlist [39 B] Get:7 https://packages.cloud.google.com/apt google-compute-engine-bookworm-stable InRelease [1321 B] Get:2 https://deb.debian.org/debian bookworm InRelease [151 kB] Get:3 https://deb.debian.org/debian bookworm-updates InRelease [55.4 kB] Get:4 https://deb.debian.org/debian bookworm-backports InRelease [59.0 kB] Hit:8 https://packages.cloud.google.com/apt cloud-sdk-bookworm InRelease Hit:6 https://deb.debian.org/debian-security bookworm-security InRelease Fetched 267 kB in 1s (274 kB/s) Reading package lists... Done **Step 2: Install NGINX** .. code-block:: bash sudo apt-get install -y nginx Expected output: .. code-block:: text Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: fontconfig-config fonts-dejavu-core libdeflate0 libfontconfig1 libgd3 libjbig0 libjpeg62-turbo libnginx-mod-http-geoip2 libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libnginx-mod-stream-geoip2 libtiff6 libwebp7 libxslt1.1 nginx-common nginx-core Suggested packages: libgd-tools fcgiwrap nginx-doc ssl-cert The following NEW packages will be installed: fontconfig-config fonts-dejavu-core libdeflate0 libfontconfig1 libgd3 libjbig0 libjpeg62-turbo libnginx-mod-http-geoip2 libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libnginx-mod-stream-geoip2 libtiff6 libwebp7 libxslt1.1 nginx nginx-common nginx-core 0 upgraded, 19 newly installed, 0 to remove and 0 not upgraded. Need to get 3,192 kB of archives. After this operation, 10.2 MB of additional disk space will be used. ... Setting up nginx (1.22.1-9) ... **Step 3: Verify NGINX is Running** .. code-block:: bash ps auwx | grep nginx Expected output: .. code-block:: text root 2330 0.0 0.0 159532 1628 ? Ss 14:06 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; www-data 2331 0.0 0.0 159864 3204 ? S 14:06 0:00 nginx: worker process www-data 2332 0.0 0.0 159864 3204 ? S 14:06 0:00 nginx: worker process user 2342 0.0 0.0 12780 988 pts/0 S+ 14:07 0:00 grep nginx **Step 4: Check NGINX Service Status** .. code-block:: bash sudo systemctl status nginx Expected output: .. code-block:: text ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Wed 2024-01-10 14:06:23 UTC; 2min ago Docs: man:nginx(8) Process: 2315 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 2316 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 2330 (nginx) Tasks: 3 (limit: 4644) Memory: 3.2M CPU: 25ms CGroup: /system.slice/nginx.service ├─2330 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" ├─2331 "nginx: worker process" └─2332 "nginx: worker process" **Step 5: Access the Web Server** 1. Return to the Cloud Console 2. In the VM instances list, find the **External IP** of your instance 3. Click on the External IP link, or open `http://EXTERNAL_IP` in a new browser tab You should see the default NGINX welcome page: .. code-block:: text Welcome to nginx! If you see this page, the nginx web server is successfully installed and working. Further configuration is required. For online documentation and support please refer to nginx.org. Commercial support is available at nginx.com. Thank you for using nginx. **Step 6: Customize the Web Page (Optional)** .. code-block:: bash # Create a custom index.html sudo bash -c 'cat > /var/www/html/index.html << EOF
Hostname: $(hostname)
Internal IP: $(hostname -I)
Zone: $(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone | cut -d/ -f4)
This server is running NGINX on Debian GNU/Linux 12
EOF' # Restart NGINX sudo systemctl restart nginx Now refresh your browser to see the customized page. =========================================== Task 4: Install WordPress on Compute Engine =========================================== This section guides you through installing WordPress, a popular content management system, on a Compute Engine VM with the LAMP stack (Linux, Apache, MySQL, PHP). **Step 1: Create a VM for WordPress** .. code-block:: bash # Create VM with appropriate resources for WordPress gcloud compute instances create wordpress-vm \ --zone=us-central1-a \ --machine-type=e2-medium \ --tags=http-server,https-server \ --image-family=debian-12 \ --image-project=debian-cloud \ --boot-disk-size=20GB # Create firewall rules if they don't exist gcloud compute firewall-rules create allow-http \ --allow=tcp:80 \ --target-tags=http-server \ --description="Allow HTTP traffic" gcloud compute firewall-rules create allow-https \ --allow=tcp:443 \ --target-tags=https-server \ --description="Allow HTTPS traffic" **Step 2: Connect to the Instance** .. code-block:: bash gcloud compute ssh wordpress-vm --zone=us-central1-a **Step 3: Install Apache Web Server** .. code-block:: bash # Update package lists sudo apt-get update # Install Apache sudo apt-get install -y apache2 # Enable and start Apache sudo systemctl enable apache2 sudo systemctl start apache2 # Verify Apache is running sudo systemctl status apache2 **Expected Apache Status Output:** .. code-block:: text ● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; preset: enabled) Active: active (running) since Thu 2024-01-11 10:30:15 UTC; 5s ago Docs: https://httpd.apache.org/docs/2.4/ Main PID: 1234 (apache2) Tasks: 55 (limit: 4644) Memory: 12.5M CPU: 85ms CGroup: /system.slice/apache2.service ├─1234 /usr/sbin/apache2 -k start ├─1235 /usr/sbin/apache2 -k start └─1236 /usr/sbin/apache2 -k start **Step 4: Install MySQL (MariaDB)** .. code-block:: bash # Install MariaDB (MySQL-compatible database) sudo apt-get install -y mariadb-server mariadb-client # Start and enable MariaDB sudo systemctl enable mariadb sudo systemctl start mariadb # Secure MySQL installation sudo mysql_secure_installation **MySQL Secure Installation Prompts:** .. code-block:: text Enter current password for root (enter for none): [Press Enter] Switch to unix_socket authentication [Y/n]: n Change the root password? [Y/n]: Y New password: [Enter a strong password] Re-enter new password: [Re-enter password] Remove anonymous users? [Y/n]: Y Disallow root login remotely? [Y/n]: Y Remove test database and access to it? [Y/n]: Y Reload privilege tables now? [Y/n]: Y .. warning:: **Important:** Remember the MySQL root password you set. You'll need it for creating the WordPress database. **Step 5: Create WordPress Database** .. code-block:: bash # Log in to MySQL sudo mysql -u root -p In the MySQL prompt, run the following commands: .. code-block:: sql -- Create database for WordPress CREATE DATABASE wordpress_db; -- Create user for WordPress CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'strong_password_here'; -- Grant privileges to the user GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'localhost'; -- Flush privileges FLUSH PRIVILEGES; -- Verify database creation SHOW DATABASES; -- Exit MySQL EXIT; **Expected Output:** .. code-block:: text MariaDB [(none)]> CREATE DATABASE wordpress_db; Query OK, 1 row affected (0.001 sec) MariaDB [(none)]> CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'strong_password_here'; Query OK, 0 rows affected (0.002 sec) MariaDB [(none)]> GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'localhost'; Query OK, 0 rows affected (0.001 sec) MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.001 sec) .. note:: Replace `'strong_password_here'` with a secure password. Save this password as you'll need it for WordPress configuration. **Step 6: Install PHP and Required Extensions** .. code-block:: bash # Install PHP and necessary extensions for WordPress sudo apt-get install -y php php-mysql php-curl php-gd php-xml php-mbstring php-xmlrpc php-zip php-soap php-intl # Verify PHP installation php -v **Expected PHP Version Output:** .. code-block:: text PHP 8.2.7 (cli) (built: Jun 9 2023 19:37:27) (NTS) Copyright (c) The PHP Group Zend Engine v4.2.7, Copyright (c) Zend Technologies with Zend OPcache v8.2.7, Copyright (c), by Zend Technologies **Step 7: Configure PHP for Apache** .. code-block:: bash # Restart Apache to load PHP module sudo systemctl restart apache2 # Create a test PHP file echo "" | sudo tee /var/www/html/info.php # Test PHP by accessing http://EXTERNAL_IP/info.php in browser # You should see PHP configuration information **Step 8: Download and Install WordPress** .. code-block:: bash # Navigate to temporary directory cd /tmp # Download latest WordPress wget https://wordpress.org/latest.tar.gz # Extract WordPress tar -xzf latest.tar.gz # Copy WordPress files to web root sudo cp -r wordpress/* /var/www/html/ # Remove default index.html sudo rm /var/www/html/index.html # Set proper ownership sudo chown -R www-data:www-data /var/www/html/ # Set proper permissions sudo find /var/www/html/ -type d -exec chmod 755 {} \; sudo find /var/www/html/ -type f -exec chmod 644 {} \; **Expected Output:** .. code-block:: text --2024-01-11 10:35:22-- https://wordpress.org/latest.tar.gz Resolving wordpress.org (wordpress.org)... 198.143.164.252 Connecting to wordpress.org (wordpress.org)|198.143.164.252|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 24123456 (23M) [application/octet-stream] Saving to: 'latest.tar.gz' latest.tar.gz 100%[===================>] 23.01M 50.2MB/s in 0.5s 2024-01-11 10:35:23 (50.2 MB/s) - 'latest.tar.gz' saved [24123456/24123456] **Step 9: Configure WordPress** .. code-block:: bash # Create WordPress configuration file from sample sudo cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php # Edit the configuration file sudo nano /var/www/html/wp-config.php Update the following lines with your database credentials: .. code-block:: php // ** Database settings ** // /** The name of the database for WordPress */ define( 'DB_NAME', 'wordpress_db' ); /** Database username */ define( 'DB_USER', 'wordpress_user' ); /** Database password */ define( 'DB_PASSWORD', 'strong_password_here' ); /** Database hostname */ define( 'DB_HOST', 'localhost' ); /** Database charset to use in creating database tables. */ define( 'DB_CHARSET', 'utf8' ); /** The database collate type. Don't change this if in doubt. */ define( 'DB_COLLATE', '' ); **Step 10: Generate Security Keys** .. code-block:: bash # Generate unique authentication keys curl -s https://api.wordpress.org/secret-key/1.1/salt/ Copy the output and replace the following section in `wp-config.php`: .. code-block:: php define('AUTH_KEY', 'put your unique phrase here'); define('SECURE_AUTH_KEY', 'put your unique phrase here'); define('LOGGED_IN_KEY', 'put your unique phrase here'); define('NONCE_KEY', 'put your unique phrase here'); define('AUTH_SALT', 'put your unique phrase here'); define('SECURE_AUTH_SALT', 'put your unique phrase here'); define('LOGGED_IN_SALT', 'put your unique phrase here'); define('NONCE_SALT', 'put your unique phrase here'); Save and close the file (Ctrl+X, then Y, then Enter). **Step 11: Complete WordPress Installation via Web Interface** 1. Get your VM's external IP: .. code-block:: bash # From Cloud Console, or run: gcloud compute instances describe wordpress-vm \ --zone=us-central1-a \ --format='get(networkInterfaces[0].accessConfigs[0].natIP)' 2. Open your browser and navigate to: `http://EXTERNAL_IP` 3. You'll see the WordPress installation wizard. Fill in the details: - **Site Title**: Your website name - **Username**: Admin username (don't use 'admin') - **Password**: Strong password - **Your Email**: Your email address - Click **Install WordPress** 4. Once installation is complete, log in with your credentials. **Step 12: Configure Apache Virtual Host (Optional but Recommended)** .. code-block:: bash # Create virtual host configuration sudo nano /etc/apache2/sites-available/wordpress.conf Add the following configuration: .. code-block:: apacheHostname: $(hostname)
HTML systemctl start nginx EOF # Create VM with script gcloud compute instances create scripted-vm \ --zone=us-central1-a \ --metadata-from-file=startup-script=startup-script.sh ======================== VM Management Operations ======================== **List Instances:** .. code-block:: bash # List all instances gcloud compute instances list # List instances in specific zone gcloud compute instances list --filter="zone:us-central1-a" # List with custom format gcloud compute instances list \ --format="table(name,zone,machineType,status,networkInterfaces[0].accessConfigs[0].natIP:label=EXTERNAL_IP)" **Get Instance Details:** .. code-block:: bash gcloud compute instances describe gcelab --zone=us-central1-a **Stop Instance:** .. code-block:: bash gcloud compute instances stop gcelab --zone=us-central1-a **Start Instance:** .. code-block:: bash gcloud compute instances start gcelab --zone=us-central1-a **Reset Instance (Hard reboot):** .. code-block:: bash gcloud compute instances reset gcelab --zone=us-central1-a **Delete Instance:** .. code-block:: bash gcloud compute instances delete gcelab --zone=us-central1-a **Delete Multiple Instances:** .. code-block:: bash gcloud compute instances delete gcelab gcelab2 --zone=us-central1-a ================================ Instance Metadata and Attributes ================================ **Set Instance Metadata:** .. code-block:: bash # Set metadata gcloud compute instances add-metadata gcelab \ --zone=us-central1-a \ --metadata=environment=production,owner=alice **Access Metadata from Instance:** .. code-block:: bash # SSH into instance and query metadata server curl -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/ # Get specific metadata curl -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/name curl -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/zone curl -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/attributes/environment **Add Network Tags:** .. code-block:: bash gcloud compute instances add-tags gcelab \ --zone=us-central1-a \ --tags=web-server,production **Set Instance Labels:** .. code-block:: bash gcloud compute instances add-labels gcelab \ --zone=us-central1-a \ --labels=env=prod,team=backend =============== Disk Management =============== **Create Additional Disk:** .. code-block:: bash gcloud compute disks create data-disk \ --size=100GB \ --type=pd-ssd \ --zone=us-central1-a **Attach Disk to Instance:** .. code-block:: bash gcloud compute instances attach-disk gcelab \ --disk=data-disk \ --zone=us-central1-a **Mount Disk (From Within Instance):** .. code-block:: bash # List disks sudo lsblk # Format disk (only needed first time) sudo mkfs.ext4 -F /dev/sdb # Create mount point sudo mkdir -p /mnt/data # Mount disk sudo mount /dev/sdb /mnt/data # Make permanent (add to /etc/fstab) echo "/dev/sdb /mnt/data ext4 defaults 0 0" | sudo tee -a /etc/fstab **Detach Disk:** .. code-block:: bash # Must stop instance first (or unmount disk) gcloud compute instances detach-disk gcelab \ --disk=data-disk \ --zone=us-central1-a **Create Disk Snapshot:** .. code-block:: bash gcloud compute disks snapshot data-disk \ --zone=us-central1-a \ --snapshot-names=data-disk-snapshot-$(date +%Y%m%d) **Create Disk from Snapshot:** .. code-block:: bash gcloud compute disks create restored-disk \ --source-snapshot=data-disk-snapshot-20240110 \ --zone=us-central1-a ============================= Instance Templates and Groups ============================= **Create Instance Template:** .. code-block:: bash gcloud compute instance-templates create web-server-template \ --machine-type=e2-medium \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=http-server \ --metadata=startup-script='#!/bin/bash apt-get update apt-get install -y nginx systemctl start nginx' **Create Managed Instance Group:** .. code-block:: bash gcloud compute instance-groups managed create web-server-group \ --base-instance-name=web-server \ --template=web-server-template \ --size=3 \ --zone=us-central1-a **Set Autoscaling:** .. code-block:: bash gcloud compute instance-groups managed set-autoscaling web-server-group \ --zone=us-central1-a \ --max-num-replicas=10 \ --min-num-replicas=2 \ --target-cpu-utilization=0.75 ============== Best Practices ============== **1. Use Appropriate Machine Types:** - Start small and scale up based on metrics - Use custom machine types for specific requirements - Consider preemptible/spot VMs for fault-tolerant workloads **2. Implement Proper Backup Strategy:** .. code-block:: bash # Create regular snapshots gcloud compute disks snapshot DISK_NAME \ --zone=ZONE \ --snapshot-names=backup-$(date +%Y%m%d-%H%M%S) **3. Use Startup Scripts:** .. code-block:: bash # Automate configuration with startup scripts gcloud compute instances create my-vm \ --metadata=startup-script='#!/bin/bash # Your automation here' **4. Tag and Label Resources:** .. code-block:: bash # Use tags for firewall rules # Use labels for billing and organization gcloud compute instances create my-vm \ --tags=web-server,production \ --labels=env=prod,team=backend,cost-center=engineering **5. Monitor Your Instances:** .. code-block:: bash # Enable OS Login for better audit trails gcloud compute project-info add-metadata \ --metadata=enable-oslogin=TRUE # Enable guest attributes gcloud compute instances add-metadata INSTANCE_NAME \ --metadata=enable-guest-attributes=TRUE =============== Troubleshooting =============== **Cannot SSH to Instance:** .. code-block:: bash # Check firewall rules gcloud compute firewall-rules list --filter="targetTags:ssh-access" # Check if instance is running gcloud compute instances describe INSTANCE_NAME --zone=ZONE # Reset SSH keys gcloud compute config-ssh **Instance Not Starting:** .. code-block:: bash # Check serial port output for boot errors gcloud compute instances get-serial-port-output INSTANCE_NAME \ --zone=ZONE **Disk Space Issues:** .. code-block:: bash # Check disk usage df -h # Find large files sudo du -h --max-depth=1 / | sort -hr | head -20 ======= Cleanup ======= .. code-block:: bash # Delete instances gcloud compute instances delete gcelab gcelab2 --zone=us-central1-a --quiet # Delete disks gcloud compute disks delete data-disk --zone=us-central1-a --quiet # Delete instance template gcloud compute instance-templates delete web-server-template --quiet # Delete instance group gcloud compute instance-groups managed delete web-server-group --zone=us-central1-a --quiet ==================== Additional Resources ==================== - Compute Engine Documentation: https://cloud.google.com/compute/docs - Machine Types: https://cloud.google.com/compute/docs/machine-types - Images: https://cloud.google.com/compute/docs/images - Instance Templates: https://cloud.google.com/compute/docs/instance-templates - Managed Instance Groups: https://cloud.google.com/compute/docs/instance-groups