別のAWSアカウントのorganizations,CostExplorerの情報をLambda(python)で取得する方法


結論

下記ドキュメントを参照。。。。。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-function-assume-iam-role/

読んでも全然わからん状態なので、
取得したい情報があるアカウント(アカウントA)と
それを渡したいアカウント(アカウントB)がある状態でやってみた

アカウントA側の処理

1.アカウントAでlambda用のロールを作成する

2.ロールに情報を取得するための必要なポリシーをアタッチ

CostExplorerFullAccess、AWSOrganizationsFullAccessなど

3.ロールの概要の信頼関係タブの信頼関係の編集を押す。

4.下記ポリシーを張り付け、更新する。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::アカウントBのアカウント番号:role/service-role/アカウントBのロールの名前"
        ],
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

アカウントB側の処理(IAM)

1.アカウントBのロール作成、必要な権限を与える。

とりあえずAdministratorAccessを与えておく

2.ロールの概要のアクセス権限タブから、インラインポリシーの追加を押す

3.Jsonタブをクリック、インラインポリシーとして下記を張り付けポリシーの確認を押し適応する

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::アカウントAのアカウント番号:role/アカウントAのロールの名前"
    }
}

アカウントB側の処理(lambda)

boto3のドキュメントに取得方法が詳しく書いてある。
詳しくは下記を参照。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/organizations.html
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ce.html#CostExplorer.Client.get_cost_forecast
https://docs.aws.amazon.com/aws-cost-management/latest/APIReference/API_GetCostAndUsage.html

import boto3

def lambda_handler(event, context):

  #他アカウントAWSリソースへのアクセスに使用するセキュリティ認証情報のセットを取得
  sts_connection = boto3.client('sts')
    acct_b = sts_connection.assume_role(
        RoleArn="arn:aws:iam::アカウントAのアカウント番号:role/アカウントAのロールの名前",
        RoleSessionName="cross_acct_lambda"
    )
    ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
    SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
    SESSION_TOKEN = acct_b['Credentials']['SessionToken']

  #アカウントAのorganizations の情報取得
    organizations = boto3.client(
        'organizations',
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )

    responses = []
    res = {}
    while True:
        if 'NextToken' in res:
            res = organizations.list_accounts(NextToken = res['NextToken'])
        else:
            res = organizations.list_accounts()
        responses += res['Accounts']
        if 'NextToken' not in res:
            break

    print(responses)

    #アカウントAのCostExplorer の情報取得
    ce = boto3.client(
        'ce', 
        region_name='us-east-1',
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )
    response = ce.get_cost_and_usage(
        TimePeriod = {"Start": "2020-10-01", "End": "2020-11-01"},
        Granularity = 'MONTHLY', 
        Metrics = ["UnblendedCost"],
        GroupBy=[{'Type': 'DIMENSION','Key': 'LINKED_ACCOUNT'}]
    ) 

    print(response)