GCP for DevOps — Managed Instance Groups
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