google-cloud-platformgoogle-cloud-pubsubgoogle-iamgoogle-deployment-manager

setIamPolicy for pubsub topics (at the resource level not project)


I'm using deployment manager to set the IAM policy of an existing pub/sub topic- I don't want to acquire it and I cannot create it with deployment manager (because it exists). So I want to set a policy on an existing resource

I can do this with buckets but the docs are confusing and I can't find the right methods for buckets

I want to do this (resource level bindings) for a topic instead of bucket:

resources:
  - name: mybucket
    action: gcp-types/storage-v1:storage.buckets.setIamPolicy
    properties:
      bucket: mybucket
      bindings:
        - role: roles/storage.admin
          members:
          - "serviceAccount:sdfsfds@sdfsdf.com"

I can only find gcp-types/pubsub-v1:projects.topics.setIamPolicy which seems like its at the project level? What is the right api for setting an IAM policy on a specific topic?

The google APIs seem inconsistent here- are these too methods equivalent? Docs are confusing: https://cloud.google.com/storage/docs/json_api/v1/buckets/setIamPolicy https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.topics/setIamPolicy

I attempted this but getting an error:

  - name: mytopic
    action: gcp-types/pubsub-v1:pubsub.projects.topics.setIamPolicy
    properties:
      resource: mytopic
      bindings:
        - role: roles/pubsub.admin
          members:
          - "serviceAccount:ssdfsdf@sdfsdf.com"

Getting error:

message: '{"ResourceType":"gcp-types/pubsub-v1:pubsub.projects.topics.setIamPolicy","ResourceErrorCode":"400","ResourceErrorMessage":{"code":400,"message":"Invalid
    JSON payload received. Unknown name \"bindings\": Cannot find field.","status":"INVALID_ARGUMENT","details":[{"@type":"type.googleapis.com/google.rpc.BadRequest","fieldViolations":[{"description":"Invalid
    JSON payload received. Unknown name \"bindings\": Cannot find field."}]}],"statusMessage":"Bad
    Request","requestPath":"https://pubsub.googleapis.com/v1/projects/myproject/topics/mytopic:setIamPolicy","httpMethod":"POST"}}

When I tried projects.topics.setIamPolicy I got:

- code: COLLECTION_NOT_FOUND
  message: Collection 'projects.topics.setIamPolicy' not found in discovery doc 'https://pubsub.googleapis.com/$discovery/rest?version=v1'

Solution

  • The pubsub-v1:projects.topics.setIamPolicy is at the topic level and the https://iam.googleapis.com/v1/{resource=projects/*/serviceAccounts/*}:setIamPolicy is to set the a Pub/Sub or other resources at the project level.

    You get those error because you are giving Pub/Sub admin and this is a role at the project level. The example roles you can provide are:

    I understand that you are trying to to deploy a topic having a IAM policy that allows only one service account to a topic. You have to use a yaml file and a python file if that is the environment you are using.

    In the python file you will set the IAM for the topic with the method "set_iam_policy" which takes 2 arguments, the policy and the topic path:

    client = pubsub_v1.PublisherClient()
    topic_path = client.topic_path(project, topic_name)
    
    policy = client.get_iam_policy(topic_path)
    
    # Add all users as viewers.
    policy.bindings.add(
        role='roles/pubsub.viewer',
        members=['allUsers'])
    
    # Add a group as a publisher.
    policy.bindings.add(
        role='roles/pubsub.publisher',
        members=['group:cloud-logs@google.com'])
    
    # Set the policy
    policy = client.set_iam_policy(topic_path, policy)
    
    print('IAM policy for topic {} set: {}'.format(
        topic_name, policy))
    

    For deployment manager:

    imports:
      - path: templates/pubsub/pubsub.py
        name: pubsub.py
    
    resources:
      - name: test-pubsub
        type: pubsub.py
        properties:
          topic: test-topic
          accessControl:
            - role: roles/pubsub.subscriber
              members:
                - user:demo@user.com
          subscriptions:
            - name: first-subscription
              accessControl:
                - role: roles/pubsub.subscriber
                  members:
                   - user:demo@user.com
            - name: second-subscription
              ackDeadlineSeconds: 15