The gcp:dataplex/aspectTypeIamMember:AspectTypeIamMember resource, part of the Pulumi GCP provider, manages IAM access for Dataplex AspectType resources by granting roles to members. This guide focuses on three capabilities: non-authoritative single-member grants, authoritative role bindings, and complete policy replacement.
These resources reference existing AspectType resources and require the Dataplex API to be enabled. The examples are intentionally small. Combine them with your own AspectType resources and access requirements. Note that AspectTypeIamPolicy cannot be used alongside AspectTypeIamBinding or AspectTypeIamMember, as they will conflict over policy state.
Grant a role to a single member non-authoritatively
When adding access for individual users or service accounts, you often need to grant permissions without affecting other members who already have the same role.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.dataplex.AspectTypeIamMember("member", {
project: testAspectTypeBasic.project,
location: testAspectTypeBasic.location,
aspectTypeId: testAspectTypeBasic.aspectTypeId,
role: "roles/viewer",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.dataplex.AspectTypeIamMember("member",
project=test_aspect_type_basic["project"],
location=test_aspect_type_basic["location"],
aspect_type_id=test_aspect_type_basic["aspectTypeId"],
role="roles/viewer",
member="user:jane@example.com")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/dataplex"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := dataplex.NewAspectTypeIamMember(ctx, "member", &dataplex.AspectTypeIamMemberArgs{
Project: pulumi.Any(testAspectTypeBasic.Project),
Location: pulumi.Any(testAspectTypeBasic.Location),
AspectTypeId: pulumi.Any(testAspectTypeBasic.AspectTypeId),
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.DataPlex.AspectTypeIamMember("member", new()
{
Project = testAspectTypeBasic.Project,
Location = testAspectTypeBasic.Location,
AspectTypeId = testAspectTypeBasic.AspectTypeId,
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.dataplex.AspectTypeIamMember;
import com.pulumi.gcp.dataplex.AspectTypeIamMemberArgs;
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 AspectTypeIamMember("member", AspectTypeIamMemberArgs.builder()
.project(testAspectTypeBasic.project())
.location(testAspectTypeBasic.location())
.aspectTypeId(testAspectTypeBasic.aspectTypeId())
.role("roles/viewer")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:dataplex:AspectTypeIamMember
properties:
project: ${testAspectTypeBasic.project}
location: ${testAspectTypeBasic.location}
aspectTypeId: ${testAspectTypeBasic.aspectTypeId}
role: roles/viewer
member: user:jane@example.com
The member property specifies a single identity using formats like user:jane@example.com, serviceAccount:app@project.iam.gserviceaccount.com, or group:team@example.com. This resource adds the member to the role without modifying other members who already have it. The aspectTypeId, location, and project properties identify which AspectType to grant access to.
Grant a role to multiple members authoritatively
When managing team access, you need to define the complete list of members for a specific role, ensuring the role has exactly the members you specify.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const binding = new gcp.dataplex.AspectTypeIamBinding("binding", {
project: testAspectTypeBasic.project,
location: testAspectTypeBasic.location,
aspectTypeId: testAspectTypeBasic.aspectTypeId,
role: "roles/viewer",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
binding = gcp.dataplex.AspectTypeIamBinding("binding",
project=test_aspect_type_basic["project"],
location=test_aspect_type_basic["location"],
aspect_type_id=test_aspect_type_basic["aspectTypeId"],
role="roles/viewer",
members=["user:jane@example.com"])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/dataplex"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := dataplex.NewAspectTypeIamBinding(ctx, "binding", &dataplex.AspectTypeIamBindingArgs{
Project: pulumi.Any(testAspectTypeBasic.Project),
Location: pulumi.Any(testAspectTypeBasic.Location),
AspectTypeId: pulumi.Any(testAspectTypeBasic.AspectTypeId),
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.DataPlex.AspectTypeIamBinding("binding", new()
{
Project = testAspectTypeBasic.Project,
Location = testAspectTypeBasic.Location,
AspectTypeId = testAspectTypeBasic.AspectTypeId,
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.dataplex.AspectTypeIamBinding;
import com.pulumi.gcp.dataplex.AspectTypeIamBindingArgs;
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 AspectTypeIamBinding("binding", AspectTypeIamBindingArgs.builder()
.project(testAspectTypeBasic.project())
.location(testAspectTypeBasic.location())
.aspectTypeId(testAspectTypeBasic.aspectTypeId())
.role("roles/viewer")
.members("user:jane@example.com")
.build());
}
}
resources:
binding:
type: gcp:dataplex:AspectTypeIamBinding
properties:
project: ${testAspectTypeBasic.project}
location: ${testAspectTypeBasic.location}
aspectTypeId: ${testAspectTypeBasic.aspectTypeId}
role: roles/viewer
members:
- user:jane@example.com
The members property takes an array of identities, replacing any existing members for this role. Other roles on the AspectType remain unchanged. This differs from AspectTypeIamMember, which adds members incrementally; AspectTypeIamBinding defines the complete membership list for one role.
Replace the entire IAM policy authoritatively
Organizations with centralized access control sometimes need to define the complete IAM policy for a resource, replacing any existing configuration.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const admin = gcp.organizations.getIAMPolicy({
bindings: [{
role: "roles/viewer",
members: ["user:jane@example.com"],
}],
});
const policy = new gcp.dataplex.AspectTypeIamPolicy("policy", {
project: testAspectTypeBasic.project,
location: testAspectTypeBasic.location,
aspectTypeId: testAspectTypeBasic.aspectTypeId,
policyData: admin.then(admin => admin.policyData),
});
import pulumi
import pulumi_gcp as gcp
admin = gcp.organizations.get_iam_policy(bindings=[{
"role": "roles/viewer",
"members": ["user:jane@example.com"],
}])
policy = gcp.dataplex.AspectTypeIamPolicy("policy",
project=test_aspect_type_basic["project"],
location=test_aspect_type_basic["location"],
aspect_type_id=test_aspect_type_basic["aspectTypeId"],
policy_data=admin.policy_data)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/dataplex"
"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/viewer",
Members: []string{
"user:jane@example.com",
},
},
},
}, nil)
if err != nil {
return err
}
_, err = dataplex.NewAspectTypeIamPolicy(ctx, "policy", &dataplex.AspectTypeIamPolicyArgs{
Project: pulumi.Any(testAspectTypeBasic.Project),
Location: pulumi.Any(testAspectTypeBasic.Location),
AspectTypeId: pulumi.Any(testAspectTypeBasic.AspectTypeId),
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/viewer",
Members = new[]
{
"user:jane@example.com",
},
},
},
});
var policy = new Gcp.DataPlex.AspectTypeIamPolicy("policy", new()
{
Project = testAspectTypeBasic.Project,
Location = testAspectTypeBasic.Location,
AspectTypeId = testAspectTypeBasic.AspectTypeId,
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.dataplex.AspectTypeIamPolicy;
import com.pulumi.gcp.dataplex.AspectTypeIamPolicyArgs;
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/viewer")
.members("user:jane@example.com")
.build())
.build());
var policy = new AspectTypeIamPolicy("policy", AspectTypeIamPolicyArgs.builder()
.project(testAspectTypeBasic.project())
.location(testAspectTypeBasic.location())
.aspectTypeId(testAspectTypeBasic.aspectTypeId())
.policyData(admin.policyData())
.build());
}
}
resources:
policy:
type: gcp:dataplex:AspectTypeIamPolicy
properties:
project: ${testAspectTypeBasic.project}
location: ${testAspectTypeBasic.location}
aspectTypeId: ${testAspectTypeBasic.aspectTypeId}
policyData: ${admin.policyData}
variables:
admin:
fn::invoke:
function: gcp:organizations:getIAMPolicy
arguments:
bindings:
- role: roles/viewer
members:
- user:jane@example.com
The policyData property accepts a complete IAM policy document, typically retrieved from gcp.organizations.getIAMPolicy. This replaces the entire policy, including all roles and members. AspectTypeIamPolicy cannot coexist with AspectTypeIamBinding or AspectTypeIamMember resources on the same AspectType, as they will conflict over policy state.
Beyond these examples
These snippets focus on specific IAM management approaches: incremental member grants, authoritative role bindings, and complete policy replacement. They’re intentionally minimal rather than full access control configurations.
The examples reference pre-existing infrastructure such as Dataplex AspectType resources and a GCP project with the Dataplex API enabled. They focus on configuring IAM access rather than provisioning the AspectTypes themselves.
To keep things focused, common IAM patterns are omitted, including:
- Conditional IAM bindings (condition property)
- Custom role definitions
- Organization-level or folder-level policies
- Policy retrieval via data sources
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 AspectTypeIamMember resource reference for all available configuration options.
Let's manage GCP Dataplex AspectType IAM Access
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
AspectTypeIamPolicy is authoritative and replaces the entire IAM policy. AspectTypeIamBinding is authoritative for a specific role, preserving other roles. AspectTypeIamMember is non-authoritative, adding a single member to a role while preserving other members.AspectTypeIamPolicy cannot be used with AspectTypeIamBinding or AspectTypeIamMember as they will conflict over policy management.AspectTypeIamPolicy for complete policy control, AspectTypeIamBinding to manage all members for a specific role, or AspectTypeIamMember to add individual members without affecting others.Identity & Role Configuration
allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner/Editor/Viewer:{projectid}, or federated identities like principal://iam.googleapis.com/....[projects|organizations]/{parent-name}/roles/{role-name}, for example projects/my-project/roles/my-custom-role.aspectTypeId, location, member, project, and role. Changes require resource replacement.Import & Operations
projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}}, {{project}}/{{location}}/{{aspect_type_id}}, {{location}}/{{aspect_type_id}}, or just {{aspect_type_id}}. Missing values are taken from the provider configuration.pulumi import gcp:dataplex/aspectTypeIamMember:AspectTypeIamMember editor "projects/{{project}}/locations/{{location}}/aspectTypes/{{aspect_type_id}} roles/viewer user:jane@example.com".