Manage GCP Cloud Tasks Queue IAM Access

The gcp:cloudtasks/queueIamMember:QueueIamMember resource, part of the Pulumi GCP provider, grants IAM permissions to Cloud Tasks queues by adding individual members to roles. This guide focuses on three capabilities: adding single identities to roles, managing complete member lists per role, and replacing entire IAM policies.

These resources reference existing Cloud Tasks queues. QueueIamPolicy cannot be used with QueueIamBinding or QueueIamMember, as they conflict over policy control. QueueIamBinding and QueueIamMember can coexist only if they manage different roles. The examples are intentionally small. Combine them with your own queue infrastructure and identity management.

Grant a single identity access to a queue

Most IAM configurations add one user or service account to a role without affecting other permissions.

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

const member = new gcp.cloudtasks.QueueIamMember("member", {
    project: _default.project,
    location: _default.location,
    name: _default.name,
    role: "roles/viewer",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

member = gcp.cloudtasks.QueueIamMember("member",
    project=default["project"],
    location=default["location"],
    name=default["name"],
    role="roles/viewer",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := cloudtasks.NewQueueIamMember(ctx, "member", &cloudtasks.QueueIamMemberArgs{
			Project:  pulumi.Any(_default.Project),
			Location: pulumi.Any(_default.Location),
			Name:     pulumi.Any(_default.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.CloudTasks.QueueIamMember("member", new()
    {
        Project = @default.Project,
        Location = @default.Location,
        Name = @default.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.cloudtasks.QueueIamMember;
import com.pulumi.gcp.cloudtasks.QueueIamMemberArgs;
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 QueueIamMember("member", QueueIamMemberArgs.builder()
            .project(default_.project())
            .location(default_.location())
            .name(default_.name())
            .role("roles/viewer")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  member:
    type: gcp:cloudtasks:QueueIamMember
    properties:
      project: ${default.project}
      location: ${default.location}
      name: ${default.name}
      role: roles/viewer
      member: user:jane@example.com

The member property specifies the identity in the format user:email, serviceAccount:email, group:email, or domain:name. The role property sets the permission level. QueueIamMember is non-authoritative: it adds this member to the role while preserving other members and roles on the queue.

Grant multiple identities the same role

When several identities need identical permissions, QueueIamBinding manages the complete member list for one role.

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

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

binding = gcp.cloudtasks.QueueIamBinding("binding",
    project=default["project"],
    location=default["location"],
    name=default["name"],
    role="roles/viewer",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := cloudtasks.NewQueueIamBinding(ctx, "binding", &cloudtasks.QueueIamBindingArgs{
			Project:  pulumi.Any(_default.Project),
			Location: pulumi.Any(_default.Location),
			Name:     pulumi.Any(_default.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.CloudTasks.QueueIamBinding("binding", new()
    {
        Project = @default.Project,
        Location = @default.Location,
        Name = @default.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.cloudtasks.QueueIamBinding;
import com.pulumi.gcp.cloudtasks.QueueIamBindingArgs;
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 QueueIamBinding("binding", QueueIamBindingArgs.builder()
            .project(default_.project())
            .location(default_.location())
            .name(default_.name())
            .role("roles/viewer")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  binding:
    type: gcp:cloudtasks:QueueIamBinding
    properties:
      project: ${default.project}
      location: ${default.location}
      name: ${default.name}
      role: roles/viewer
      members:
        - user:jane@example.com

The members property lists all identities that should have this role. QueueIamBinding is authoritative for the specified role: it replaces any existing members for that role while preserving other roles on the queue. If you later remove an identity from the members list, Pulumi revokes their access.

Replace the entire IAM policy for a queue

Some deployments require complete control over all IAM bindings, replacing any existing policy.

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.cloudtasks.QueueIamPolicy("policy", {
    project: _default.project,
    location: _default.location,
    name: _default.name,
    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.cloudtasks.QueueIamPolicy("policy",
    project=default["project"],
    location=default["location"],
    name=default["name"],
    policy_data=admin.policy_data)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/cloudtasks"
	"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 = cloudtasks.NewQueueIamPolicy(ctx, "policy", &cloudtasks.QueueIamPolicyArgs{
			Project:    pulumi.Any(_default.Project),
			Location:   pulumi.Any(_default.Location),
			Name:       pulumi.Any(_default.Name),
			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.CloudTasks.QueueIamPolicy("policy", new()
    {
        Project = @default.Project,
        Location = @default.Location,
        Name = @default.Name,
        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.cloudtasks.QueueIamPolicy;
import com.pulumi.gcp.cloudtasks.QueueIamPolicyArgs;
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 QueueIamPolicy("policy", QueueIamPolicyArgs.builder()
            .project(default_.project())
            .location(default_.location())
            .name(default_.name())
            .policyData(admin.policyData())
            .build());

    }
}
resources:
  policy:
    type: gcp:cloudtasks:QueueIamPolicy
    properties:
      project: ${default.project}
      location: ${default.location}
      name: ${default.name}
      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 as role-to-members mappings. QueueIamPolicy is fully authoritative: it removes any IAM bindings not defined in the policy. This approach provides the most control but requires managing all permissions in one place. For incremental changes, use QueueIamMember or QueueIamBinding instead.

Beyond these examples

These snippets focus on specific IAM management approaches: single-member grants, role-level member lists, and complete policy replacement. They’re intentionally minimal rather than full access control configurations.

The examples reference pre-existing infrastructure such as Cloud Tasks queues and a GCP project with configured location. They focus on granting permissions rather than provisioning queues or managing identities.

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

  • Conditional IAM bindings (condition property)
  • Custom role definitions
  • Federated identity configuration
  • 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 Tasks QueueIamMember resource reference for all available configuration options.

Let's manage GCP Cloud Tasks Queue IAM Access

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
Can I use QueueIamPolicy together with QueueIamBinding or QueueIamMember?
No, QueueIamPolicy cannot be used with QueueIamBinding or QueueIamMember as they will conflict over the policy configuration.
Can I use QueueIamBinding and QueueIamMember together?
Yes, but only if they manage different roles. Using both resources for the same role will cause conflicts.
What's the difference between QueueIamPolicy, QueueIamBinding, and QueueIamMember?
QueueIamPolicy is authoritative and replaces the entire IAM policy. QueueIamBinding is authoritative for a specific role, replacing all members for that role while preserving other roles. QueueIamMember is non-authoritative, adding a single member to a role without affecting other members.
Which IAM resource should I use for my use case?
Use QueueIamPolicy for complete policy control, QueueIamBinding to manage all members for specific roles, or QueueIamMember to add individual members without affecting existing permissions.
Identity & Role Configuration
What member identity formats are supported?
Supported formats include allUsers, allAuthenticatedUsers, user:{emailid}, serviceAccount:{emailid}, group:{emailid}, domain:{domain}, projectOwner:projectid, projectEditor:projectid, projectViewer:projectid, and federated identities (e.g., principal://iam.googleapis.com/...).
How do I grant access to a single user?
Use QueueIamMember with member set to user:{emailid}, such as user:jane@example.com.
How do I use custom IAM roles?
Custom roles must use the format [projects|organizations]/{parent-name}/roles/{role-name} in the role property.
Resource Management
What happens if I change a property after creation?
All properties (location, member, name, project, role, condition) are immutable and require resource replacement if changed.
What import formats are supported?
Four formats are supported: projects/{{project}}/locations/{{location}}/queues/{{name}}, {{project}}/{{location}}/{{name}}, {{location}}/{{name}}, or {{name}}. Variables not specified in the import command are taken from the provider configuration.
How do I import an existing IAM member binding?
Use space-delimited identifiers with the queue resource, role, and member identity: pulumi import gcp:cloudtasks/queueIamMember:QueueIamMember editor "projects/{{project}}/locations/{{location}}/queues/{{queue}} roles/viewer user:jane@example.com".

Using a different cloud?

Explore security guides for other cloud providers: