0
votes

How can I trigger a Cloud Function from Cloud Tasks when that function has its ingress settings set to "allow internal only"?

With that setting, the function rejects the incoming HTTP traffic from Cloud Tasks. This behavior occurs even if Cloud Tasks is in the same project as the function.

2

2 Answers

1
votes

It's funny because I asked Google PMs exactly about that on Tuesday this week! Because today you can't! It's in the radar of the PMs, with not timeline but it will be possible, a day.

My solution today.

If I have a cloud function in internal only mode which is used internally AND externally (or by Google serverless products not compliant with VPC connector, like Cloud Task, Cloud Scheduler, PubSub and Workflows), I create a "proxy function"

  • This proxy function is deployed in ingress=all mode and with no-allow-unauthenticated param
  • I grant only the service account of the external product on it as cloudfunctions.invoker on the proxy function to be sure that only this service account will be able to call the proxy function
  • I create a serverless VPC connector and add it to the proxy function
  • The proxy function only call the internal function.
-2
votes

Hello @guillaume & @Thomas, I am facing challenge to invoke cloud Function from cloud task. Here are details of my IAM & Code:

const { CloudTasksClient } = require('@google-cloud/tasks');
const client = new CloudTasksClient();

//See https://cloud.google.com/tasks/docs/tutorial-gcf
module.exports = async (payload, scheduleTimeInSec) => {
  const project = process.env.GOOGLE_APPLICATION_PROJECTID;
  const queue = process.env.QUEUE_NAME;
  const location = process.env.QUEUE_LOCATION;
  const callBackUrl = https://asia-south2-trial-288318.cloudfunctions.net/cloud-function-node-expres/;

  // Construct the fully qualified queue name.
  const parent = client.queuePath(project, location, queue);

  const body = Buffer.from(JSON.stringify(payload)).toString('base64');

  const task = {
    httpRequest: {
      httpMethod: 'POST',
      url: callBackUrl,
      headers: { 'Content-Type': 'application/json' },
      body
    },
    scheduleTime: {
      seconds: scheduleTimeInSec,
    }
  };

  if (process.env.GOOGLE_APPLICATION_SERVICE_ACCOUNT_EMAIL) {
    task.httpRequest.oidcToken = {
      serviceAccountEmail: process.env.GOOGLE_APPLICATION_SERVICE_ACCOUNT_EMAIL
    }
  }

  const request = {
    parent: parent,
    task: task,
  };

  // Send create task request.
  try {
    let [responses] = await client.createTask(request);

    return ({ sts: true, taskName: responses.name, msg: "Email Schedule Task Created" })
  }
  catch (e) {
    return ({ sts: true, err: true, errInfo: e, msg: "Unable to Schedule Task. Internal Error." })
  }
}

The process.env.GOOGLE_APPLICATION_SERVICE_ACCOUNT_EMAIL has Cloud Functions Invoker role and the Cloud Function has allAuthenticatedUsers member with role Cloud Functions Invoker as per the doc.

But still I am seeing the 401 resposnse recevied by Cloud Task and Cloud Function is not getting called(See below image):

enter image description here

Any comment on this, whats going wrong here