Configure GCP OS Config Guest Policies

The gcp:osconfig/guestPolicies:GuestPolicies resource, part of the Pulumi GCP provider, defines OS Config guest policies that declare desired package states and software installations across VM fleets. This guide focuses on three capabilities: VM targeting strategies, package repository configuration, and recipe-based software deployment from GCS.

Guest policies apply to Compute Engine instances and can reference Cloud Storage artifacts for custom software. The examples are intentionally small. Combine them with your own VM infrastructure and deployment workflows.

Assign a policy to specific VM instances

When you need to ensure specific VMs maintain certain package states, guest policies let you target individual instances.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const myImage = gcp.compute.getImage({
    family: "debian-11",
    project: "debian-cloud",
});
const foobar = new gcp.compute.Instance("foobar", {
    name: "guest-policy-inst",
    machineType: "e2-medium",
    zone: "us-central1-a",
    canIpForward: false,
    tags: [
        "foo",
        "bar",
    ],
    bootDisk: {
        initializeParams: {
            image: myImage.then(myImage => myImage.selfLink),
        },
    },
    networkInterfaces: [{
        network: "default",
    }],
    metadata: {
        foo: "bar",
    },
});
const guestPolicies = new gcp.osconfig.GuestPolicies("guest_policies", {
    guestPolicyId: "guest-policy",
    assignment: {
        instances: [foobar.id],
    },
    packages: [{
        name: "my-package",
        desiredState: "UPDATED",
    }],
});
import pulumi
import pulumi_gcp as gcp

my_image = gcp.compute.get_image(family="debian-11",
    project="debian-cloud")
foobar = gcp.compute.Instance("foobar",
    name="guest-policy-inst",
    machine_type="e2-medium",
    zone="us-central1-a",
    can_ip_forward=False,
    tags=[
        "foo",
        "bar",
    ],
    boot_disk={
        "initialize_params": {
            "image": my_image.self_link,
        },
    },
    network_interfaces=[{
        "network": "default",
    }],
    metadata={
        "foo": "bar",
    })
guest_policies = gcp.osconfig.GuestPolicies("guest_policies",
    guest_policy_id="guest-policy",
    assignment={
        "instances": [foobar.id],
    },
    packages=[{
        "name": "my-package",
        "desired_state": "UPDATED",
    }])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/osconfig"
	"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
		}
		foobar, err := compute.NewInstance(ctx, "foobar", &compute.InstanceArgs{
			Name:         pulumi.String("guest-policy-inst"),
			MachineType:  pulumi.String("e2-medium"),
			Zone:         pulumi.String("us-central1-a"),
			CanIpForward: pulumi.Bool(false),
			Tags: pulumi.StringArray{
				pulumi.String("foo"),
				pulumi.String("bar"),
			},
			BootDisk: &compute.InstanceBootDiskArgs{
				InitializeParams: &compute.InstanceBootDiskInitializeParamsArgs{
					Image: pulumi.String(myImage.SelfLink),
				},
			},
			NetworkInterfaces: compute.InstanceNetworkInterfaceArray{
				&compute.InstanceNetworkInterfaceArgs{
					Network: pulumi.String("default"),
				},
			},
			Metadata: pulumi.StringMap{
				"foo": pulumi.String("bar"),
			},
		})
		if err != nil {
			return err
		}
		_, err = osconfig.NewGuestPolicies(ctx, "guest_policies", &osconfig.GuestPoliciesArgs{
			GuestPolicyId: pulumi.String("guest-policy"),
			Assignment: &osconfig.GuestPoliciesAssignmentArgs{
				Instances: pulumi.StringArray{
					foobar.ID(),
				},
			},
			Packages: osconfig.GuestPoliciesPackageArray{
				&osconfig.GuestPoliciesPackageArgs{
					Name:         pulumi.String("my-package"),
					DesiredState: pulumi.String("UPDATED"),
				},
			},
		})
		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 foobar = new Gcp.Compute.Instance("foobar", new()
    {
        Name = "guest-policy-inst",
        MachineType = "e2-medium",
        Zone = "us-central1-a",
        CanIpForward = false,
        Tags = new[]
        {
            "foo",
            "bar",
        },
        BootDisk = new Gcp.Compute.Inputs.InstanceBootDiskArgs
        {
            InitializeParams = new Gcp.Compute.Inputs.InstanceBootDiskInitializeParamsArgs
            {
                Image = myImage.Apply(getImageResult => getImageResult.SelfLink),
            },
        },
        NetworkInterfaces = new[]
        {
            new Gcp.Compute.Inputs.InstanceNetworkInterfaceArgs
            {
                Network = "default",
            },
        },
        Metadata = 
        {
            { "foo", "bar" },
        },
    });

    var guestPolicies = new Gcp.OsConfig.GuestPolicies("guest_policies", new()
    {
        GuestPolicyId = "guest-policy",
        Assignment = new Gcp.OsConfig.Inputs.GuestPoliciesAssignmentArgs
        {
            Instances = new[]
            {
                foobar.Id,
            },
        },
        Packages = new[]
        {
            new Gcp.OsConfig.Inputs.GuestPoliciesPackageArgs
            {
                Name = "my-package",
                DesiredState = "UPDATED",
            },
        },
    });

});
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.Instance;
import com.pulumi.gcp.compute.InstanceArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskInitializeParamsArgs;
import com.pulumi.gcp.compute.inputs.InstanceNetworkInterfaceArgs;
import com.pulumi.gcp.osconfig.GuestPolicies;
import com.pulumi.gcp.osconfig.GuestPoliciesArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesAssignmentArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesPackageArgs;
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 foobar = new Instance("foobar", InstanceArgs.builder()
            .name("guest-policy-inst")
            .machineType("e2-medium")
            .zone("us-central1-a")
            .canIpForward(false)
            .tags(            
                "foo",
                "bar")
            .bootDisk(InstanceBootDiskArgs.builder()
                .initializeParams(InstanceBootDiskInitializeParamsArgs.builder()
                    .image(myImage.selfLink())
                    .build())
                .build())
            .networkInterfaces(InstanceNetworkInterfaceArgs.builder()
                .network("default")
                .build())
            .metadata(Map.of("foo", "bar"))
            .build());

        var guestPolicies = new GuestPolicies("guestPolicies", GuestPoliciesArgs.builder()
            .guestPolicyId("guest-policy")
            .assignment(GuestPoliciesAssignmentArgs.builder()
                .instances(foobar.id())
                .build())
            .packages(GuestPoliciesPackageArgs.builder()
                .name("my-package")
                .desiredState("UPDATED")
                .build())
            .build());

    }
}
resources:
  foobar:
    type: gcp:compute:Instance
    properties:
      name: guest-policy-inst
      machineType: e2-medium
      zone: us-central1-a
      canIpForward: false
      tags:
        - foo
        - bar
      bootDisk:
        initializeParams:
          image: ${myImage.selfLink}
      networkInterfaces:
        - network: default
      metadata:
        foo: bar
  guestPolicies:
    type: gcp:osconfig:GuestPolicies
    name: guest_policies
    properties:
      guestPolicyId: guest-policy
      assignment:
        instances:
          - ${foobar.id}
      packages:
        - name: my-package
          desiredState: UPDATED
variables:
  myImage:
    fn::invoke:
      function: gcp:compute:getImage
      arguments:
        family: debian-11
        project: debian-cloud

The assignment block targets VMs using the instances array, which accepts instance IDs. The packages array declares which packages should be managed; desiredState controls whether the package is INSTALLED, UPDATED, or REMOVED. OS Config enforces this state on the targeted VMs.

Target VMs by labels and configure package repositories

Production environments often organize VMs using labels. Guest policies can target these label groups and configure custom repositories.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const guestPolicies = new gcp.osconfig.GuestPolicies("guest_policies", {
    guestPolicyId: "guest-policy",
    assignment: {
        groupLabels: [
            {
                labels: {
                    color: "red",
                    env: "test",
                },
            },
            {
                labels: {
                    color: "blue",
                    env: "test",
                },
            },
        ],
    },
    packages: [
        {
            name: "my-package",
            desiredState: "INSTALLED",
        },
        {
            name: "bad-package-1",
            desiredState: "REMOVED",
        },
        {
            name: "bad-package-2",
            desiredState: "REMOVED",
            manager: "APT",
        },
    ],
    packageRepositories: [
        {
            apt: {
                uri: "https://packages.cloud.google.com/apt",
                archiveType: "DEB",
                distribution: "cloud-sdk-stretch",
                components: ["main"],
            },
        },
        {
            yum: {
                id: "google-cloud-sdk",
                displayName: "Google Cloud SDK",
                baseUrl: "https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64",
                gpgKeys: [
                    "https://packages.cloud.google.com/yum/doc/yum-key.gpg",
                    "https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg",
                ],
            },
        },
    ],
});
import pulumi
import pulumi_gcp as gcp

guest_policies = gcp.osconfig.GuestPolicies("guest_policies",
    guest_policy_id="guest-policy",
    assignment={
        "group_labels": [
            {
                "labels": {
                    "color": "red",
                    "env": "test",
                },
            },
            {
                "labels": {
                    "color": "blue",
                    "env": "test",
                },
            },
        ],
    },
    packages=[
        {
            "name": "my-package",
            "desired_state": "INSTALLED",
        },
        {
            "name": "bad-package-1",
            "desired_state": "REMOVED",
        },
        {
            "name": "bad-package-2",
            "desired_state": "REMOVED",
            "manager": "APT",
        },
    ],
    package_repositories=[
        {
            "apt": {
                "uri": "https://packages.cloud.google.com/apt",
                "archive_type": "DEB",
                "distribution": "cloud-sdk-stretch",
                "components": ["main"],
            },
        },
        {
            "yum": {
                "id": "google-cloud-sdk",
                "display_name": "Google Cloud SDK",
                "base_url": "https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64",
                "gpg_keys": [
                    "https://packages.cloud.google.com/yum/doc/yum-key.gpg",
                    "https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg",
                ],
            },
        },
    ])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/osconfig"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := osconfig.NewGuestPolicies(ctx, "guest_policies", &osconfig.GuestPoliciesArgs{
			GuestPolicyId: pulumi.String("guest-policy"),
			Assignment: &osconfig.GuestPoliciesAssignmentArgs{
				GroupLabels: osconfig.GuestPoliciesAssignmentGroupLabelArray{
					&osconfig.GuestPoliciesAssignmentGroupLabelArgs{
						Labels: pulumi.StringMap{
							"color": pulumi.String("red"),
							"env":   pulumi.String("test"),
						},
					},
					&osconfig.GuestPoliciesAssignmentGroupLabelArgs{
						Labels: pulumi.StringMap{
							"color": pulumi.String("blue"),
							"env":   pulumi.String("test"),
						},
					},
				},
			},
			Packages: osconfig.GuestPoliciesPackageArray{
				&osconfig.GuestPoliciesPackageArgs{
					Name:         pulumi.String("my-package"),
					DesiredState: pulumi.String("INSTALLED"),
				},
				&osconfig.GuestPoliciesPackageArgs{
					Name:         pulumi.String("bad-package-1"),
					DesiredState: pulumi.String("REMOVED"),
				},
				&osconfig.GuestPoliciesPackageArgs{
					Name:         pulumi.String("bad-package-2"),
					DesiredState: pulumi.String("REMOVED"),
					Manager:      pulumi.String("APT"),
				},
			},
			PackageRepositories: osconfig.GuestPoliciesPackageRepositoryArray{
				&osconfig.GuestPoliciesPackageRepositoryArgs{
					Apt: &osconfig.GuestPoliciesPackageRepositoryAptArgs{
						Uri:          pulumi.String("https://packages.cloud.google.com/apt"),
						ArchiveType:  pulumi.String("DEB"),
						Distribution: pulumi.String("cloud-sdk-stretch"),
						Components: pulumi.StringArray{
							pulumi.String("main"),
						},
					},
				},
				&osconfig.GuestPoliciesPackageRepositoryArgs{
					Yum: &osconfig.GuestPoliciesPackageRepositoryYumArgs{
						Id:          pulumi.String("google-cloud-sdk"),
						DisplayName: pulumi.String("Google Cloud SDK"),
						BaseUrl:     pulumi.String("https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64"),
						GpgKeys: pulumi.StringArray{
							pulumi.String("https://packages.cloud.google.com/yum/doc/yum-key.gpg"),
							pulumi.String("https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg"),
						},
					},
				},
			},
		})
		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 guestPolicies = new Gcp.OsConfig.GuestPolicies("guest_policies", new()
    {
        GuestPolicyId = "guest-policy",
        Assignment = new Gcp.OsConfig.Inputs.GuestPoliciesAssignmentArgs
        {
            GroupLabels = new[]
            {
                new Gcp.OsConfig.Inputs.GuestPoliciesAssignmentGroupLabelArgs
                {
                    Labels = 
                    {
                        { "color", "red" },
                        { "env", "test" },
                    },
                },
                new Gcp.OsConfig.Inputs.GuestPoliciesAssignmentGroupLabelArgs
                {
                    Labels = 
                    {
                        { "color", "blue" },
                        { "env", "test" },
                    },
                },
            },
        },
        Packages = new[]
        {
            new Gcp.OsConfig.Inputs.GuestPoliciesPackageArgs
            {
                Name = "my-package",
                DesiredState = "INSTALLED",
            },
            new Gcp.OsConfig.Inputs.GuestPoliciesPackageArgs
            {
                Name = "bad-package-1",
                DesiredState = "REMOVED",
            },
            new Gcp.OsConfig.Inputs.GuestPoliciesPackageArgs
            {
                Name = "bad-package-2",
                DesiredState = "REMOVED",
                Manager = "APT",
            },
        },
        PackageRepositories = new[]
        {
            new Gcp.OsConfig.Inputs.GuestPoliciesPackageRepositoryArgs
            {
                Apt = new Gcp.OsConfig.Inputs.GuestPoliciesPackageRepositoryAptArgs
                {
                    Uri = "https://packages.cloud.google.com/apt",
                    ArchiveType = "DEB",
                    Distribution = "cloud-sdk-stretch",
                    Components = new[]
                    {
                        "main",
                    },
                },
            },
            new Gcp.OsConfig.Inputs.GuestPoliciesPackageRepositoryArgs
            {
                Yum = new Gcp.OsConfig.Inputs.GuestPoliciesPackageRepositoryYumArgs
                {
                    Id = "google-cloud-sdk",
                    DisplayName = "Google Cloud SDK",
                    BaseUrl = "https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64",
                    GpgKeys = new[]
                    {
                        "https://packages.cloud.google.com/yum/doc/yum-key.gpg",
                        "https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.osconfig.GuestPolicies;
import com.pulumi.gcp.osconfig.GuestPoliciesArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesAssignmentArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesPackageArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesPackageRepositoryArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesPackageRepositoryAptArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesPackageRepositoryYumArgs;
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 guestPolicies = new GuestPolicies("guestPolicies", GuestPoliciesArgs.builder()
            .guestPolicyId("guest-policy")
            .assignment(GuestPoliciesAssignmentArgs.builder()
                .groupLabels(                
                    GuestPoliciesAssignmentGroupLabelArgs.builder()
                        .labels(Map.ofEntries(
                            Map.entry("color", "red"),
                            Map.entry("env", "test")
                        ))
                        .build(),
                    GuestPoliciesAssignmentGroupLabelArgs.builder()
                        .labels(Map.ofEntries(
                            Map.entry("color", "blue"),
                            Map.entry("env", "test")
                        ))
                        .build())
                .build())
            .packages(            
                GuestPoliciesPackageArgs.builder()
                    .name("my-package")
                    .desiredState("INSTALLED")
                    .build(),
                GuestPoliciesPackageArgs.builder()
                    .name("bad-package-1")
                    .desiredState("REMOVED")
                    .build(),
                GuestPoliciesPackageArgs.builder()
                    .name("bad-package-2")
                    .desiredState("REMOVED")
                    .manager("APT")
                    .build())
            .packageRepositories(            
                GuestPoliciesPackageRepositoryArgs.builder()
                    .apt(GuestPoliciesPackageRepositoryAptArgs.builder()
                        .uri("https://packages.cloud.google.com/apt")
                        .archiveType("DEB")
                        .distribution("cloud-sdk-stretch")
                        .components("main")
                        .build())
                    .build(),
                GuestPoliciesPackageRepositoryArgs.builder()
                    .yum(GuestPoliciesPackageRepositoryYumArgs.builder()
                        .id("google-cloud-sdk")
                        .displayName("Google Cloud SDK")
                        .baseUrl("https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64")
                        .gpgKeys(                        
                            "https://packages.cloud.google.com/yum/doc/yum-key.gpg",
                            "https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg")
                        .build())
                    .build())
            .build());

    }
}
resources:
  guestPolicies:
    type: gcp:osconfig:GuestPolicies
    name: guest_policies
    properties:
      guestPolicyId: guest-policy
      assignment:
        groupLabels:
          - labels:
              color: red
              env: test
          - labels:
              color: blue
              env: test
      packages:
        - name: my-package
          desiredState: INSTALLED
        - name: bad-package-1
          desiredState: REMOVED
        - name: bad-package-2
          desiredState: REMOVED
          manager: APT
      packageRepositories:
        - apt:
            uri: https://packages.cloud.google.com/apt
            archiveType: DEB
            distribution: cloud-sdk-stretch
            components:
              - main
        - yum:
            id: google-cloud-sdk
            displayName: Google Cloud SDK
            baseUrl: https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64
            gpgKeys:
              - https://packages.cloud.google.com/yum/doc/yum-key.gpg
              - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

The groupLabels array targets VMs that match any of the specified label sets. The packageRepositories block configures APT and YUM repositories before applying package changes, ensuring the package manager can find the software. Each package entry can specify a manager (APT, YUM) or let OS Config detect it automatically.

Install software from GCS artifacts using recipes

When software doesn’t come from package repositories, recipes download artifacts from Cloud Storage and run installation steps.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const guestPolicies = new gcp.osconfig.GuestPolicies("guest_policies", {
    guestPolicyId: "guest-policy",
    assignment: {
        zones: [
            "us-east1-b",
            "us-east1-d",
        ],
    },
    recipes: [{
        name: "guest-policy-recipe",
        desiredState: "INSTALLED",
        artifacts: [{
            id: "guest-policy-artifact-id",
            gcs: {
                bucket: "my-bucket",
                object: "executable.msi",
                generation: 1546030865175603,
            },
        }],
        installSteps: [{
            msiInstallation: {
                artifactId: "guest-policy-artifact-id",
            },
        }],
    }],
});
import pulumi
import pulumi_gcp as gcp

guest_policies = gcp.osconfig.GuestPolicies("guest_policies",
    guest_policy_id="guest-policy",
    assignment={
        "zones": [
            "us-east1-b",
            "us-east1-d",
        ],
    },
    recipes=[{
        "name": "guest-policy-recipe",
        "desired_state": "INSTALLED",
        "artifacts": [{
            "id": "guest-policy-artifact-id",
            "gcs": {
                "bucket": "my-bucket",
                "object": "executable.msi",
                "generation": 1546030865175603,
            },
        }],
        "install_steps": [{
            "msi_installation": {
                "artifact_id": "guest-policy-artifact-id",
            },
        }],
    }])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/osconfig"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := osconfig.NewGuestPolicies(ctx, "guest_policies", &osconfig.GuestPoliciesArgs{
			GuestPolicyId: pulumi.String("guest-policy"),
			Assignment: &osconfig.GuestPoliciesAssignmentArgs{
				Zones: pulumi.StringArray{
					pulumi.String("us-east1-b"),
					pulumi.String("us-east1-d"),
				},
			},
			Recipes: osconfig.GuestPoliciesRecipeArray{
				&osconfig.GuestPoliciesRecipeArgs{
					Name:         pulumi.String("guest-policy-recipe"),
					DesiredState: pulumi.String("INSTALLED"),
					Artifacts: osconfig.GuestPoliciesRecipeArtifactArray{
						&osconfig.GuestPoliciesRecipeArtifactArgs{
							Id: pulumi.String("guest-policy-artifact-id"),
							Gcs: &osconfig.GuestPoliciesRecipeArtifactGcsArgs{
								Bucket:     pulumi.String("my-bucket"),
								Object:     pulumi.String("executable.msi"),
								Generation: pulumi.Int(1546030865175603),
							},
						},
					},
					InstallSteps: osconfig.GuestPoliciesRecipeInstallStepArray{
						&osconfig.GuestPoliciesRecipeInstallStepArgs{
							MsiInstallation: &osconfig.GuestPoliciesRecipeInstallStepMsiInstallationArgs{
								ArtifactId: pulumi.String("guest-policy-artifact-id"),
							},
						},
					},
				},
			},
		})
		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 guestPolicies = new Gcp.OsConfig.GuestPolicies("guest_policies", new()
    {
        GuestPolicyId = "guest-policy",
        Assignment = new Gcp.OsConfig.Inputs.GuestPoliciesAssignmentArgs
        {
            Zones = new[]
            {
                "us-east1-b",
                "us-east1-d",
            },
        },
        Recipes = new[]
        {
            new Gcp.OsConfig.Inputs.GuestPoliciesRecipeArgs
            {
                Name = "guest-policy-recipe",
                DesiredState = "INSTALLED",
                Artifacts = new[]
                {
                    new Gcp.OsConfig.Inputs.GuestPoliciesRecipeArtifactArgs
                    {
                        Id = "guest-policy-artifact-id",
                        Gcs = new Gcp.OsConfig.Inputs.GuestPoliciesRecipeArtifactGcsArgs
                        {
                            Bucket = "my-bucket",
                            Object = "executable.msi",
                            Generation = 1546030865175603,
                        },
                    },
                },
                InstallSteps = new[]
                {
                    new Gcp.OsConfig.Inputs.GuestPoliciesRecipeInstallStepArgs
                    {
                        MsiInstallation = new Gcp.OsConfig.Inputs.GuestPoliciesRecipeInstallStepMsiInstallationArgs
                        {
                            ArtifactId = "guest-policy-artifact-id",
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.osconfig.GuestPolicies;
import com.pulumi.gcp.osconfig.GuestPoliciesArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesAssignmentArgs;
import com.pulumi.gcp.osconfig.inputs.GuestPoliciesRecipeArgs;
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 guestPolicies = new GuestPolicies("guestPolicies", GuestPoliciesArgs.builder()
            .guestPolicyId("guest-policy")
            .assignment(GuestPoliciesAssignmentArgs.builder()
                .zones(                
                    "us-east1-b",
                    "us-east1-d")
                .build())
            .recipes(GuestPoliciesRecipeArgs.builder()
                .name("guest-policy-recipe")
                .desiredState("INSTALLED")
                .artifacts(GuestPoliciesRecipeArtifactArgs.builder()
                    .id("guest-policy-artifact-id")
                    .gcs(GuestPoliciesRecipeArtifactGcsArgs.builder()
                        .bucket("my-bucket")
                        .object("executable.msi")
                        .generation(1546030865175603)
                        .build())
                    .build())
                .installSteps(GuestPoliciesRecipeInstallStepArgs.builder()
                    .msiInstallation(GuestPoliciesRecipeInstallStepMsiInstallationArgs.builder()
                        .artifactId("guest-policy-artifact-id")
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  guestPolicies:
    type: gcp:osconfig:GuestPolicies
    name: guest_policies
    properties:
      guestPolicyId: guest-policy
      assignment:
        zones:
          - us-east1-b
          - us-east1-d
      recipes:
        - name: guest-policy-recipe
          desiredState: INSTALLED
          artifacts:
            - id: guest-policy-artifact-id
              gcs:
                bucket: my-bucket
                object: executable.msi
                generation: 1.546030865175603e+15
          installSteps:
            - msiInstallation:
                artifactId: guest-policy-artifact-id

The assignment block targets VMs by zone. The recipes array defines software to install: artifacts specify GCS locations (bucket, object, generation), and installSteps describe how to install them. Here, msiInstallation runs a Windows MSI installer using the downloaded artifact.

Beyond these examples

These snippets focus on specific guest policy features: VM targeting (instances, labels, zones), package management and repository configuration, and recipe-based software installation from GCS. They’re intentionally minimal rather than full configuration management solutions.

The examples may reference pre-existing infrastructure such as Compute Engine VM instances and GCS buckets with software artifacts. They focus on policy configuration rather than provisioning the underlying infrastructure.

To keep things focused, common guest policy patterns are omitted, including:

  • OS family targeting (osShortName)
  • Instance name prefix/suffix matching
  • Recipe update and removal workflows
  • Package manager-specific options beyond APT/YUM

These omissions are intentional: the goal is to illustrate how each guest policy feature is wired, not provide drop-in configuration management modules. See the OS Config GuestPolicies resource reference for all available configuration options.

Let's configure GCP OS Config Guest Policies

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Policy Assignment & Targeting
How do I target specific VM instances with a guest policy?
Use the assignment field with instances (array of instance IDs), groupLabels (label sets), or zones (array of zone names). You can combine multiple targeting criteria.
What happens if I leave the assignment field empty?
All VM instances underneath the policy are targeted.
What happens if multiple guest policies conflict?
The service prevents creation of multiple policies that conflict with each other at the same resource hierarchy level (within a project). Review your assignment criteria to avoid overlapping policies.
Package Management
What package states can I specify?
You can use INSTALLED (install package), UPDATED (keep package updated), or REMOVED (uninstall package) as the desiredState for each package.
When are package repositories configured?
Package repositories are configured before any other configs are applied, so subsequent package installations can use these repos. Repositories are only configured if the corresponding package manager is available.
Can I specify which package manager to use?
Yes, use the optional manager field (e.g., APT) in the package configuration. If not specified, the system uses the default package manager.
Recipes & Artifacts
How do I install software using recipes?
Configure recipes with artifacts (e.g., GCS objects using gcs.bucket, gcs.object, gcs.generation) and install steps (e.g., msiInstallation with artifactId).
Configuration & Naming
What are the naming rules for guest policy IDs?
The guestPolicyId must contain only lowercase letters, numbers, and hyphens; start with a letter; be 1-63 characters long; end with a number or letter; and be unique within the project.
Can I change the project after creating a guest policy?
No, the project property is immutable. Changing it requires recreating the resource.
What's the maximum length for the policy description?
The description is limited to 1024 characters.

Using a different cloud?

Explore compute guides for other cloud providers: