3

I am deploying a Google Cloud Function from another Cloud Function with Python. See my code below:

import requests
import json


def make_func(request):


    # Get the access token from the metadata server
    metadata_server_token_url = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token?scopes=https://www.googleapis.com/auth/cloud-platform'
    token_request_headers = {'Metadata-Flavor': 'Google'}
    token_response = requests.get(metadata_server_token_url, headers=token_request_headers)
    token_response_decoded = token_response.content.decode("utf-8")
    jwt = json.loads(token_response_decoded)['access_token']

    # Use the api to create the function
    response = requests.post('https://cloudfunctions.googleapis.com/v1/projects/myproject/locations/us-central1/functions',
                               json={"name":"projects/my-project/locations/us-central1/functions/funct","runtime":"python37","sourceArchiveUrl":"gs://bucket/main.zip","entryPoint":"hello_world","httpsTrigger": {} },
                               headers={'Accept': 'application/json', 
                                        'Content-Type': 'application/json',
                                        'Authorization': 'Bearer {}'.format(jwt)} )   
    if response:
         return 'Success! Function Created'
    else:
         return str(response.json())  

However this function does not have "allow unauthenticated" on automatically. Thus, no requests from outside are allowed. How can I change my Python code to add this functionality when deploying the new function?

Thanks

2 Answers 2

3

You'll need to additionally give the allUsers member the Cloud Functions Invoker role:

from googleapiclient.discovery import build
service = build('cloudfunctions', 'v1')

project_id = ...
location_id = ...
function_id = ...
resource = f'projects/{project_id}/locations/{location_id}/functions/{function_id}'

set_iam_policy_request_body = {
    'policy': {
        "bindings": [
            {
              "role": "roles/cloudfunctions.invoker",
              "members": ["allUsers"],
            },
        ],
    },
}

request = service.projects().locations().functions().setIamPolicy(
    resource=resource,
    body=set_iam_policy_request_body,
)
response = request.execute()

print(response)

This uses the google-api-python-client package.

Sign up to request clarification or add additional context in comments.

5 Comments

Do you know how I can do this in Python?
Thanks. But this is to create a role in the project right? How do I bind it to the function I created?
Updated my answer with a complete example. You can also use this API service to deploy the function instead of manually getting the tokens and creating an HTTP request: cloud.google.com/functions/docs/reference/rest/v1/…
@SiemPeters, no, it binds on the function. Look at the resource name projects/{project_id}/locations/{location_id}/functions/{function_id}. It's not all the functions of the project, only this one with the function_id in the defined location
2

In addition of Dustin answer, you have to know that the --allow-unauthenticated is for developer convenience. Under the hood it perform 2 things

  • Deploy your function in private mode
  • Add allUsers as member with Cloudfunction.invoker role
gcloud functions add-iam-policy-binding --member=allUsers --role=roles/cloudfunctions.invoker function-1

So, indeed, use the google-cloud-iam library for doing this.

In addition, your current code don't work because you use an access token to reach Cloud Function.

  • Indeed, you have an authorized error (401) -> You present an authorization header, but it's not authorize.
  • Without the header, you get a 403 error -> unauthenticated.

Anyway, you need to have a signed identity token. You have description and python code snippet here

3 Comments

Thank you. Do you know how to do do the policy binding in Python?
Thanks @Dustin-Ingram
how can I use iam_v2beta to achieve the same?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.