The gcp:bigtable/tableIamPolicy:TableIamPolicy resource, part of the Pulumi GCP provider, manages IAM policies for Bigtable tables, controlling who can read, write, or administer table data. This guide focuses on three approaches: authoritative policy replacement (TableIamPolicy), role-based grants (TableIamBinding), and member-based grants (TableIamMember).
These resources reference existing Bigtable tables and instances. TableIamPolicy replaces the entire policy, TableIamBinding manages all members for a specific role, and TableIamMember adds individual members to roles. The examples are intentionally small. Combine them with your own table and instance infrastructure.
Replace the entire IAM policy for a table
When you need complete control over table permissions, you can set the entire IAM policy at once, replacing any existing permissions.
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.TableIamPolicy("editor", {
project: "your-project",
instanceName: "your-bigtable-instance",
table: "your-bigtable-table",
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.TableIamPolicy("editor",
project="your-project",
instance_name="your-bigtable-instance",
table="your-bigtable-table",
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.NewTableIamPolicy(ctx, "editor", &bigtable.TableIamPolicyArgs{
Project: pulumi.String("your-project"),
InstanceName: pulumi.String("your-bigtable-instance"),
Table: pulumi.String("your-bigtable-table"),
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.TableIamPolicy("editor", new()
{
Project = "your-project",
InstanceName = "your-bigtable-instance",
Table = "your-bigtable-table",
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.TableIamPolicy;
import com.pulumi.gcp.bigtable.TableIamPolicyArgs;
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 TableIamPolicy("editor", TableIamPolicyArgs.builder()
.project("your-project")
.instanceName("your-bigtable-instance")
.table("your-bigtable-table")
.policyData(admin.policyData())
.build());
}
}
resources:
editor:
type: gcp:bigtable:TableIamPolicy
properties:
project: your-project
instanceName: your-bigtable-instance
table: your-bigtable-table
policyData: ${admin.policyData}
variables:
admin:
fn::invoke:
function: gcp:organizations:getIAMPolicy
arguments:
bindings:
- role: roles/bigtable.user
members:
- user:jane@example.com
The TableIamPolicy resource sets the complete IAM policy using policyData from getIAMPolicy. This approach is authoritative: it replaces all existing permissions on the table. The table and instanceName properties identify which table to manage. Be careful not to accidentally remove your own access when replacing the entire policy.
Grant a role to multiple members at once
Teams often need to grant the same role to several users or service accounts without affecting other roles on the table.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const editor = new gcp.bigtable.TableIamBinding("editor", {
table: "your-bigtable-table",
instanceName: "your-bigtable-instance",
role: "roles/bigtable.user",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
editor = gcp.bigtable.TableIamBinding("editor",
table="your-bigtable-table",
instance_name="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.NewTableIamBinding(ctx, "editor", &bigtable.TableIamBindingArgs{
Table: pulumi.String("your-bigtable-table"),
InstanceName: 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.TableIamBinding("editor", new()
{
Table = "your-bigtable-table",
InstanceName = "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.TableIamBinding;
import com.pulumi.gcp.bigtable.TableIamBindingArgs;
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 TableIamBinding("editor", TableIamBindingArgs.builder()
.table("your-bigtable-table")
.instanceName("your-bigtable-instance")
.role("roles/bigtable.user")
.members("user:jane@example.com")
.build());
}
}
resources:
editor:
type: gcp:bigtable:TableIamBinding
properties:
table: your-bigtable-table
instanceName: your-bigtable-instance
role: roles/bigtable.user
members:
- user:jane@example.com
The TableIamBinding resource grants a specific role to a list of members. Unlike TableIamPolicy, this approach is authoritative only for the specified role; other roles on the table remain unchanged. The members array can include users, service accounts, and groups. You cannot use TableIamBinding and TableIamPolicy together, as they will conflict over policy ownership.
Add a single member to a role incrementally
When you need to grant access to one additional user without modifying existing permissions, non-authoritative member grants let you add permissions incrementally.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const editor = new gcp.bigtable.TableIamMember("editor", {
table: "your-bigtable-table",
instanceName: "your-bigtable-instance",
role: "roles/bigtable.user",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
editor = gcp.bigtable.TableIamMember("editor",
table="your-bigtable-table",
instance_name="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.NewTableIamMember(ctx, "editor", &bigtable.TableIamMemberArgs{
Table: pulumi.String("your-bigtable-table"),
InstanceName: 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.TableIamMember("editor", new()
{
Table = "your-bigtable-table",
InstanceName = "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.TableIamMember;
import com.pulumi.gcp.bigtable.TableIamMemberArgs;
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 TableIamMember("editor", TableIamMemberArgs.builder()
.table("your-bigtable-table")
.instanceName("your-bigtable-instance")
.role("roles/bigtable.user")
.member("user:jane@example.com")
.build());
}
}
resources:
editor:
type: gcp:bigtable:TableIamMember
properties:
table: your-bigtable-table
instanceName: your-bigtable-instance
role: roles/bigtable.user
member: user:jane@example.com
The TableIamMember resource adds a single member to a role without affecting other members. This is the most granular approach: multiple TableIamMember resources can grant the same role to different members, and they won’t conflict with each other. You can combine TableIamMember with TableIamBinding as long as they don’t grant the same role.
Beyond these examples
These snippets focus on specific IAM management approaches: authoritative and non-authoritative IAM management, and role-based and member-based grants. They’re intentionally minimal rather than full access control configurations.
The examples reference pre-existing infrastructure such as Bigtable tables and instances. They focus on configuring IAM policies rather than provisioning the tables themselves.
To keep things focused, common IAM patterns are omitted, including:
- Project specification (uses provider default)
- Conditional IAM bindings
- Service account creation and management
- Custom role definitions
These omissions are intentional: the goal is to illustrate how each IAM resource type is wired, not provide drop-in access control modules. See the Bigtable TableIamPolicy resource reference for all available configuration options.
Let's manage GCP Bigtable IAM Policies
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
TableIamPolicy is authoritative and replaces the entire IAM policy. TableIamBinding is authoritative for a specific role but preserves other roles. TableIamMember is non-authoritative and adds a single member to a role while preserving other members.TableIamPolicy cannot be used with TableIamBinding or TableIamMember because they’ll conflict over the policy configuration.TableIamPolicy replaces the entire policy, so you could lose access if you don’t include existing ownership permissions in your policy data. Always ensure all necessary permissions are included.Configuration & Usage
gcp.organizations.getIAMPolicy to generate policy data with bindings, then pass the result to the policyData property.role property and provide an array of members in the members property.role property and provide a single member string in the member property.Import & Special Cases
[projects/my-project|organizations/my-org]/roles/my-custom-role.