Manage GCP Spanner Instance IAM Permissions

The gcp:spanner/instanceIAMMember:InstanceIAMMember resource, part of the Pulumi GCP provider, grants IAM permissions to Spanner instances by adding individual members to roles without replacing existing permissions. This guide focuses on two capabilities: non-authoritative single-member grants and role-level member list management.

GCP provides three IAM resources for Spanner instances with different authoritativeness levels. InstanceIAMPolicy replaces the entire policy (and can lock you out). InstanceIAMBinding manages all members for one role. InstanceIAMMember adds individual members without affecting others. The examples reference existing Spanner instances and IAM principals. Combine them with your own instance names and member identities.

Grant a single member access to an instance

Most teams start by granting individual users or service accounts access to Spanner instances without affecting other permissions.

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

The instance property identifies the Spanner instance by name. The role property specifies the IAM role to grant (predefined roles like “roles/spanner.databaseAdmin” or custom roles in the format “[projects|organizations]/{parent-name}/roles/{role-name}”). The member property identifies who receives the permission using formats like “user:jane@example.com” for Google accounts, “serviceAccount:app@project.iam.gserviceaccount.com” for service accounts, or “group:admins@example.com” for groups. This resource is non-authoritative: it adds the member to the role without removing other members.

Manage all members for a single role

When you need to control the complete membership list for a role, InstanceIAMBinding replaces all members for that role while preserving other roles.

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 takes an array of member identities, replacing the complete member list for the specified role. Other roles on the instance remain unchanged. Use this when you want authoritative control over who has a specific role, but InstanceIAMBinding and InstanceIAMMember can coexist as long as they don’t grant the same role.

Beyond these examples

These snippets focus on specific IAM grant features: single-member grants (InstanceIAMMember) and role-level member management (InstanceIAMBinding). They’re intentionally minimal rather than full access control configurations.

The examples reference pre-existing infrastructure such as Spanner instances and IAM principals (users, service accounts, groups). They focus on granting permissions rather than provisioning instances or creating service accounts.

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

  • Conditional IAM bindings (condition property)
  • Full policy replacement (InstanceIAMPolicy)
  • Custom role definitions
  • Project-level configuration (project property)

These omissions are intentional: the goal is to illustrate how each IAM grant type is wired, not provide drop-in access control modules. See the Spanner InstanceIAMMember 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
What's the difference between InstanceIAMPolicy, InstanceIAMBinding, and InstanceIAMMember?
gcp.spanner.InstanceIAMPolicy is authoritative and replaces the entire IAM policy. gcp.spanner.InstanceIAMBinding is authoritative for a specific role, managing all members for that role while preserving other roles. gcp.spanner.InstanceIAMMember is non-authoritative, adding individual members to a role without affecting other members.
Can I lock myself out of my Spanner instance using InstanceIAMPolicy?
Yes. gcp.spanner.InstanceIAMPolicy replaces the entire IAM policy, removing any default permissions not explicitly included in your configuration. Always include all necessary permissions to maintain access.
Which IAM resources can I use together?
gcp.spanner.InstanceIAMPolicy cannot be used with gcp.spanner.InstanceIAMBinding or gcp.spanner.InstanceIAMMember, as they will conflict. However, gcp.spanner.InstanceIAMBinding and gcp.spanner.InstanceIAMMember can be used together only if they don’t grant privileges to the same role.
Configuration & Identity Formats
What member identity formats are supported?

Supported formats include:

  • user:{email} for Google accounts
  • serviceAccount:{email} for service accounts
  • group:{email} for Google groups
  • domain:{domain} for G Suite domains
  • allUsers for anyone on the internet
  • allAuthenticatedUsers for any authenticated user
  • principal:{principal} for federated single identity
  • principalSet:{principalSet} for federated identity groups
What format should I use for custom roles?
Custom roles must use the format [projects|organizations]/{parent-name}/roles/{role-name}.
Immutability & Limitations
Can I modify the instance, role, member, or project after creation?
No. All properties (instance, role, member, project, and condition) are immutable and require resource replacement if changed.
Should I use InstanceIAMBinding or InstanceIAMMember for a single user?
Use gcp.spanner.InstanceIAMMember for adding individual members. Use gcp.spanner.InstanceIAMBinding when you need to manage all members for a role authoritatively (the members array replaces all existing members for that role).
Can I use multiple InstanceIAMBinding resources for the same role?
No. Only one gcp.spanner.InstanceIAMBinding can be used per role, as it authoritatively manages all members for that role. Use gcp.spanner.InstanceIAMMember for adding multiple individual members to the same role.

Using a different cloud?

Explore iam guides for other cloud providers: