The gcp:compute/instanceGroupManager:InstanceGroupManager resource, part of the Pulumi GCP provider, manages pools of homogeneous Compute Engine instances from a common template, handling creation, health monitoring, and version management. This guide focuses on four capabilities: auto-healing with health checks, canary deployments with multiple versions, standby policies for fast scaling, and resource policies for specialized hardware.
Instance group managers require instance templates and may reference health checks, target pools, or resource policies that must exist separately. The examples are intentionally small. Combine them with your own templates, networking, and load balancing configuration.
Deploy instances with health checks and auto-healing
Most managed instance groups start with a single instance template and health checks that automatically replace unhealthy instances.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const autohealing = new gcp.compute.HealthCheck("autohealing", {
name: "autohealing-health-check",
checkIntervalSec: 5,
timeoutSec: 5,
healthyThreshold: 2,
unhealthyThreshold: 10,
httpHealthCheck: {
requestPath: "/healthz",
port: 8080,
},
});
const appserver = new gcp.compute.InstanceGroupManager("appserver", {
name: "appserver-igm",
baseInstanceName: "app",
zone: "us-central1-a",
versions: [{
instanceTemplate: appserverGoogleComputeInstanceTemplate.selfLinkUnique,
}],
allInstancesConfig: {
metadata: {
metadata_key: "metadata_value",
},
labels: {
label_key: "label_value",
},
},
targetPools: [appserverGoogleComputeTargetPool.id],
targetSize: 2,
namedPorts: [{
name: "customhttp",
port: 8888,
}],
autoHealingPolicies: {
healthCheck: autohealing.id,
initialDelaySec: 300,
},
});
import pulumi
import pulumi_gcp as gcp
autohealing = gcp.compute.HealthCheck("autohealing",
name="autohealing-health-check",
check_interval_sec=5,
timeout_sec=5,
healthy_threshold=2,
unhealthy_threshold=10,
http_health_check={
"request_path": "/healthz",
"port": 8080,
})
appserver = gcp.compute.InstanceGroupManager("appserver",
name="appserver-igm",
base_instance_name="app",
zone="us-central1-a",
versions=[{
"instance_template": appserver_google_compute_instance_template["selfLinkUnique"],
}],
all_instances_config={
"metadata": {
"metadata_key": "metadata_value",
},
"labels": {
"label_key": "label_value",
},
},
target_pools=[appserver_google_compute_target_pool["id"]],
target_size=2,
named_ports=[{
"name": "customhttp",
"port": 8888,
}],
auto_healing_policies={
"health_check": autohealing.id,
"initial_delay_sec": 300,
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
autohealing, err := compute.NewHealthCheck(ctx, "autohealing", &compute.HealthCheckArgs{
Name: pulumi.String("autohealing-health-check"),
CheckIntervalSec: pulumi.Int(5),
TimeoutSec: pulumi.Int(5),
HealthyThreshold: pulumi.Int(2),
UnhealthyThreshold: pulumi.Int(10),
HttpHealthCheck: &compute.HealthCheckHttpHealthCheckArgs{
RequestPath: pulumi.String("/healthz"),
Port: pulumi.Int(8080),
},
})
if err != nil {
return err
}
_, err = compute.NewInstanceGroupManager(ctx, "appserver", &compute.InstanceGroupManagerArgs{
Name: pulumi.String("appserver-igm"),
BaseInstanceName: pulumi.String("app"),
Zone: pulumi.String("us-central1-a"),
Versions: compute.InstanceGroupManagerVersionArray{
&compute.InstanceGroupManagerVersionArgs{
InstanceTemplate: pulumi.Any(appserverGoogleComputeInstanceTemplate.SelfLinkUnique),
},
},
AllInstancesConfig: &compute.InstanceGroupManagerAllInstancesConfigArgs{
Metadata: pulumi.StringMap{
"metadata_key": pulumi.String("metadata_value"),
},
Labels: pulumi.StringMap{
"label_key": pulumi.String("label_value"),
},
},
TargetPools: pulumi.StringArray{
appserverGoogleComputeTargetPool.Id,
},
TargetSize: pulumi.Int(2),
NamedPorts: compute.InstanceGroupManagerNamedPortArray{
&compute.InstanceGroupManagerNamedPortArgs{
Name: pulumi.String("customhttp"),
Port: pulumi.Int(8888),
},
},
AutoHealingPolicies: &compute.InstanceGroupManagerAutoHealingPoliciesArgs{
HealthCheck: autohealing.ID(),
InitialDelaySec: pulumi.Int(300),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var autohealing = new Gcp.Compute.HealthCheck("autohealing", new()
{
Name = "autohealing-health-check",
CheckIntervalSec = 5,
TimeoutSec = 5,
HealthyThreshold = 2,
UnhealthyThreshold = 10,
HttpHealthCheck = new Gcp.Compute.Inputs.HealthCheckHttpHealthCheckArgs
{
RequestPath = "/healthz",
Port = 8080,
},
});
var appserver = new Gcp.Compute.InstanceGroupManager("appserver", new()
{
Name = "appserver-igm",
BaseInstanceName = "app",
Zone = "us-central1-a",
Versions = new[]
{
new Gcp.Compute.Inputs.InstanceGroupManagerVersionArgs
{
InstanceTemplate = appserverGoogleComputeInstanceTemplate.SelfLinkUnique,
},
},
AllInstancesConfig = new Gcp.Compute.Inputs.InstanceGroupManagerAllInstancesConfigArgs
{
Metadata =
{
{ "metadata_key", "metadata_value" },
},
Labels =
{
{ "label_key", "label_value" },
},
},
TargetPools = new[]
{
appserverGoogleComputeTargetPool.Id,
},
TargetSize = 2,
NamedPorts = new[]
{
new Gcp.Compute.Inputs.InstanceGroupManagerNamedPortArgs
{
Name = "customhttp",
Port = 8888,
},
},
AutoHealingPolicies = new Gcp.Compute.Inputs.InstanceGroupManagerAutoHealingPoliciesArgs
{
HealthCheck = autohealing.Id,
InitialDelaySec = 300,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.InstanceGroupManager;
import com.pulumi.gcp.compute.InstanceGroupManagerArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerVersionArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerAllInstancesConfigArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerNamedPortArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerAutoHealingPoliciesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var autohealing = new HealthCheck("autohealing", HealthCheckArgs.builder()
.name("autohealing-health-check")
.checkIntervalSec(5)
.timeoutSec(5)
.healthyThreshold(2)
.unhealthyThreshold(10)
.httpHealthCheck(HealthCheckHttpHealthCheckArgs.builder()
.requestPath("/healthz")
.port(8080)
.build())
.build());
var appserver = new InstanceGroupManager("appserver", InstanceGroupManagerArgs.builder()
.name("appserver-igm")
.baseInstanceName("app")
.zone("us-central1-a")
.versions(InstanceGroupManagerVersionArgs.builder()
.instanceTemplate(appserverGoogleComputeInstanceTemplate.selfLinkUnique())
.build())
.allInstancesConfig(InstanceGroupManagerAllInstancesConfigArgs.builder()
.metadata(Map.of("metadata_key", "metadata_value"))
.labels(Map.of("label_key", "label_value"))
.build())
.targetPools(appserverGoogleComputeTargetPool.id())
.targetSize(2)
.namedPorts(InstanceGroupManagerNamedPortArgs.builder()
.name("customhttp")
.port(8888)
.build())
.autoHealingPolicies(InstanceGroupManagerAutoHealingPoliciesArgs.builder()
.healthCheck(autohealing.id())
.initialDelaySec(300)
.build())
.build());
}
}
resources:
autohealing:
type: gcp:compute:HealthCheck
properties:
name: autohealing-health-check
checkIntervalSec: 5
timeoutSec: 5
healthyThreshold: 2
unhealthyThreshold: 10 # 50 seconds
httpHealthCheck:
requestPath: /healthz
port: '8080'
appserver:
type: gcp:compute:InstanceGroupManager
properties:
name: appserver-igm
baseInstanceName: app
zone: us-central1-a
versions:
- instanceTemplate: ${appserverGoogleComputeInstanceTemplate.selfLinkUnique}
allInstancesConfig:
metadata:
metadata_key: metadata_value
labels:
label_key: label_value
targetPools:
- ${appserverGoogleComputeTargetPool.id}
targetSize: 2
namedPorts:
- name: customhttp
port: 8888
autoHealingPolicies:
healthCheck: ${autohealing.id}
initialDelaySec: 300
The versions property specifies which instance template to use. The autoHealingPolicies property connects a health check and sets initialDelaySec, which delays health checks after instance startup to allow application initialization. When an instance fails health checks, the manager automatically replaces it. The targetSize property sets the desired number of running instances.
Run canary deployments with multiple instance templates
Teams testing new application versions often run a small canary deployment alongside the stable version.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const appserver = new gcp.compute.InstanceGroupManager("appserver", {
name: "appserver-igm",
baseInstanceName: "app",
zone: "us-central1-a",
targetSize: 5,
versions: [
{
name: "appserver",
instanceTemplate: appserverGoogleComputeInstanceTemplate.selfLinkUnique,
},
{
name: "appserver-canary",
instanceTemplate: appserver_canary.selfLinkUnique,
targetSize: {
fixed: 1,
},
},
],
});
import pulumi
import pulumi_gcp as gcp
appserver = gcp.compute.InstanceGroupManager("appserver",
name="appserver-igm",
base_instance_name="app",
zone="us-central1-a",
target_size=5,
versions=[
{
"name": "appserver",
"instance_template": appserver_google_compute_instance_template["selfLinkUnique"],
},
{
"name": "appserver-canary",
"instance_template": appserver_canary["selfLinkUnique"],
"target_size": {
"fixed": 1,
},
},
])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewInstanceGroupManager(ctx, "appserver", &compute.InstanceGroupManagerArgs{
Name: pulumi.String("appserver-igm"),
BaseInstanceName: pulumi.String("app"),
Zone: pulumi.String("us-central1-a"),
TargetSize: pulumi.Int(5),
Versions: compute.InstanceGroupManagerVersionArray{
&compute.InstanceGroupManagerVersionArgs{
Name: pulumi.String("appserver"),
InstanceTemplate: pulumi.Any(appserverGoogleComputeInstanceTemplate.SelfLinkUnique),
},
&compute.InstanceGroupManagerVersionArgs{
Name: pulumi.String("appserver-canary"),
InstanceTemplate: pulumi.Any(appserver_canary.SelfLinkUnique),
TargetSize: &compute.InstanceGroupManagerVersionTargetSizeArgs{
Fixed: pulumi.Int(1),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var appserver = new Gcp.Compute.InstanceGroupManager("appserver", new()
{
Name = "appserver-igm",
BaseInstanceName = "app",
Zone = "us-central1-a",
TargetSize = 5,
Versions = new[]
{
new Gcp.Compute.Inputs.InstanceGroupManagerVersionArgs
{
Name = "appserver",
InstanceTemplate = appserverGoogleComputeInstanceTemplate.SelfLinkUnique,
},
new Gcp.Compute.Inputs.InstanceGroupManagerVersionArgs
{
Name = "appserver-canary",
InstanceTemplate = appserver_canary.SelfLinkUnique,
TargetSize = new Gcp.Compute.Inputs.InstanceGroupManagerVersionTargetSizeArgs
{
Fixed = 1,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.InstanceGroupManager;
import com.pulumi.gcp.compute.InstanceGroupManagerArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerVersionArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerVersionTargetSizeArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var appserver = new InstanceGroupManager("appserver", InstanceGroupManagerArgs.builder()
.name("appserver-igm")
.baseInstanceName("app")
.zone("us-central1-a")
.targetSize(5)
.versions(
InstanceGroupManagerVersionArgs.builder()
.name("appserver")
.instanceTemplate(appserverGoogleComputeInstanceTemplate.selfLinkUnique())
.build(),
InstanceGroupManagerVersionArgs.builder()
.name("appserver-canary")
.instanceTemplate(appserver_canary.selfLinkUnique())
.targetSize(InstanceGroupManagerVersionTargetSizeArgs.builder()
.fixed(1)
.build())
.build())
.build());
}
}
resources:
appserver:
type: gcp:compute:InstanceGroupManager
properties:
name: appserver-igm
baseInstanceName: app
zone: us-central1-a
targetSize: 5
versions:
- name: appserver
instanceTemplate: ${appserverGoogleComputeInstanceTemplate.selfLinkUnique}
- name: appserver-canary
instanceTemplate: ${["appserver-canary"].selfLinkUnique}
targetSize:
fixed: 1
The versions array can contain multiple entries, each with its own instance template. The targetSize property within a version controls how many instances run that template. Here, one instance runs the canary template while the remaining instances run the stable version. This allows gradual traffic shifting as confidence builds.
Maintain stopped and suspended instances for fast scaling
Applications with predictable traffic spikes can pre-provision stopped or suspended instances that start faster than creating new instances.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const igm_sr = new gcp.compute.InstanceGroupManager("igm-sr", {
name: "tf-sr-igm",
baseInstanceName: "tf-sr-igm-instance",
zone: "us-central1-a",
targetSize: 5,
versions: [{
instanceTemplate: sr_igm.selfLink,
name: "primary",
}],
standbyPolicy: {
initialDelaySec: 30,
mode: "MANUAL",
},
targetSuspendedSize: 2,
targetStoppedSize: 1,
});
import pulumi
import pulumi_gcp as gcp
igm_sr = gcp.compute.InstanceGroupManager("igm-sr",
name="tf-sr-igm",
base_instance_name="tf-sr-igm-instance",
zone="us-central1-a",
target_size=5,
versions=[{
"instance_template": sr_igm["selfLink"],
"name": "primary",
}],
standby_policy={
"initial_delay_sec": 30,
"mode": "MANUAL",
},
target_suspended_size=2,
target_stopped_size=1)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewInstanceGroupManager(ctx, "igm-sr", &compute.InstanceGroupManagerArgs{
Name: pulumi.String("tf-sr-igm"),
BaseInstanceName: pulumi.String("tf-sr-igm-instance"),
Zone: pulumi.String("us-central1-a"),
TargetSize: pulumi.Int(5),
Versions: compute.InstanceGroupManagerVersionArray{
&compute.InstanceGroupManagerVersionArgs{
InstanceTemplate: pulumi.Any(sr_igm.SelfLink),
Name: pulumi.String("primary"),
},
},
StandbyPolicy: &compute.InstanceGroupManagerStandbyPolicyArgs{
InitialDelaySec: pulumi.Int(30),
Mode: pulumi.String("MANUAL"),
},
TargetSuspendedSize: pulumi.Int(2),
TargetStoppedSize: pulumi.Int(1),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var igm_sr = new Gcp.Compute.InstanceGroupManager("igm-sr", new()
{
Name = "tf-sr-igm",
BaseInstanceName = "tf-sr-igm-instance",
Zone = "us-central1-a",
TargetSize = 5,
Versions = new[]
{
new Gcp.Compute.Inputs.InstanceGroupManagerVersionArgs
{
InstanceTemplate = sr_igm.SelfLink,
Name = "primary",
},
},
StandbyPolicy = new Gcp.Compute.Inputs.InstanceGroupManagerStandbyPolicyArgs
{
InitialDelaySec = 30,
Mode = "MANUAL",
},
TargetSuspendedSize = 2,
TargetStoppedSize = 1,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.InstanceGroupManager;
import com.pulumi.gcp.compute.InstanceGroupManagerArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerVersionArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerStandbyPolicyArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var igm_sr = new InstanceGroupManager("igm-sr", InstanceGroupManagerArgs.builder()
.name("tf-sr-igm")
.baseInstanceName("tf-sr-igm-instance")
.zone("us-central1-a")
.targetSize(5)
.versions(InstanceGroupManagerVersionArgs.builder()
.instanceTemplate(sr_igm.selfLink())
.name("primary")
.build())
.standbyPolicy(InstanceGroupManagerStandbyPolicyArgs.builder()
.initialDelaySec(30)
.mode("MANUAL")
.build())
.targetSuspendedSize(2)
.targetStoppedSize(1)
.build());
}
}
resources:
igm-sr:
type: gcp:compute:InstanceGroupManager
properties:
name: tf-sr-igm
baseInstanceName: tf-sr-igm-instance
zone: us-central1-a
targetSize: 5
versions:
- instanceTemplate: ${["sr-igm"].selfLink}
name: primary
standbyPolicy:
initialDelaySec: 30
mode: MANUAL
targetSuspendedSize: 2
targetStoppedSize: 1
The standbyPolicy property configures how the manager handles stopped and suspended instances. The mode property controls whether standby instances are managed automatically or manually. The targetSuspendedSize and targetStoppedSize properties specify how many instances to keep in each state. Stopped and suspended instances start faster than creating new instances from scratch, reducing scaling latency.
Apply workload policies for specialized hardware
Workloads running on specialized hardware like GPUs or high-throughput machines often need resource policies that optimize scheduling and placement.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const myImage = gcp.compute.getImage({
family: "debian-11",
project: "debian-cloud",
});
const workloadPolicy = new gcp.compute.ResourcePolicy("workload_policy", {
name: "tf-test-gce-policy",
region: "us-central1",
workloadPolicy: {
type: "HIGH_THROUGHPUT",
},
});
const igm_basic = new gcp.compute.InstanceTemplate("igm-basic", {
name: "igm-instance-template",
machineType: "a4-highgpu-8g",
canIpForward: false,
tags: [
"foo",
"bar",
],
disks: [{
sourceImage: myImage.then(myImage => myImage.selfLink),
autoDelete: true,
boot: true,
diskType: "hyperdisk-balanced",
}],
networkInterfaces: [{
network: "default",
}],
serviceAccount: {
scopes: [
"userinfo-email",
"compute-ro",
"storage-ro",
],
},
});
const igm_workload_policy = new gcp.compute.InstanceGroupManager("igm-workload-policy", {
description: "Terraform test instance group manager",
name: "igm-basic-workload-policy",
versions: [{
name: "prod",
instanceTemplate: igm_basic.selfLink,
}],
baseInstanceName: "tf-test-igm-no-tp",
zone: "us-central1-b",
targetSize: 0,
resourcePolicies: {
workloadPolicy: workloadPolicy.selfLink,
},
});
import pulumi
import pulumi_gcp as gcp
my_image = gcp.compute.get_image(family="debian-11",
project="debian-cloud")
workload_policy = gcp.compute.ResourcePolicy("workload_policy",
name="tf-test-gce-policy",
region="us-central1",
workload_policy={
"type": "HIGH_THROUGHPUT",
})
igm_basic = gcp.compute.InstanceTemplate("igm-basic",
name="igm-instance-template",
machine_type="a4-highgpu-8g",
can_ip_forward=False,
tags=[
"foo",
"bar",
],
disks=[{
"source_image": my_image.self_link,
"auto_delete": True,
"boot": True,
"disk_type": "hyperdisk-balanced",
}],
network_interfaces=[{
"network": "default",
}],
service_account={
"scopes": [
"userinfo-email",
"compute-ro",
"storage-ro",
],
})
igm_workload_policy = gcp.compute.InstanceGroupManager("igm-workload-policy",
description="Terraform test instance group manager",
name="igm-basic-workload-policy",
versions=[{
"name": "prod",
"instance_template": igm_basic.self_link,
}],
base_instance_name="tf-test-igm-no-tp",
zone="us-central1-b",
target_size=0,
resource_policies={
"workload_policy": workload_policy.self_link,
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
myImage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
Family: pulumi.StringRef("debian-11"),
Project: pulumi.StringRef("debian-cloud"),
}, nil)
if err != nil {
return err
}
workloadPolicy, err := compute.NewResourcePolicy(ctx, "workload_policy", &compute.ResourcePolicyArgs{
Name: pulumi.String("tf-test-gce-policy"),
Region: pulumi.String("us-central1"),
WorkloadPolicy: &compute.ResourcePolicyWorkloadPolicyArgs{
Type: pulumi.String("HIGH_THROUGHPUT"),
},
})
if err != nil {
return err
}
igm_basic, err := compute.NewInstanceTemplate(ctx, "igm-basic", &compute.InstanceTemplateArgs{
Name: pulumi.String("igm-instance-template"),
MachineType: pulumi.String("a4-highgpu-8g"),
CanIpForward: pulumi.Bool(false),
Tags: pulumi.StringArray{
pulumi.String("foo"),
pulumi.String("bar"),
},
Disks: compute.InstanceTemplateDiskArray{
&compute.InstanceTemplateDiskArgs{
SourceImage: pulumi.String(myImage.SelfLink),
AutoDelete: pulumi.Bool(true),
Boot: pulumi.Bool(true),
DiskType: pulumi.String("hyperdisk-balanced"),
},
},
NetworkInterfaces: compute.InstanceTemplateNetworkInterfaceArray{
&compute.InstanceTemplateNetworkInterfaceArgs{
Network: pulumi.String("default"),
},
},
ServiceAccount: &compute.InstanceTemplateServiceAccountArgs{
Scopes: pulumi.StringArray{
pulumi.String("userinfo-email"),
pulumi.String("compute-ro"),
pulumi.String("storage-ro"),
},
},
})
if err != nil {
return err
}
_, err = compute.NewInstanceGroupManager(ctx, "igm-workload-policy", &compute.InstanceGroupManagerArgs{
Description: pulumi.String("Terraform test instance group manager"),
Name: pulumi.String("igm-basic-workload-policy"),
Versions: compute.InstanceGroupManagerVersionArray{
&compute.InstanceGroupManagerVersionArgs{
Name: pulumi.String("prod"),
InstanceTemplate: igm_basic.SelfLink,
},
},
BaseInstanceName: pulumi.String("tf-test-igm-no-tp"),
Zone: pulumi.String("us-central1-b"),
TargetSize: pulumi.Int(0),
ResourcePolicies: &compute.InstanceGroupManagerResourcePoliciesArgs{
WorkloadPolicy: workloadPolicy.SelfLink,
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var myImage = Gcp.Compute.GetImage.Invoke(new()
{
Family = "debian-11",
Project = "debian-cloud",
});
var workloadPolicy = new Gcp.Compute.ResourcePolicy("workload_policy", new()
{
Name = "tf-test-gce-policy",
Region = "us-central1",
WorkloadPolicy = new Gcp.Compute.Inputs.ResourcePolicyWorkloadPolicyArgs
{
Type = "HIGH_THROUGHPUT",
},
});
var igm_basic = new Gcp.Compute.InstanceTemplate("igm-basic", new()
{
Name = "igm-instance-template",
MachineType = "a4-highgpu-8g",
CanIpForward = false,
Tags = new[]
{
"foo",
"bar",
},
Disks = new[]
{
new Gcp.Compute.Inputs.InstanceTemplateDiskArgs
{
SourceImage = myImage.Apply(getImageResult => getImageResult.SelfLink),
AutoDelete = true,
Boot = true,
DiskType = "hyperdisk-balanced",
},
},
NetworkInterfaces = new[]
{
new Gcp.Compute.Inputs.InstanceTemplateNetworkInterfaceArgs
{
Network = "default",
},
},
ServiceAccount = new Gcp.Compute.Inputs.InstanceTemplateServiceAccountArgs
{
Scopes = new[]
{
"userinfo-email",
"compute-ro",
"storage-ro",
},
},
});
var igm_workload_policy = new Gcp.Compute.InstanceGroupManager("igm-workload-policy", new()
{
Description = "Terraform test instance group manager",
Name = "igm-basic-workload-policy",
Versions = new[]
{
new Gcp.Compute.Inputs.InstanceGroupManagerVersionArgs
{
Name = "prod",
InstanceTemplate = igm_basic.SelfLink,
},
},
BaseInstanceName = "tf-test-igm-no-tp",
Zone = "us-central1-b",
TargetSize = 0,
ResourcePolicies = new Gcp.Compute.Inputs.InstanceGroupManagerResourcePoliciesArgs
{
WorkloadPolicy = workloadPolicy.SelfLink,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.ResourcePolicy;
import com.pulumi.gcp.compute.ResourcePolicyArgs;
import com.pulumi.gcp.compute.inputs.ResourcePolicyWorkloadPolicyArgs;
import com.pulumi.gcp.compute.InstanceTemplate;
import com.pulumi.gcp.compute.InstanceTemplateArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateNetworkInterfaceArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateServiceAccountArgs;
import com.pulumi.gcp.compute.InstanceGroupManager;
import com.pulumi.gcp.compute.InstanceGroupManagerArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerVersionArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerResourcePoliciesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var myImage = ComputeFunctions.getImage(GetImageArgs.builder()
.family("debian-11")
.project("debian-cloud")
.build());
var workloadPolicy = new ResourcePolicy("workloadPolicy", ResourcePolicyArgs.builder()
.name("tf-test-gce-policy")
.region("us-central1")
.workloadPolicy(ResourcePolicyWorkloadPolicyArgs.builder()
.type("HIGH_THROUGHPUT")
.build())
.build());
var igm_basic = new InstanceTemplate("igm-basic", InstanceTemplateArgs.builder()
.name("igm-instance-template")
.machineType("a4-highgpu-8g")
.canIpForward(false)
.tags(
"foo",
"bar")
.disks(InstanceTemplateDiskArgs.builder()
.sourceImage(myImage.selfLink())
.autoDelete(true)
.boot(true)
.diskType("hyperdisk-balanced")
.build())
.networkInterfaces(InstanceTemplateNetworkInterfaceArgs.builder()
.network("default")
.build())
.serviceAccount(InstanceTemplateServiceAccountArgs.builder()
.scopes(
"userinfo-email",
"compute-ro",
"storage-ro")
.build())
.build());
var igm_workload_policy = new InstanceGroupManager("igm-workload-policy", InstanceGroupManagerArgs.builder()
.description("Terraform test instance group manager")
.name("igm-basic-workload-policy")
.versions(InstanceGroupManagerVersionArgs.builder()
.name("prod")
.instanceTemplate(igm_basic.selfLink())
.build())
.baseInstanceName("tf-test-igm-no-tp")
.zone("us-central1-b")
.targetSize(0)
.resourcePolicies(InstanceGroupManagerResourcePoliciesArgs.builder()
.workloadPolicy(workloadPolicy.selfLink())
.build())
.build());
}
}
resources:
workloadPolicy:
type: gcp:compute:ResourcePolicy
name: workload_policy
properties:
name: tf-test-gce-policy
region: us-central1
workloadPolicy:
type: HIGH_THROUGHPUT
igm-basic:
type: gcp:compute:InstanceTemplate
properties:
name: igm-instance-template
machineType: a4-highgpu-8g
canIpForward: false
tags:
- foo
- bar
disks:
- sourceImage: ${myImage.selfLink}
autoDelete: true
boot: true
diskType: hyperdisk-balanced
networkInterfaces:
- network: default
serviceAccount:
scopes:
- userinfo-email
- compute-ro
- storage-ro
igm-workload-policy:
type: gcp:compute:InstanceGroupManager
properties:
description: Terraform test instance group manager
name: igm-basic-workload-policy
versions:
- name: prod
instanceTemplate: ${["igm-basic"].selfLink}
baseInstanceName: tf-test-igm-no-tp
zone: us-central1-b
targetSize: 0
resourcePolicies:
workloadPolicy: ${workloadPolicy.selfLink}
variables:
myImage:
fn::invoke:
function: gcp:compute:getImage
arguments:
family: debian-11
project: debian-cloud
The resourcePolicies property attaches a workload policy to the instance group. The ResourcePolicy resource defines the policy type (here, HIGH_THROUGHPUT for high-performance networking). This configuration works with specialized machine types like a4-highgpu-8g, which require specific quotas and are optimized for GPU workloads.
Beyond these examples
These snippets focus on specific instance group manager features: health checks and auto-healing, canary deployments with multiple versions, standby policies for stopped/suspended instances, and resource policies for specialized workloads. They’re intentionally minimal rather than full application deployments.
The examples may reference pre-existing infrastructure such as instance templates, target pools for load balancing, health checks, and VPC networks and subnets implicit in templates. They focus on configuring the instance group manager rather than provisioning everything around it.
To keep things focused, common instance group patterns are omitted, including:
- Update policies for rolling updates (updatePolicy)
- Stateful disk and IP preservation (statefulDisks, statefulExternalIps)
- Named ports for service discovery
- Instance lifecycle policies
- Wait conditions for deployment synchronization
These omissions are intentional: the goal is to illustrate how each instance group feature is wired, not provide drop-in compute modules. See the Instance Group Manager resource reference for all available configuration options.
Let's configure GCP Instance Group Managers
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Resource Selection & Scope
gcp.compute.RegionInstanceGroupManager to create a regional (multi-zone) instance group manager. Use InstanceGroupManager for zonal (single-zone) deployments.Autoscaling & Target Sizes
targetSize when using an autoscaler causes conflicts because both try to control instance count. Either don’t set targetSize when using an autoscaler, or use lifecycle.ignore_changes to prevent Pulumi from modifying it.targetSize defaults to 0, so you must explicitly set it if you want running instances without an autoscaler.Instance Versions & Updates
versions array, each with a different instanceTemplate. You can specify targetSize.fixed for each version to control the rollout (e.g., 1 canary instance alongside your main version).allInstancesConfig, you must manually update the group’s instances to apply the configuration. Changes don’t automatically propagate to existing instances.STABLE waits until instances are stable. UPDATED waits for the version target to be reached, per-instance configs to be effective, and all instances to be stable before returning.Stateful Configuration
statefulDisks for persistent disks, statefulExternalIps for external IPs, and statefulInternalIps for internal IPs. These resources are preserved on instance delete, update, and other operations.Health & Lifecycle
autoHealingPolicies with a healthCheck ID and initialDelaySec (time to wait before checking health on new instances). The health check monitors instances and replaces unhealthy ones.standbyPolicy with targetStoppedSize and targetSuspendedSize to maintain a pool of stopped or suspended instances. Set the mode to MANUAL or let the system manage it automatically.namedPorts define port mappings (name and port number) that load balancers and other services can reference. For example, you might define a customhttp port at 8888 for routing traffic.Immutability & Constraints
baseInstanceName, name, project, zone, and params are immutable and cannot be changed after creation. You’ll need to recreate the resource to modify these.name must be 1-63 characters long and comply with RFC1035: lowercase letters, numbers, and hyphens only. The baseInstanceName follows the same rules and is used as a prefix for instance names.