Manage IAM Permissions for GCP AI Notebooks

The gcp:notebooks/instanceIamBinding:InstanceIamBinding resource, part of the Pulumi GCP provider, manages IAM role bindings for Cloud AI Notebooks instances by granting a specific role to a list of members. This resource is deprecated; the parent resource gcp.notebooks.Instance is being replaced by gcp.workbench.Instance for new projects. This guide focuses on two capabilities: granting roles to multiple members and adding individual members incrementally.

InstanceIamBinding is authoritative for a given role, meaning it replaces all members for that role while preserving other roles on the instance. The examples reference existing notebook instances. Combine them with your own instance resources and member identities.

Grant a role to multiple members at once

Teams managing notebook access often need to grant the same role to multiple users or service accounts simultaneously.

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

const binding = new gcp.notebooks.InstanceIamBinding("binding", {
    project: instance.project,
    location: instance.location,
    instanceName: instance.name,
    role: "roles/viewer",
    members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp

binding = gcp.notebooks.InstanceIamBinding("binding",
    project=instance["project"],
    location=instance["location"],
    instance_name=instance["name"],
    role="roles/viewer",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := notebooks.NewInstanceIamBinding(ctx, "binding", &notebooks.InstanceIamBindingArgs{
			Project:      pulumi.Any(instance.Project),
			Location:     pulumi.Any(instance.Location),
			InstanceName: pulumi.Any(instance.Name),
			Role:         pulumi.String("roles/viewer"),
			Members: pulumi.StringArray{
				pulumi.String("user:jane@example.com"),
			},
		})
		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 binding = new Gcp.Notebooks.InstanceIamBinding("binding", new()
    {
        Project = instance.Project,
        Location = instance.Location,
        InstanceName = instance.Name,
        Role = "roles/viewer",
        Members = new[]
        {
            "user:jane@example.com",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.notebooks.InstanceIamBinding;
import com.pulumi.gcp.notebooks.InstanceIamBindingArgs;
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 binding = new InstanceIamBinding("binding", InstanceIamBindingArgs.builder()
            .project(instance.project())
            .location(instance.location())
            .instanceName(instance.name())
            .role("roles/viewer")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  binding:
    type: gcp:notebooks:InstanceIamBinding
    properties:
      project: ${instance.project}
      location: ${instance.location}
      instanceName: ${instance.name}
      role: roles/viewer
      members:
        - user:jane@example.com

The role property specifies which IAM role to grant (e.g., “roles/viewer”). The members array lists all identities that should have this role; InstanceIamBinding replaces any existing members for this role with the specified list. The instanceName, location, and project properties identify which notebook instance to configure.

Add a single member to a role incrementally

When you need to grant access to one user without affecting existing members of the same role, use InstanceIamMember to add members individually.

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

const member = new gcp.notebooks.InstanceIamMember("member", {
    project: instance.project,
    location: instance.location,
    instanceName: instance.name,
    role: "roles/viewer",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

member = gcp.notebooks.InstanceIamMember("member",
    project=instance["project"],
    location=instance["location"],
    instance_name=instance["name"],
    role="roles/viewer",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := notebooks.NewInstanceIamMember(ctx, "member", &notebooks.InstanceIamMemberArgs{
			Project:      pulumi.Any(instance.Project),
			Location:     pulumi.Any(instance.Location),
			InstanceName: pulumi.Any(instance.Name),
			Role:         pulumi.String("roles/viewer"),
			Member:       pulumi.String("user:jane@example.com"),
		})
		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 member = new Gcp.Notebooks.InstanceIamMember("member", new()
    {
        Project = instance.Project,
        Location = instance.Location,
        InstanceName = instance.Name,
        Role = "roles/viewer",
        Member = "user:jane@example.com",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.notebooks.InstanceIamMember;
import com.pulumi.gcp.notebooks.InstanceIamMemberArgs;
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 member = new InstanceIamMember("member", InstanceIamMemberArgs.builder()
            .project(instance.project())
            .location(instance.location())
            .instanceName(instance.name())
            .role("roles/viewer")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  member:
    type: gcp:notebooks:InstanceIamMember
    properties:
      project: ${instance.project}
      location: ${instance.location}
      instanceName: ${instance.name}
      role: roles/viewer
      member: user:jane@example.com

The member property (singular) specifies one identity to add to the role. Unlike InstanceIamBinding, this resource is non-authoritative: it adds the member without removing others who already have the role. You can use multiple InstanceIamMember resources for the same role, or combine them with InstanceIamBinding resources as long as they target different roles.

Beyond these examples

These snippets focus on specific IAM binding features: role-based access control and batch vs incremental member management. They’re intentionally minimal rather than full access control configurations.

The examples reference pre-existing infrastructure such as Cloud AI Notebooks instances (gcp.notebooks.Instance). They focus on configuring IAM bindings rather than provisioning the instances themselves.

To keep things focused, common IAM patterns are omitted, including:

  • Conditional IAM bindings (condition property)
  • Custom role definitions and formatting
  • InstanceIamPolicy for full policy replacement
  • Combining Binding and Member resources safely

These omissions are intentional: the goal is to illustrate how each IAM binding approach is wired, not provide drop-in access control modules. See the Notebooks InstanceIamBinding resource reference for all available configuration options.

Let's manage IAM Permissions for GCP AI Notebooks

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Migration & Deprecation
Should I still use gcp.notebooks.Instance for IAM bindings?
No, gcp.notebooks.Instance is deprecated and will be removed in a future major release. Migrate to gcp.workbench.Instance instead.
Resource Selection & Conflicts
What's the difference between InstanceIamPolicy, InstanceIamBinding, and InstanceIamMember?
InstanceIamPolicy is authoritative and replaces the entire IAM policy. InstanceIamBinding is authoritative for a specific role, preserving other roles. InstanceIamMember is non-authoritative, adding a single member to a role while preserving existing members.
Can I use InstanceIamPolicy together with InstanceIamBinding or InstanceIamMember?
No, InstanceIamPolicy cannot be used with InstanceIamBinding or InstanceIamMember because they will conflict over the policy configuration.
Can I use InstanceIamBinding and InstanceIamMember together?
Yes, but only if they don’t grant privileges to the same role. Each role can have only one InstanceIamBinding resource.
Can I create multiple InstanceIamBinding resources for the same role?
No, only one InstanceIamBinding can be used per role. To add multiple members to the same role, include them all in the members array of a single binding, or use InstanceIamMember resources instead.
Configuration & Usage
How do I use custom IAM roles?
Custom roles must use the format [projects|organizations]/{parent-name}/roles/{role-name}, for example projects/my-project/roles/my-custom-role.
What member identity formats are supported?
Supported formats include allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner:{projectid}, projectEditor:{projectid}, projectViewer:{projectid}, and federated identities like principal://iam.googleapis.com/locations/global/workforcePools/....
Do I need to specify project and location explicitly?
Not necessarily. Both project and location can be parsed from the parent resource identifier or taken from the provider configuration if not specified directly.
How do I grant a role to multiple users at once?
Use InstanceIamBinding with a members array containing all the identities, such as members: ["user:jane@example.com", "user:john@example.com"].
Which properties are immutable after creation?
The instanceName, location, project, role, and condition properties are all immutable and cannot be changed after the resource is created.

Using a different cloud?

Explore iam guides for other cloud providers: