The gcp:servicedirectory/serviceIamBinding:ServiceIamBinding resource, part of the Pulumi GCP provider, manages IAM role bindings for Service Directory services. This guide focuses on two capabilities: granting roles to multiple members and adding individual members to roles.
IAM bindings reference existing Service Directory services. The examples are intentionally small. Combine them with your own Service Directory namespaces and services.
Grant a role to multiple members
Teams managing Service Directory services grant IAM roles to groups of users, service accounts, or other principals.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const binding = new gcp.servicedirectory.ServiceIamBinding("binding", {
name: example.name,
role: "roles/viewer",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
binding = gcp.servicedirectory.ServiceIamBinding("binding",
name=example["name"],
role="roles/viewer",
members=["user:jane@example.com"])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/servicedirectory"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := servicedirectory.NewServiceIamBinding(ctx, "binding", &servicedirectory.ServiceIamBindingArgs{
Name: pulumi.Any(example.Name),
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.ServiceDirectory.ServiceIamBinding("binding", new()
{
Name = example.Name,
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.servicedirectory.ServiceIamBinding;
import com.pulumi.gcp.servicedirectory.ServiceIamBindingArgs;
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 ServiceIamBinding("binding", ServiceIamBindingArgs.builder()
.name(example.name())
.role("roles/viewer")
.members("user:jane@example.com")
.build());
}
}
resources:
binding:
type: gcp:servicedirectory:ServiceIamBinding
properties:
name: ${example.name}
role: roles/viewer
members:
- user:jane@example.com
The role property specifies which permission set to grant (e.g., “roles/viewer”). The members array lists all principals who receive that role. ServiceIamBinding is authoritative for the specified role: it replaces any existing member list for that role, but preserves other roles on the service.
Add a single member to a role
When onboarding individual users or service accounts, ServiceIamMember adds one principal without affecting others.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.servicedirectory.ServiceIamMember("member", {
name: example.name,
role: "roles/viewer",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.servicedirectory.ServiceIamMember("member",
name=example["name"],
role="roles/viewer",
member="user:jane@example.com")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/servicedirectory"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := servicedirectory.NewServiceIamMember(ctx, "member", &servicedirectory.ServiceIamMemberArgs{
Name: pulumi.Any(example.Name),
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.ServiceDirectory.ServiceIamMember("member", new()
{
Name = example.Name,
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.servicedirectory.ServiceIamMember;
import com.pulumi.gcp.servicedirectory.ServiceIamMemberArgs;
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 ServiceIamMember("member", ServiceIamMemberArgs.builder()
.name(example.name())
.role("roles/viewer")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:servicedirectory:ServiceIamMember
properties:
name: ${example.name}
role: roles/viewer
member: user:jane@example.com
The member property (singular) specifies one principal to grant access. Unlike ServiceIamBinding, ServiceIamMember is non-authoritative: it adds the specified member without removing others already granted the same role. Use ServiceIamMember when you need incremental access grants; use ServiceIamBinding when you want to define the complete member list for a role.
Beyond these examples
These snippets focus on specific IAM binding features: role-based access control and member management (binding vs individual). They’re intentionally minimal rather than full access control configurations.
The examples reference pre-existing infrastructure such as Service Directory services (namespace and service must exist). They focus on configuring IAM bindings rather than provisioning the services themselves.
To keep things focused, common IAM patterns are omitted, including:
- Conditional IAM bindings (condition property)
- Custom role definitions and formatting
- ServiceIamPolicy for full policy replacement
- Federated identity and workload identity pool configuration
These omissions are intentional: the goal is to illustrate how IAM bindings are wired, not provide drop-in access control modules. See the Service Directory ServiceIamBinding resource reference for all available configuration options.
Let's manage GCP Service Directory IAM Bindings
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
ServiceIamPolicy cannot be used with ServiceIamBinding or ServiceIamMember, as they will fight over the policy. Additionally, ServiceIamBinding and ServiceIamMember conflict if they grant privilege to the same role.ServiceIamPolicy is authoritative and replaces the entire IAM policy. ServiceIamBinding is authoritative for a specific role, preserving other roles in the policy. ServiceIamMember is non-authoritative, adding a single member to a role while preserving other members for that role.Configuration & Roles
[projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/my-custom-role or organizations/my-org/roles/my-custom-role.role property is immutable. You must destroy and recreate the resource to change the role.Supported formats include:
allUsersorallAuthenticatedUsersfor public/authenticated accessuser:{email},serviceAccount:{email},group:{email}for specific identitiesdomain:{domain}for G Suite domainsprojectOwner/Editor/Viewer:{projectid}for project-level rolesprincipal://...for federated identities (workload/workforce pools)