GCP for DevOps — Managed Instance Groups

4 minute read

Managed Instance Groups

A Managed Instance Group (MIG) is a group of identical VM instances that GCE manages as a single entity. MIGs provide auto-scaling, auto-healing, rolling updates, and load balancing integration.

MIG Architecture

┌─────────────────────────────────────────────────────┐
│              Managed Instance Group (MIG)            │
│                                                     │
│  ┌──────────────────────────────────────┐           │
│  │       Instance Template              │           │
│  │  machine-type: e2-standard-2         │           │
│  │  image: devops-base-v1               │           │
│  │  startup-script: deploy.sh           │           │
│  └──────────────────┬───────────────────┘           │
│                     │ creates                       │
│         ┌───────────┼───────────┐                   │
│         │           │           │                   │
│    ┌────▼────┐ ┌────▼────┐ ┌────▼────┐             │
│    │  VM-1   │ │  VM-2   │ │  VM-3   │             │
│    │ (auto)  │ │ (auto)  │ │ (auto)  │             │
│    └─────────┘ └─────────┘ └─────────┘             │
│                                                     │
│  Auto-scaler: min=2, max=10, target CPU=60%         │
│  Auto-healer: health check every 30s               │
│  Update policy: rolling, max-surge=1                │
└─────────────────────────────────────────────────────┘

Step 1: Create an Instance Template

# Create an instance template
$ gcloud compute instance-templates create web-template \
    --machine-type=e2-standard-2 \
    --image-family=debian-12 \
    --image-project=debian-cloud \
    --boot-disk-size=20GB \
    --boot-disk-type=pd-balanced \
    --tags=http-server,health-check \
    --service-account=web-sa@my-project.iam.gserviceaccount.com \
    --scopes=cloud-platform \
    --metadata-from-file=startup-script=startup.sh

Created [web-template].

# List templates
$ gcloud compute instance-templates list

NAME            MACHINE_TYPE    PREEMPTIBLE  CREATION_TIMESTAMP
web-template    e2-standard-2               2026-03-30T12:00:00.000-07:00

Step 2: Create a Managed Instance Group

# Create a zonal MIG
$ gcloud compute instance-groups managed create web-mig \
    --zone=us-central1-a \
    --template=web-template \
    --size=3

Created [web-mig].
NAME     LOCATION       SCOPE  BASE_INSTANCE_NAME  SIZE  TARGET_SIZE  INSTANCE_TEMPLATE  AUTOSCALED
web-mig  us-central1-a  zone   web-mig             3     3            web-template       no

# Create a regional MIG (spans multiple zones — higher availability)
$ gcloud compute instance-groups managed create web-mig-regional \
    --region=us-central1 \
    --template=web-template \
    --size=6 \
    --zones=us-central1-a,us-central1-b,us-central1-c

Step 3: Configure Auto-Scaling

# Set up auto-scaling based on CPU utilization
$ gcloud compute instance-groups managed set-autoscaling web-mig \
    --zone=us-central1-a \
    --min-num-replicas=2 \
    --max-num-replicas=10 \
    --target-cpu-utilization=0.60 \
    --cool-down-period=60

Created [autoscaler].

# Auto-scale based on HTTP load balancing utilization
$ gcloud compute instance-groups managed set-autoscaling web-mig \
    --zone=us-central1-a \
    --min-num-replicas=2 \
    --max-num-replicas=20 \
    --target-load-balancing-utilization=0.70

# Scale based on a custom Cloud Monitoring metric
$ gcloud compute instance-groups managed set-autoscaling web-mig \
    --zone=us-central1-a \
    --min-num-replicas=2 \
    --max-num-replicas=10 \
    --custom-metric-utilization=metric=custom.googleapis.com/queue_depth,utilization-target=5,utilization-target-type=GAUGE

Step 4: Configure Auto-Healing

Auto-healing automatically replaces unhealthy VMs detected by a health check.

# Create a health check
$ gcloud compute health-checks create http web-health-check \
    --port=80 \
    --request-path=/health \
    --check-interval=30s \
    --timeout=10s \
    --healthy-threshold=2 \
    --unhealthy-threshold=3

# Attach the health check to the MIG
$ gcloud compute instance-groups managed set-autohealing web-mig \
    --zone=us-central1-a \
    --health-check=web-health-check \
    --initial-delay=120

# The initial delay gives VMs time to boot before health checks start

Rolling Updates

Update VMs without downtime using rolling update policies.

# Create a new template with updated image
$ gcloud compute instance-templates create web-template-v2 \
    --machine-type=e2-standard-2 \
    --image-family=devops-base \
    --image-project=my-project \
    --boot-disk-size=20GB \
    --tags=http-server,health-check \
    --service-account=web-sa@my-project.iam.gserviceaccount.com \
    --scopes=cloud-platform \
    --metadata=app-version=2.0.0

# Start a rolling update
$ gcloud compute instance-groups managed rolling-action start-update web-mig \
    --zone=us-central1-a \
    --version=template=web-template-v2 \
    --max-surge=1 \
    --max-unavailable=0

# Monitor the update
$ gcloud compute instance-groups managed list-instances web-mig \
    --zone=us-central1-a \
    --format="table(instance,status,currentAction,version.instanceTemplate)"

INSTANCE                 STATUS   CURRENT_ACTION  INSTANCE_TEMPLATE
web-mig-xxxx             RUNNING  NONE            web-template-v2
web-mig-yyyy             RUNNING  RECREATING      web-template
web-mig-zzzz             RUNNING  NONE            web-template

Canary Updates

# Canary deployment: 20% of instances get the new version
$ gcloud compute instance-groups managed rolling-action start-update web-mig \
    --zone=us-central1-a \
    --version=template=web-template \
    --canary-version=template=web-template-v2,target-size=20%

# If canary is healthy, promote to 100%
$ gcloud compute instance-groups managed rolling-action start-update web-mig \
    --zone=us-central1-a \
    --version=template=web-template-v2

# Rollback: switch back to old template
$ gcloud compute instance-groups managed rolling-action start-update web-mig \
    --zone=us-central1-a \
    --version=template=web-template \
    --max-surge=1 \
    --max-unavailable=0

Update Policies

Parameter Description Recommended
--max-surge Extra VMs during update 1 or 20%
--max-unavailable VMs that can be down 0 (zero downtime)
--replacement-method=substitute Replace in-place Default
--replacement-method=recreate Delete then create When you need fresh VMs
--minimal-action=RESTART Restart VMs For metadata changes
--minimal-action=REPLACE Replace VMs For template changes

Managing MIGs

# Resize a MIG manually
$ gcloud compute instance-groups managed resize web-mig \
    --zone=us-central1-a \
    --size=5

# List instances in a MIG
$ gcloud compute instance-groups managed list-instances web-mig \
    --zone=us-central1-a

# Delete a specific instance (MIG recreates it)
$ gcloud compute instance-groups managed delete-instances web-mig \
    --zone=us-central1-a \
    --instances=web-mig-abcd

# Abandon an instance (remove from MIG without deleting)
$ gcloud compute instance-groups managed abandon-instances web-mig \
    --zone=us-central1-a \
    --instances=web-mig-abcd

Common Mistakes

Mistake Why It’s Wrong Fix
Not setting --max-unavailable=0 Causes downtime during updates Always set to 0 for production
No health check MIG can’t detect failed VMs Always attach a health check
Short initial delay Health check fails before app boots Set --initial-delay to > boot time
Using zonal MIG for prod Single zone = single point of failure Use regional MIG
Not using instance templates Can’t do rolling updates Always define a template

Quick Reference

Command Description
gcloud compute instance-templates create NAME Create template
gcloud compute instance-groups managed create NAME --template=T --size=N Create MIG
gcloud compute instance-groups managed set-autoscaling NAME Configure auto-scaling
gcloud compute instance-groups managed set-autohealing NAME Configure auto-healing
gcloud compute instance-groups managed rolling-action start-update NAME Rolling update
gcloud compute instance-groups managed resize NAME --size=N Resize MIG
gcloud compute instance-groups managed list-instances NAME List MIG instances

Next → Practice Exercises

Updated: