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 FREEFrequently Asked Questions
Resource Selection & Conflicts
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.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.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
Supported formats include:
user:{email}for Google accountsserviceAccount:{email}for service accountsgroup:{email}for Google groupsdomain:{domain}for G Suite domainsallUsersfor anyone on the internetallAuthenticatedUsersfor any authenticated userprincipal:{principal}for federated single identityprincipalSet:{principalSet}for federated identity groups
[projects|organizations]/{parent-name}/roles/{role-name}.Immutability & Limitations
instance, role, member, project, and condition) are immutable and require resource replacement if changed.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).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.