GCP:从 Cloud Function 启动 Compute Engine 实例时无法设置元数据

GCP: Cannot set metadata when starting Compute Engine instance from Cloud Function

我正在尝试从另一个 GCP 项目中托管的 Cloud Functions 启动一个 GCP 项目中的 Compute Engine 实例。它运行良好,但我无法添加计算引擎 instance metadata,我收到 HTTP 错误代码 400。

云函数(Node.js,与compute engine client):

const Compute = require('@google-cloud/compute');
const compute = new Compute({
  projectId: 'myGcpProject'
});

exports.startVmInstance = async (data, context, callback) => {
  let zone = compute.zone('us-central1-a');
  let vm = zone.vm('myVmInstance');
  let metadata = {
    'myMeta': 'myValue'
  };

  // THIS PART HAS NO EFFECT IN THE COMPUTE ENGINE INSTANCE
  await vm.setMetadata(metadata).then((response) => {
    console.info('Set metadata response: ' + JSON.stringify(response[1]));
  }).catch((error) => {
    throw 'Error while setting metadata to VM instance: ' + error;
  });

  await vm.start().then(() => {
    console.info('Compute Engine instance started successfully');
  }).catch(error => {
    throw 'Error while starting Compute Engine instance: ' + error;
  });

  callback();
};

日志:

- Function execution took 2235 ms, finished with status: 'ok'
- Compute Engine instance started successfully 
- Set metadata response: {"id":"84345484841776xxxxx","name":"operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5","zone":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a","operationType":"setMetadata","targetLink":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a/instances/myVmInstance","targetId":"48593751438611xxxxx","status":"RUNNING","user":"cloud-function@myCloudFunctionGcpProject.iam.gserviceaccount.com","progress":0,"insertTime":"2020-04-17T18:57:28.704-07:00","startTime":"2020-04-17T18:57:28.721-07:00","selfLink":"https://www.googleapis.com/compute/v1/projects/myGcpProject/zones/us-central1-a/operations/operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5","kind":"compute#operation"} 
- Function execution started

当我使用 SSH 登录 Compute Engine 实例时,我无法读取元数据 'myMeta'(只有我默认拥有的启动脚本):

$ gcloud compute instances describe myVmInstance
...
metadata:
  fingerprint: 0ay6MSNkjI8=
  items:
  - key: startup-script
    value: |-
      #!/bin/bash
      echo `date`
  kind: compute#metadata
...

我可以看到该操作,但我收到 HTTP 错误代码 400

$ gcloud compute operations list | grep operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5
operation-1587175048337-5a386fcf3d737-36e59a28-332a95f5    setMetadata    us-central1-a/instances/myVmInstance  400          DONE    2020-04-17T18:57:28.704-07:00

Cloud Functions 使用的服务帐户在托管 Compute Engine 实例的 GCP 中具有 Compute Admin 角色。

我错过了什么?

@John Hanley 说的对,我需要等待手术完成。

此外,即使 Cloud Functions 使用的服务帐户在托管 Compute Engine 实例的 GCP 项目上被授予 Compute Admin 角色,它也需要在服务帐户上被授予角色 Service Account User由 Compute Engine 实例使用。

否则我会得到下面的错误

Error: The user does not have access to service account '661830xxxxxx-compute@developer.gserviceaccount.com'. User: 'cloud-function@myCloudFunctionGcpProject.iam.gserviceaccount.com'. Ask a project owner to grant you the iam.serviceAccountUser role on the service account

云函数代码(Node.js):

const Compute = require('@google-cloud/compute');
const compute = new Compute({
  projectId: 'myGcpProject'
});

exports.startVmInstance = async (data, context, callback) => {
  let zone = compute.zone('us-central1-a');
  let vm = zone.vm('myVmInstance');
  let metadata = {
    'myMeta': 'myValue'
  };

  let setMetadataOperation;
  await vm.setMetadata(metadata).then((response) => {
    setMetadataOperation = response[0];
    console.info('Set metadata response: ' + JSON.stringify(response[1]));
  }).catch((error) => {
    throw 'Error while setting metadata to VM instance: ' + error;
  });

  await setMetadataOperation.promise().then(() => {
    console.info('The operation setMetadata successfully completed');
  }).catch((error) => {
    throw 'Error with the operation setMetadata: ' + error;
  });

  await vm.start().then(() => {
    console.info('Compute Engine instance started successfully');
  }).catch(error => {
    throw 'Error while starting Compute Engine instance: ' + error;
  });

  callback();
};