GCP: невозможно установить метаданные при запуске экземпляра Compute Engine из облачной функции - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь запустить экземпляр Compute Engine в проекте GCP из облачной функции, размещенной в другом проекте GCP. Это работает хорошо, но я не могу добавить вычислительный движок метаданные экземпляра , я получаю код ошибки HTTP 400.

Облачная функция (Node.js, с вычислительным механизмом ) 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

И когда я вхожу в экземпляр Compute Engine с S SH, я не могу прочитать метаданные ' 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

Используемая учетная запись службы Облачной функцией принадлежит роль Compute Admin в GCP, на которой размещен экземпляр Compute Engine.

Чего мне не хватает?

1 Ответ

1 голос
/ 19 апреля 2020

@ Джон Хэнли прав, мне нужно дождаться завершения операции.

Кроме того, даже несмотря на то, что учетной записи службы, используемой облачной функцией, предоставляется роль Compute Admin в проекте GCP, в котором размещен экземпляр Compute Engine, ей также должна быть назначена роль Пользователь учетной записи службы в служебной учетной записи, используемой экземпляром 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();
};
...