NodeJS: aws -sdk sts.assumeRole не работает - PullRequest
0 голосов
/ 31 января 2020

У меня странная проблема, когда я не могу go где-либо с. Я следил за всем в Интернете (несколько уроков и т. Д. c), но не могу заставить sts.assumeRole работать.

Мои настройки:

  • Основная AWS учетная запись (используется для выставления счетов, IAM et c)
  • Sub AWS учетная запись 1 (используется для клиента 1)
  • Sub AWS учетная запись 2 (используется для клиента 2)
  • et c

У меня есть бот, работающий в Sub AWS аккаунт 1 , где мне нужна информация о ценах из Main AWS account .

Итак, я создал роль в Main AWS account , чтобы иметь AWS ce: * доступ, ниже:

{
    "Version": "2012-10-17",
    "Statement": [{
            "Effect": "Allow",
            "Action": ["ce:*"],
            "Resource": ["*"]
        }]
}

Доверительные отношения

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com",
        "AWS": "arn:aws:iam::SubAWSaccount1-ID:role/instance-profile"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Теперь это экземпляр-профиль , прикрепленный к экземпляру EC2, работающему на Sub AWS учётная запись 1 :

"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor1",
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::mainAWSaccount-ID:role/botRole"
    }
  ]
}

Доверительные отношения

{
  "Version": "2012-10-17",
  "Statement": [
   {
    "Sid": "",
    "Effect": "Allow",
    "Principal": {
      "Service": "ec2.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
   }
  ]
}

Хорошо, что это не так, этот код не работает:

var AWS = require('aws-sdk');
var pricingAWS = new AWS.CostExplorer();

var getPricing = function(){

    var costParams = {
        TimePeriod: { Start: "2019-12-01 ", End: "2020-01-01"},
        Granularity: 'MONTHLY',
        Metrics: ['BlendedCost'],
        Filter: {      
            Dimensions: {
                Key: "LINKED_ACCOUNT",
                Values: ["Sub AWS account 2s ID"] //Main AWS account has access to many sub accounts info. So bot in running on Sub account 1, I need info from Sub account 1, 2, 3 etc and Role is on Main account
            }
        }
    };

    var roleToAssume = {
        RoleArn: 'arn:aws:iam::mainAWSaccount-ID:role/botRole',
        RoleSessionName: 'testTestTest',
        DurationSeconds: 900
    };

    var roleCreds = {};

    sts.assumeRole(roleToAssume, function(err, data) {
        if (err) {
            console.log(err);
        } else {
            roleCreds = {
                accessKeyId: data.Credentials.AccessKeyId,
                secretAccessKey: data.Credentials.SecretAccessKey,
                sessionToken: data.Credentials.SessionToken
            };

            pricingAWS.config.update({
                accessKeyId: roleCreds.AccessKeyId,
                secretAccessKey: roleCreds.SecretAccessKey,
                sessionToken: roleCreds.SessionToken
              });
        }
    });

    pricingAWS.getCostAndUsage(costParams, function (err, data) {
        if (err) {
            reject(err);
        }else{
            resolve(data);
        }
    });
};

getPricing();

Что я получаю из console.log (err):

* 104 9 *

1 Ответ

1 голос
/ 31 января 2020

чтобы подтвердить мое понимание, вы пытаетесь принять роль в одной учетной записи из экземпляра ec2 в другой учетной записи.

  1. создать роль IAM в учетной записи child
  2. . Позвольте вновь созданной роли, указанной выше, предположить, что роль существует в учетной записи main, подключив политику IAM. Разрешить дочерней роли принимать основную роль через политику доверия основной роли (вы уже делаете это)
  3. В вашем коде Nodejs, запущенном в дочернем экземпляре ec2, примите родительскую роль и прочитайте отчеты по выставлению счетов (вы уже делаете это)

исправление кода

Переместите строку pricingAWS.getCostAndUsage() в функцию обратного вызова допустимой роли. потому что линия вызывается до обновления учетных данных :). Вы также можете изменить все на async / await, как я показал ниже.

import AWS = require('aws-sdk');
var pricingAWS = new AWS.CostExplorer();
const sts = new AWS.STS()

var getPricing = async function () {

  var costParams = {
    TimePeriod: { Start: "2019-12-01 ", End: "2020-01-01" },
    Granularity: 'MONTHLY',
    Metrics: ['BlendedCost'],
    Filter: {
      Dimensions: {
        Key: "LINKED_ACCOUNT",
        Values: ["Sub AWS account 2s ID"] //Main AWS account has access to many sub accounts info. So bot in running on Sub account 1, I need info from Sub account 1, 2, 3 etc and Role is on Main account
      }
    }
  };

  var roleToAssume = {
    RoleArn: 'arn:aws:iam::mainAWSaccount-ID:role/botRole',
    RoleSessionName: 'testTestTest',
    DurationSeconds: 900
  };

  var roleCreds = {};


  try {

    const data = await sts.assumeRole(roleToAssume).promise();
    const roleCreds = {
      accessKeyId: data.Credentials.AccessKeyId,
      secretAccessKey: data.Credentials.SecretAccessKey,
      sessionToken: data.Credentials.SessionToken
    };

    pricingAWS.config.update({
      accessKeyId: roleCreds.accessKeyId,
      secretAccessKey: roleCreds.secretAccessKey,
      sessionToken: roleCreds.sessionToken
    });

    const costAndUsage = await pricingAWS.getCostAndUsage(costParams).promise()
    return costAndUsage
  } catch (err) {
    console.log('error: ', err);
    throw err;
  }

};

getPricing();

надеюсь, это поможет.

...