The gcp:endpoints/serviceIamPolicy:ServiceIamPolicy resource, part of the Pulumi GCP provider, manages IAM policies for Cloud Endpoints services. This guide focuses on three approaches: authoritative policy replacement, role-level member management, and incremental member addition.
The ServiceIamPolicy, ServiceIamBinding, and ServiceIamMember resources provide different levels of control. ServiceIamPolicy replaces the entire policy; ServiceIamBinding manages all members for a specific role; ServiceIamMember adds individual members. All three reference an existing Cloud Endpoints service. The examples are intentionally small. Combine them with your own service definitions and organizational access patterns.
Replace the entire IAM policy for a service
When you need complete control over service access, ServiceIamPolicy replaces the entire IAM policy with your 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.endpoints.ServiceIamPolicy("policy", {
serviceName: endpointsService.serviceName,
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.endpoints.ServiceIamPolicy("policy",
service_name=endpoints_service["serviceName"],
policy_data=admin.policy_data)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/endpoints"
"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 = endpoints.NewServiceIamPolicy(ctx, "policy", &endpoints.ServiceIamPolicyArgs{
ServiceName: pulumi.Any(endpointsService.ServiceName),
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.Endpoints.ServiceIamPolicy("policy", new()
{
ServiceName = endpointsService.ServiceName,
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.endpoints.ServiceIamPolicy;
import com.pulumi.gcp.endpoints.ServiceIamPolicyArgs;
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 ServiceIamPolicy("policy", ServiceIamPolicyArgs.builder()
.serviceName(endpointsService.serviceName())
.policyData(admin.policyData())
.build());
}
}
resources:
policy:
type: gcp:endpoints:ServiceIamPolicy
properties:
serviceName: ${endpointsService.serviceName}
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 output from getIAMPolicy, which defines bindings between roles and members. ServiceIamPolicy is authoritative: it removes any permissions not specified in your policy. The serviceName property identifies which Cloud Endpoints service to configure.
Grant a role to multiple members at once
Teams often grant the same role to several users while preserving other role assignments.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const binding = new gcp.endpoints.ServiceIamBinding("binding", {
serviceName: endpointsService.serviceName,
role: "roles/viewer",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
binding = gcp.endpoints.ServiceIamBinding("binding",
service_name=endpoints_service["serviceName"],
role="roles/viewer",
members=["user:jane@example.com"])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/endpoints"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := endpoints.NewServiceIamBinding(ctx, "binding", &endpoints.ServiceIamBindingArgs{
ServiceName: pulumi.Any(endpointsService.ServiceName),
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.Endpoints.ServiceIamBinding("binding", new()
{
ServiceName = endpointsService.ServiceName,
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.endpoints.ServiceIamBinding;
import com.pulumi.gcp.endpoints.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()
.serviceName(endpointsService.serviceName())
.role("roles/viewer")
.members("user:jane@example.com")
.build());
}
}
resources:
binding:
type: gcp:endpoints:ServiceIamBinding
properties:
serviceName: ${endpointsService.serviceName}
role: roles/viewer
members:
- user:jane@example.com
ServiceIamBinding manages all members for a specific role. The members array lists users, groups, or service accounts. This resource is authoritative for its role: it replaces the member list but leaves other roles unchanged. You can use multiple ServiceIamBinding resources for different roles on the same service.
Add a single member to a role incrementally
When multiple teams manage access independently, ServiceIamMember adds individual members without coordinating full member lists.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.endpoints.ServiceIamMember("member", {
serviceName: endpointsService.serviceName,
role: "roles/viewer",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.endpoints.ServiceIamMember("member",
service_name=endpoints_service["serviceName"],
role="roles/viewer",
member="user:jane@example.com")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/endpoints"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := endpoints.NewServiceIamMember(ctx, "member", &endpoints.ServiceIamMemberArgs{
ServiceName: pulumi.Any(endpointsService.ServiceName),
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.Endpoints.ServiceIamMember("member", new()
{
ServiceName = endpointsService.ServiceName,
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.endpoints.ServiceIamMember;
import com.pulumi.gcp.endpoints.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()
.serviceName(endpointsService.serviceName())
.role("roles/viewer")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:endpoints:ServiceIamMember
properties:
serviceName: ${endpointsService.serviceName}
role: roles/viewer
member: user:jane@example.com
ServiceIamMember is non-authoritative: it adds one member to a role without affecting existing members. The member property uses GCP’s identity format (user:, serviceAccount:, group:, domain:). Multiple ServiceIamMember resources can grant the same role to different members.
Beyond these examples
These snippets focus on specific IAM management approaches: authoritative vs non-authoritative updates, and policy-level, role-level, and member-level control. They’re intentionally minimal rather than full access control systems.
The examples reference pre-existing infrastructure such as a Cloud Endpoints service (serviceName reference). They focus on IAM configuration rather than service provisioning.
To keep things focused, common IAM patterns are omitted, including:
- IAM conditions for time-based or attribute-based access
- Audit logging configuration (auditConfigs)
- Custom role definitions
- Service account creation and management
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 Cloud Endpoints ServiceIamPolicy resource reference for all available configuration options.
Let's manage GCP Cloud Endpoints 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 Conflicts & Compatibility
gcp.endpoints.ServiceIamPolicy cannot be used with gcp.endpoints.ServiceIamBinding or gcp.endpoints.ServiceIamMember because they’ll conflict over policy state.Resource Selection & Configuration
Choose based on your needs:
- ServiceIamPolicy - Authoritative; replaces the entire IAM policy
- ServiceIamBinding - Authoritative for a specific role; preserves other roles
- ServiceIamMember - Non-authoritative; adds a single member while preserving others
gcp.organizations.getIAMPolicy data source to generate policyData, as shown in the examples.serviceName is immutable and cannot be changed after creation.Import & Custom Roles
projects/my-project/roles/my-custom-role or organizations/my-org/roles/my-custom-role.