Pankaj
Pankaj

Reputation: 2708

Setting up pub/sub subscription across different project?

In my GCP project (project A) I have created a Pub/sub topic (topicA) and messages published in this pub/sub topic needs to be consumed in other GCP project (project B) by Subscription (subscriptionB).

What's the recommended way of setting up subscriptionB ?

  1. Define subscriptionB in project A and add service account from project B with appropriate IAM permission.
  2. Define subscriptionB in project B. In cloud console it's possible to attach subscription from different topic by granting pubsub.topic.attachSubscription (shown below).

Is approach 2 even possible ? If yes, then when to use approach 2 and what all needs to be done for approach 2 ?

enter image description here

Upvotes: 5

Views: 7356

Answers (2)

Yves
Yves

Reputation: 227

  • A Google Cloud Function can't be triggered by a subsription to a topic of another project (since you can't subscribe to another project's topic).

  • But a Google Cloud Function can publish to a topic of another project (and then subscribers of this topic will be triggered).

I solved it by establishing a Google Cloud Function in the original project which listens to the original topic and reacts with publishing to a new topic in the other project. Therefore, the service account ([email protected]) of this function "in the middle" needs to be authorized by the new topic (console.cloud.google.com/cloudpubsub/topic/detail/...?project=...), i.e. add principal with role: "Pub/Sub Publisher"

enter image description here

import base64
import json
import os

from google.cloud import pubsub_v1


#https://cloud.google.com/functions/docs/calling/pubsub?hl=en#publishing_a_message_from_within_a_function


# Instantiates a Pub/Sub client
publisher = pubsub_v1.PublisherClient()

def notify(event, context):
    project_id = os.environ.get('project_id')  
    topic_name = os.environ.get('topic_name')  

    # References an existing topic
    topic_path = publisher.topic_path(project_id, topic_name)  

    message_json = json.dumps({
        'data': {'message': 'here would be the message'},  # or you can pass the message of event/context
    })
    message_bytes = message_json.encode('utf-8')

    # Publishes a message
    try:
        publish_future = publisher.publish(topic_path, data=message_bytes)
        publish_future.result()  # Verify the publish succeeded
        return 'Message published.'
    except Exception as e:
        print(e)
        return (e, 500)

Upvotes: 0

guillaume blaquiere
guillaume blaquiere

Reputation: 75990

The 2 approach are possible, and there is also a 3rd one.

  1. use the role roles/pubsub.subscriber on the service account of the projectB, on the subscription (or the project) of the project A
  2. You need to have the role roles/pubsub.subscriber on the topic that you want (or the project) on the project A. As defined in the message, you need, at least the permission pubsub.topics.attachSubscription on the topic (or the project). For this, you can create a custom role if you want to grant only this permission and not the 2 others of the role roles/pubsub.subscriber
  3. The third solution is based on the solution 1, create a subscription in the project A, but a Push subscription, and push the messages to a HTTP endpoint. No authentication required in the Project B this time. However, if you want to protect your HTTP endpoint (for example deployed on Cloud Run or Cloud Functions), you will need, in the push subscription in the projectA, to have the correct authorization to call the endpoint in projectB

Upvotes: 7

Related Questions