Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically get current project id in Google cloud run api

Tags:

I have an API that is containerized and running inside cloud run. How can I get the current project ID where my cloud run is executing? I have tried:

  • I see it in textpayload in logs but I am not sure how to read the textpayload inside the post function? The pub sub message I receive is missing this information.
  • I have read up into querying the metadata api, but it is not very clear on how to do that again from within the api. Any links?

Is there any other way?

Edit:

After some comments below, I ended up with this code inside my .net API running inside Cloud Run.

        private string GetProjectid()
        {
            var projectid = string.Empty;
            try {
                var PATH = "http://metadata.google.internal/computeMetadata/v1/project/project-id";
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("Metadata-Flavor", "Google");
                    projectid = client.GetStringAsync(PATH).Result.ToString();
                }

                Console.WriteLine("PROJECT: " + projectid);
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message + " --- " + ex.ToString());
            }
            return projectid;
        }

Update, it works. My build pushes had been failing and I did not see. Thanks everyone.

like image 386
AIK DO Avatar asked Dec 19 '19 20:12

AIK DO


2 Answers

You get the project ID by sending an GET request to http://metadata.google.internal/computeMetadata/v1/project/project-id with the Metadata-Flavor:Google header.

See this documentation

In Node.js for example:

index.js:

    const express = require('express');
    const axios = require('axios');
    const app = express();
    
    const axiosInstance = axios.create({
      baseURL: 'http://metadata.google.internal/',
      timeout: 1000,
      headers: {'Metadata-Flavor': 'Google'}
    });
    
    app.get('/', (req, res) => {
      let path = req.query.path || 'computeMetadata/v1/project/project-id';
      axiosInstance.get(path).then(response => {
        console.log(response.status)
        console.log(response.data);
        res.send(response.data);
      });
    });
    
    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log('Hello world listening on port', port);
    });

package.json:


    {
      "name": "metadata",
      "version": "1.0.0",
      "description": "Metadata server",
      "main": "app.js",
      "scripts": {
        "start": "node index.js"
      },
      "author": "",
      "license": "Apache-2.0",
      "dependencies": {
        "axios": "^0.18.0",
        "express": "^4.16.4"
      }
    }
like image 135
Steren Avatar answered Sep 27 '22 22:09

Steren


Others have shown how to get the project name via HTTP API, but in my opinion the easier, simpler, and more performant thing to do here is to just set the project ID as a run-time environment variable. To do this, when you deploy the function:

gcloud functions deploy myFunction --set-env-vars PROJECT_ID=my-project-name

And then you would access it in code like:

exports.myFunction = (req, res) => {
  console.log(process.env.PROJECT_ID);
}

You would simply need to set the proper value for each environment where you deploy the function. This has the very minor downside of requiring a one-time command line parameter for each environment, and the very major upside of not making your function depend on successfully authenticating with and parsing an API response. This also provides code portability, because virtually all hosting environments support environment variables, including your local development environment.

like image 21
Matt Korostoff Avatar answered Sep 28 '22 00:09

Matt Korostoff