Manage GCP BigQuery Analytics Hub Data Exchange IAM Bindings

The gcp:bigqueryanalyticshub/dataExchangeIamBinding:DataExchangeIamBinding resource, part of the Pulumi GCP provider, manages IAM role bindings for BigQuery Analytics Hub data exchanges. This guide focuses on two capabilities: bulk role assignment to multiple members and incremental member addition.

IAM bindings reference existing data exchanges and require valid member identifiers. The examples are intentionally small. Combine them with your own data exchange resources and organizational access patterns.

Grant a role to multiple members at once

Teams managing data exchanges often need to grant the same role to multiple users or service accounts simultaneously, such as giving viewer access to an entire team.

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

const binding = new gcp.bigqueryanalyticshub.DataExchangeIamBinding("binding", {
    project: dataExchange.project,
    location: dataExchange.location,
    dataExchangeId: dataExchange.dataExchangeId,
    role: "roles/viewer",
    members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp

binding = gcp.bigqueryanalyticshub.DataExchangeIamBinding("binding",
    project=data_exchange["project"],
    location=data_exchange["location"],
    data_exchange_id=data_exchange["dataExchangeId"],
    role="roles/viewer",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bigqueryanalyticshub.NewDataExchangeIamBinding(ctx, "binding", &bigqueryanalyticshub.DataExchangeIamBindingArgs{
			Project:        pulumi.Any(dataExchange.Project),
			Location:       pulumi.Any(dataExchange.Location),
			DataExchangeId: pulumi.Any(dataExchange.DataExchangeId),
			Role:           pulumi.String("roles/viewer"),
			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 binding = new Gcp.BigQueryAnalyticsHub.DataExchangeIamBinding("binding", new()
    {
        Project = dataExchange.Project,
        Location = dataExchange.Location,
        DataExchangeId = dataExchange.DataExchangeId,
        Role = "roles/viewer",
        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.bigqueryanalyticshub.DataExchangeIamBinding;
import com.pulumi.gcp.bigqueryanalyticshub.DataExchangeIamBindingArgs;
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 binding = new DataExchangeIamBinding("binding", DataExchangeIamBindingArgs.builder()
            .project(dataExchange.project())
            .location(dataExchange.location())
            .dataExchangeId(dataExchange.dataExchangeId())
            .role("roles/viewer")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  binding:
    type: gcp:bigqueryanalyticshub:DataExchangeIamBinding
    properties:
      project: ${dataExchange.project}
      location: ${dataExchange.location}
      dataExchangeId: ${dataExchange.dataExchangeId}
      role: roles/viewer
      members:
        - user:jane@example.com

The DataExchangeIamBinding resource is authoritative for the specified role: it replaces all members for that role with the list you provide. The members array accepts various identity formats including user emails, service accounts, groups, and domains. The role property specifies which permission set to grant, and dataExchangeId identifies the target data exchange.

Add a single member to a role incrementally

When onboarding individual users or service accounts, you often want to add them to an existing role without affecting other members.

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

const member = new gcp.bigqueryanalyticshub.DataExchangeIamMember("member", {
    project: dataExchange.project,
    location: dataExchange.location,
    dataExchangeId: dataExchange.dataExchangeId,
    role: "roles/viewer",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

member = gcp.bigqueryanalyticshub.DataExchangeIamMember("member",
    project=data_exchange["project"],
    location=data_exchange["location"],
    data_exchange_id=data_exchange["dataExchangeId"],
    role="roles/viewer",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := bigqueryanalyticshub.NewDataExchangeIamMember(ctx, "member", &bigqueryanalyticshub.DataExchangeIamMemberArgs{
			Project:        pulumi.Any(dataExchange.Project),
			Location:       pulumi.Any(dataExchange.Location),
			DataExchangeId: pulumi.Any(dataExchange.DataExchangeId),
			Role:           pulumi.String("roles/viewer"),
			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 member = new Gcp.BigQueryAnalyticsHub.DataExchangeIamMember("member", new()
    {
        Project = dataExchange.Project,
        Location = dataExchange.Location,
        DataExchangeId = dataExchange.DataExchangeId,
        Role = "roles/viewer",
        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.bigqueryanalyticshub.DataExchangeIamMember;
import com.pulumi.gcp.bigqueryanalyticshub.DataExchangeIamMemberArgs;
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 member = new DataExchangeIamMember("member", DataExchangeIamMemberArgs.builder()
            .project(dataExchange.project())
            .location(dataExchange.location())
            .dataExchangeId(dataExchange.dataExchangeId())
            .role("roles/viewer")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  member:
    type: gcp:bigqueryanalyticshub:DataExchangeIamMember
    properties:
      project: ${dataExchange.project}
      location: ${dataExchange.location}
      dataExchangeId: ${dataExchange.dataExchangeId}
      role: roles/viewer
      member: user:jane@example.com

The DataExchangeIamMember resource adds a single member to a role non-authoritatively, preserving other members who already have that role. This is useful when you manage access grants separately or when different teams control different member assignments. Use member (singular) instead of members (plural) to specify the identity.

Beyond these examples

These snippets focus on specific IAM binding features: role-based access control and bulk and incremental member assignment. They’re intentionally minimal rather than full access management solutions.

The examples reference pre-existing infrastructure such as BigQuery Analytics Hub data exchanges. They focus on configuring IAM bindings rather than provisioning the data exchanges themselves.

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

  • Conditional IAM bindings (condition property)
  • Policy-level management (DataExchangeIamPolicy resource)
  • Custom role definitions
  • Cross-project or cross-organization access patterns

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

Let's manage GCP BigQuery Analytics Hub Data Exchange IAM Bindings

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 DataExchangeIamPolicy, DataExchangeIamBinding, and DataExchangeIamMember?
DataExchangeIamPolicy is authoritative and replaces the entire IAM policy. DataExchangeIamBinding is authoritative for a specific role but preserves other roles. DataExchangeIamMember is non-authoritative and preserves other members for the same role.
Can I use DataExchangeIamPolicy with DataExchangeIamBinding or DataExchangeIamMember?
No. DataExchangeIamPolicy cannot be used with DataExchangeIamBinding or DataExchangeIamMember because they will conflict over the policy configuration.
Can I use DataExchangeIamBinding and DataExchangeIamMember together?
Yes, but only if they don’t grant privileges to the same role. Using both for the same role will cause conflicts.
Which IAM resource should I use?
Use DataExchangeIamPolicy for complete policy control, DataExchangeIamBinding to manage all members for a specific role, or DataExchangeIamMember to add individual members without affecting others.
IAM Configuration
What member identity formats are supported?
Supported formats include allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner:{projectid}, projectEditor:{projectid}, projectViewer:{projectid}, and federated identities like principal://iam.googleapis.com/....
How do I specify custom roles?
Custom roles must use the full format [projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/my-custom-role.
How do I grant a role to multiple users at once?
Use DataExchangeIamBinding with an array of members in the members property, as shown in the Binding example with ["user:jane@example.com"].
Resource Properties
What properties can't I change after creating the resource?
The dataExchangeId, location, project, role, and condition properties are immutable and cannot be changed after creation.
How do I import existing IAM bindings?
Use space-delimited identifiers: for bindings, specify the resource identifier and role; for members, add the member identity. For example, pulumi import gcp:bigqueryanalyticshub/dataExchangeIamBinding:DataExchangeIamBinding editor "projects/{{project}}/locations/{{location}}/dataExchanges/{{data_exchange_id}} roles/viewer".

Using a different cloud?

Explore security guides for other cloud providers: