Manage GCP Spanner Instance IAM Permissions

The gcp:spanner/instanceIAMBinding:InstanceIAMBinding resource, part of the Pulumi GCP provider, manages IAM role bindings for Spanner instances by setting the complete member list for a specific role. This guide focuses on two capabilities: authoritative role-to-members binding and non-authoritative single-member grants.

InstanceIAMBinding is authoritative for a given role, meaning it replaces the entire member list. Other roles on the instance remain unchanged. InstanceIAMMember adds individual members non-authoritatively. The examples are intentionally small. Combine them with your own Spanner instances and identity management.

Grant a role to multiple members

Teams managing Spanner instances often need to grant database administration access to multiple users or service accounts at once.

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

const instance = new gcp.spanner.InstanceIAMBinding("instance", {
    instance: "your-instance-name",
    role: "roles/spanner.databaseAdmin",
    members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp

instance = gcp.spanner.InstanceIAMBinding("instance",
    instance="your-instance-name",
    role="roles/spanner.databaseAdmin",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := spanner.NewInstanceIAMBinding(ctx, "instance", &spanner.InstanceIAMBindingArgs{
			Instance: pulumi.String("your-instance-name"),
			Role:     pulumi.String("roles/spanner.databaseAdmin"),
			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 instance = new Gcp.Spanner.InstanceIAMBinding("instance", new()
    {
        Instance = "your-instance-name",
        Role = "roles/spanner.databaseAdmin",
        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.spanner.InstanceIAMBinding;
import com.pulumi.gcp.spanner.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 instance = new InstanceIAMBinding("instance", InstanceIAMBindingArgs.builder()
            .instance("your-instance-name")
            .role("roles/spanner.databaseAdmin")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  instance:
    type: gcp:spanner:InstanceIAMBinding
    properties:
      instance: your-instance-name
      role: roles/spanner.databaseAdmin
      members:
        - user:jane@example.com

The members property lists all identities that receive the specified role. InstanceIAMBinding is authoritative for this role: it replaces any existing member list. The role property uses GCP’s predefined role format (e.g., “roles/spanner.databaseAdmin”). Other roles on the instance remain unaffected.

Add a single member to a role

When onboarding individual users or granting access to specific service accounts, you can add one member without affecting others already assigned to the role.

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

const instance = new gcp.spanner.InstanceIAMMember("instance", {
    instance: "your-instance-name",
    role: "roles/spanner.databaseAdmin",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

instance = gcp.spanner.InstanceIAMMember("instance",
    instance="your-instance-name",
    role="roles/spanner.databaseAdmin",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := spanner.NewInstanceIAMMember(ctx, "instance", &spanner.InstanceIAMMemberArgs{
			Instance: pulumi.String("your-instance-name"),
			Role:     pulumi.String("roles/spanner.databaseAdmin"),
			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 instance = new Gcp.Spanner.InstanceIAMMember("instance", new()
    {
        Instance = "your-instance-name",
        Role = "roles/spanner.databaseAdmin",
        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.spanner.InstanceIAMMember;
import com.pulumi.gcp.spanner.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 instance = new InstanceIAMMember("instance", InstanceIAMMemberArgs.builder()
            .instance("your-instance-name")
            .role("roles/spanner.databaseAdmin")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  instance:
    type: gcp:spanner:InstanceIAMMember
    properties:
      instance: your-instance-name
      role: roles/spanner.databaseAdmin
      member: user:jane@example.com

InstanceIAMMember adds a single identity to a role non-authoritatively, preserving existing members. Use member (singular) instead of members (plural). This resource complements InstanceIAMBinding: use Binding to set the full member list for one role, Member to add individuals to other roles.

Beyond these examples

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

The examples reference pre-existing infrastructure such as Spanner instances. 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)
  • Project-level scoping (project property)
  • Full policy replacement (InstanceIAMPolicy)
  • Custom role formatting ([projects|organizations]/{parent}/roles/{name})

These omissions are intentional: the goal is to illustrate how IAM bindings are wired, not provide drop-in access control modules. See the Spanner InstanceIAMBinding resource reference for all available configuration options.

Let's manage GCP Spanner Instance IAM Permissions

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Selection & Conflicts
Can I lock myself out of my Spanner instance with InstanceIAMPolicy?
Yes, gcp.spanner.InstanceIAMPolicy is authoritative and replaces the entire IAM policy. Any default permissions not explicitly included in your config will be removed, potentially locking you out.
Can I use these IAM resources together?
gcp.spanner.InstanceIAMPolicy cannot be used with gcp.spanner.InstanceIAMBinding or gcp.spanner.InstanceIAMMember as they’ll conflict. However, gcp.spanner.InstanceIAMBinding and gcp.spanner.InstanceIAMMember can be used together only if they don’t grant privilege to the same role.
What's the difference between InstanceIAMPolicy, InstanceIAMBinding, and InstanceIAMMember?
gcp.spanner.InstanceIAMPolicy is authoritative and replaces the entire policy. gcp.spanner.InstanceIAMBinding is authoritative for a given role, managing all members for that role while preserving other roles. gcp.spanner.InstanceIAMMember is non-authoritative, adding individual members without affecting other members for the role.
IAM Configuration
What format do I use for custom 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}, principal:{principal}, principalSet:{principalSet}, group:{email}, and domain:{domain}.
Resource Properties
What properties can't I change after creating the resource?
The instance, role, and project properties are all immutable and cannot be changed after creation.
How do I import a resource with a custom role?
Use the full name of the custom role, such as projects/my-project/roles/my-custom-role or organizations/my-org/roles/my-custom-role.

Using a different cloud?

Explore iam guides for other cloud providers: