Manage GCP Bigtable Instance IAM Policies

The gcp:bigtable/instanceIamPolicy:InstanceIamPolicy resource, part of the Pulumi GCP provider, manages IAM access control for Bigtable instances using three distinct approaches: complete policy replacement (InstanceIamPolicy), role-level binding (InstanceIamBinding), or individual member grants (InstanceIamMember). This guide focuses on three capabilities: authoritative policy replacement, role-level member management, and incremental member grants.

These resources reference existing Bigtable instances. InstanceIamPolicy replaces the entire IAM policy and cannot be used with InstanceIamBinding or InstanceIamMember, or they will conflict. InstanceIamBinding and InstanceIamMember can coexist if they manage different roles. The examples are intentionally small. Combine them with your own instance references and member lists.

Replace the entire IAM policy with a complete definition

When you need full control over all IAM bindings, you can define the complete policy in one place and replace any existing configuration.

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

const admin = gcp.organizations.getIAMPolicy({
    bindings: [{
        role: "roles/bigtable.user",
        members: ["user:jane@example.com"],
    }],
});
const editor = new gcp.bigtable.InstanceIamPolicy("editor", {
    project: "your-project",
    instance: "your-bigtable-instance",
    policyData: admin.then(admin => admin.policyData),
});
import pulumi
import pulumi_gcp as gcp

admin = gcp.organizations.get_iam_policy(bindings=[{
    "role": "roles/bigtable.user",
    "members": ["user:jane@example.com"],
}])
editor = gcp.bigtable.InstanceIamPolicy("editor",
    project="your-project",
    instance="your-bigtable-instance",
    policy_data=admin.policy_data)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		admin, err := organizations.LookupIAMPolicy(ctx, &organizations.LookupIAMPolicyArgs{
			Bindings: []organizations.GetIAMPolicyBinding{
				{
					Role: "roles/bigtable.user",
					Members: []string{
						"user:jane@example.com",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		_, err = bigtable.NewInstanceIamPolicy(ctx, "editor", &bigtable.InstanceIamPolicyArgs{
			Project:    pulumi.String("your-project"),
			Instance:   pulumi.String("your-bigtable-instance"),
			PolicyData: pulumi.String(admin.PolicyData),
		})
		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 admin = Gcp.Organizations.GetIAMPolicy.Invoke(new()
    {
        Bindings = new[]
        {
            new Gcp.Organizations.Inputs.GetIAMPolicyBindingInputArgs
            {
                Role = "roles/bigtable.user",
                Members = new[]
                {
                    "user:jane@example.com",
                },
            },
        },
    });

    var editor = new Gcp.BigTable.InstanceIamPolicy("editor", new()
    {
        Project = "your-project",
        Instance = "your-bigtable-instance",
        PolicyData = admin.Apply(getIAMPolicyResult => getIAMPolicyResult.PolicyData),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetIAMPolicyArgs;
import com.pulumi.gcp.bigtable.InstanceIamPolicy;
import com.pulumi.gcp.bigtable.InstanceIamPolicyArgs;
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 admin = OrganizationsFunctions.getIAMPolicy(GetIAMPolicyArgs.builder()
            .bindings(GetIAMPolicyBindingArgs.builder()
                .role("roles/bigtable.user")
                .members("user:jane@example.com")
                .build())
            .build());

        var editor = new InstanceIamPolicy("editor", InstanceIamPolicyArgs.builder()
            .project("your-project")
            .instance("your-bigtable-instance")
            .policyData(admin.policyData())
            .build());

    }
}
resources:
  editor:
    type: gcp:bigtable:InstanceIamPolicy
    properties:
      project: your-project
      instance: your-bigtable-instance
      policyData: ${admin.policyData}
variables:
  admin:
    fn::invoke:
      function: gcp:organizations:getIAMPolicy
      arguments:
        bindings:
          - role: roles/bigtable.user
            members:
              - user:jane@example.com

The getIAMPolicy function constructs a policy document from bindings, which InstanceIamPolicy then applies to the instance. This approach is authoritative: it replaces the entire policy, removing any bindings not defined in policyData. Use this when you want to manage all access from a single source of truth.

Grant a role to multiple members at once

Teams often need to grant the same role to several users without affecting other role assignments.

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

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

editor = gcp.bigtable.InstanceIamBinding("editor",
    instance="your-bigtable-instance",
    role="roles/bigtable.user",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bigtable.NewInstanceIamBinding(ctx, "editor", &bigtable.InstanceIamBindingArgs{
			Instance: pulumi.String("your-bigtable-instance"),
			Role:     pulumi.String("roles/bigtable.user"),
			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 editor = new Gcp.BigTable.InstanceIamBinding("editor", new()
    {
        Instance = "your-bigtable-instance",
        Role = "roles/bigtable.user",
        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.bigtable.InstanceIamBinding;
import com.pulumi.gcp.bigtable.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 editor = new InstanceIamBinding("editor", InstanceIamBindingArgs.builder()
            .instance("your-bigtable-instance")
            .role("roles/bigtable.user")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  editor:
    type: gcp:bigtable:InstanceIamBinding
    properties:
      instance: your-bigtable-instance
      role: roles/bigtable.user
      members:
        - user:jane@example.com

InstanceIamBinding manages all members for a single role. The members array lists everyone who should have this role; anyone not in the list loses access to this role. Other roles on the instance remain unchanged. This is authoritative for the specified role but non-authoritative for the overall policy.

Add a single member to a role incrementally

When you need to grant access to one user without managing the complete member list, incremental grants provide the safest approach.

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

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

editor = gcp.bigtable.InstanceIamMember("editor",
    instance="your-bigtable-instance",
    role="roles/bigtable.user",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bigtable.NewInstanceIamMember(ctx, "editor", &bigtable.InstanceIamMemberArgs{
			Instance: pulumi.String("your-bigtable-instance"),
			Role:     pulumi.String("roles/bigtable.user"),
			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 editor = new Gcp.BigTable.InstanceIamMember("editor", new()
    {
        Instance = "your-bigtable-instance",
        Role = "roles/bigtable.user",
        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.bigtable.InstanceIamMember;
import com.pulumi.gcp.bigtable.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 editor = new InstanceIamMember("editor", InstanceIamMemberArgs.builder()
            .instance("your-bigtable-instance")
            .role("roles/bigtable.user")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  editor:
    type: gcp:bigtable:InstanceIamMember
    properties:
      instance: your-bigtable-instance
      role: roles/bigtable.user
      member: user:jane@example.com

InstanceIamMember adds one member to one role without affecting other members of that role. This is the most granular approach: it only ensures this specific member has this specific role. You can use multiple InstanceIamMember resources for different roles, or combine them with InstanceIamBinding resources that manage different roles.

Beyond these examples

These snippets focus on specific IAM management approaches: authoritative policy replacement, role-level binding management, and incremental member grants. They’re intentionally minimal rather than full access control configurations.

The examples reference pre-existing infrastructure such as Bigtable instances and GCP projects. They focus on IAM binding configuration rather than provisioning the instances themselves.

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

  • Conditional IAM bindings (condition blocks)
  • Service account and group member types
  • Multiple role assignments in a single resource
  • Project-level IAM inheritance

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

Let's manage GCP Bigtable Instance IAM Policies

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?
InstanceIamPolicy is authoritative and replaces the entire IAM policy. InstanceIamBinding is authoritative for a specific role, preserving other roles. InstanceIamMember is non-authoritative and adds a single member to a role without affecting other members.
Can I use these IAM resources together?
No, InstanceIamPolicy cannot be used with InstanceIamBinding or InstanceIamMember, as they’ll conflict over the policy. However, InstanceIamBinding and InstanceIamMember can be used together only if they manage different roles.
Why did I lose access to my Bigtable instance after applying InstanceIamPolicy?
InstanceIamPolicy replaces the entire IAM policy, which can accidentally remove ownership or admin roles if they’re not included in the new policy. Always include all necessary bindings, including ownership roles, when using this resource.
Configuration & Usage
How do I grant a role to multiple members at once?
Use InstanceIamBinding with the members property set to a list of members, such as ["user:jane@example.com", "user:john@example.com"].
How do I add a single member to a role without affecting existing members?
Use InstanceIamMember with the member property. This is non-authoritative and preserves other members already assigned to the role.
Properties & Immutability
Can I change the instance or project after creating the IAM resource?
No, both instance and project are immutable and cannot be changed after creation. You must recreate the resource to target a different instance or project.

Using a different cloud?

Explore security guides for other cloud providers: