首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用python boto3从多个AWS帐户生成boto3库存

如何使用python boto3从多个AWS帐户生成boto3库存
EN

Stack Overflow用户
提问于 2021-02-07 07:09:08
回答 2查看 2.4K关注 0票数 1

我试图从AWS帐户生成一个库存,并将其写入一个CSV文件中。

我有5个帐户,如开发,测试,DevOps,准备,和Prod。通常我使用下面的bash脚本生成,这需要一些手动任务;

代码语言:javascript
复制
#!/bin/bash
reg="ap-south-1"
input="profile.txt" ##This file contain all the profile name which configured on ~/.aws/credentials file
while IFS= read -r line
do
    aws ec2 describe-instances --profile ${line} --region ${reg} --query "Reservations[*].Instances[*].[Tags[?Key=='Name']|[0].Value,InstanceId,InstanceType,PrivateIpAddress,State.Name,Platform,Placement.AvailabilityZone]" --output text >> ec2_inventory.csv
done < "$input"

因此,这里我编写了一个python boto3脚本来生成ec2目录;

它可以像预期的那样工作在一个AWS配置文件上。以下脚本;

代码语言:javascript
复制
import boto3

session = boto3.Session(profile_name='dev')
ec2 = session.client('ec2', region_name='ap-south-1')
response = ec2.describe_instances()

import datetime
import csv
time = datetime.datetime.now().strftime ('%Y-%m-%d-%H-%M-%S')
filename_describe_instances = ('ec2_inventory_me-south-1_' + time + '.csv')
fieldnames = ['Instance_Name','ImageId', 'InstanceId', 'InstanceType', 'Availability_Zone', 'Platform', 'PrivateIpAddress','PublicIpAddress', 'State', 'SubnetId','VpcId', 'Environment', 'AccountId']



with open(filename_describe_instances, 'w', newline='') as csvFile:
    writer = csv.writer(csvFile, dialect='excel')
    writer.writerow(fieldnames)
    for Reserv in response['Reservations']:
        for Insta in Reserv['Instances']:
            instance_imageid = Insta.get('ImageId', 'NULL')
            instance_InstanceId = Insta.get('InstanceId', 'NULL')
            instance_InstanceType = Insta.get('InstanceType', 'NULL')
            instance_Availability_Zone = Insta['Placement'].get('AvailabilityZone', 'NULL')
            instance_Platform = Insta.get('Platform', 'Linux')
            instance_Private_IP = Insta.get('PrivateIpAddress', 'NULL')
            instance_Public_IP = Insta.get('PublicIpAddress', 'NULL')
            instance_State = Insta['State'].get('Name', 'NULL')
            instance_Subnet = Insta.get('SubnetId', 'NULL')
            instance_VPCID = Insta.get('VpcId', 'NULL')
            instance_OwnerId = Reserv.get('OwnerId', 'NULL')

            tags_list = []
            for n in Insta.get('Tags', 'NULL'):
                if n.get('Key', 'NULL') == 'Name':
                    instance_Name = n.get('Value', 'NULL')
                if n.get('Key', 'NULL') == 'Environment':
                    instance_Environment = n.get('Value', 'NULL')

            raw = [instance_Name,
                   instance_imageid,
                   instance_InstanceId,
                   instance_InstanceType,
                   instance_Availability_Zone,
                   instance_Platform,
                   instance_Private_IP,
                   instance_Public_IP,
                   instance_State,
                   instance_Subnet,
                   instance_VPCID,
                   instance_Environment,
                   instance_OwnerId]

            writer.writerow(raw)
            for o in raw:
                o = 'NULL'
            raw = []

csvFile.close()

那么,有人能帮我用这个脚本从多个AWS帐户生成库存并将其写到一个CSV文件中吗?

EN

回答 2

Stack Overflow用户

发布于 2021-02-08 14:33:25

编辑-修改一些基本细节。

如果您已经配置了配置文件,那么最简单的事情就是对它们进行循环,并使用boto3 Session对象获取循环中的实例详细信息。

代码语言:javascript
复制
# set up your .csv writer, etc outside the loop

# iterate over your profiles
profiles = ['Dev', 'Test', 'DevOps', 'Prepared', 'Prod']

for name in profiles:
    session = boto3.Session(profile_name=name)
    ec2 = session.client('ec2')
    response = ec2.describe_instances()
    #format your row and write to the .csv

您可以对配置文件列表进行硬编码,或者查看argparse以从命令行获取它们。

profile方法很好,并且是我广泛用于编写跨越帐户的报告和审计工具的工具。然而,对于交叉帐户的设置应该是什么样的,这一点值得深入挖掘。你有两个基本的选择:

通过每个帐户中的IAM用户访问

  • --每个帐户都有一个具有自己的密钥的唯一用户,并且在每个帐户中通过IAM角色进行访问--您在一个帐户中创建一个唯一的用户(例如,一个中央“管理”帐户),并在执行实际工作的目标帐户中创建角色。

我强烈推荐后者作为一种更安全、更灵活的选择(除非您的组织已经使用了某种形式的SSO,这在概念上是相似的,但超出了这个答案的范围)。使用角色更安全,因为您只提供/管理单个凭据,并将自己设置为管理中央auth存储库中的所有帐户。

为此,SDK支持通过引用其他配置文件隐式调用sts:AssumeRole的配置文件。例如:

~/.aws/credentials

代码语言:javascript
复制
[management]
region=us-west-2
aws_access_key_id=...
aws_secret_access_key=...

~/.aws/config

代码语言:javascript
复制
[profile foo-account]
source_profile=management
role_arn=arn:aws:iam::[foo-account-id]:role/Inventory

(请注意两个文件之间的节头名称的差异-这是有意的)

鉴于以上所述,如果您运行aws --profile foo-account ec2 describe-instances,CLI将使用profile management下的密钥/机密调用sts:AssumeRole,目标是Inventory角色。如果设置AWS_PROFILE env变量,则可以省略--profile标志。在您的Python脚本中,使用profile_name参数对Session进行同样的操作。

该角色在您希望使用的每个帐户中定义(具有相应的配置文件),并具有足够的权限来读取所需的EC2数据,并且必须具有允许您的IAM用户调用库存角色上的sts:AssumeRoleAssumeRolePolicyDocument

代码语言:javascript
复制
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[foo-account-id]:user/[your-user]"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

同样,IAM用户需要一个允许它调用sts:AssumeRole的策略。

代码语言:javascript
复制
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "*"
        }
    ]
}

可以将"*"资源引用替换为角色ARN的列表。AssumeRolePolicyDocument允许指定的主体承担角色;用户策略允许用户针对指定的资源调用AssumeRole。这似乎有点违背直觉,但请记住,授权需要回答两个问题:用户可以这样做吗?资源允许这样做吗?

最后,随着您变得更高级,一旦您完成了基本的帐户/角色设置,您实际上可以省略配置文件,只需使用一个帐户列表直接调用sts:AssumeRole

代码语言:javascript
复制
accounts = ['123...789', '234...890',]
sts = boto3.client('sts') #assumes you have a default profile set
for id in accounts:
    role_arn = f'arn:aws:iam::{id}:role/Inventory'
    creds = sts.assume_role(role_arn=role_arn, role_session_name='some-name')
    session = boto3.Session(aws_access_key_id=creds['AccessKeyId'], ...)
    ec2 = session.client('ec2')

如果你必须做很多跨帐户工作,花时间思考和配置中央帐户绝对是值得的。副作用是,一旦您有了跨帐户角色,您就可以通过在管理帐户中的Lambda函数中运行它,并对该执行角色执行相同的权限设置(而不是将.csv写入S3 )来自动化它。

票数 1
EN

Stack Overflow用户

发布于 2021-05-22 20:18:38

有一个云管理平台可以做到这一点。它使用户能够从一个仪表板管理多个AWS帐户,并提供AWS库存管理和成本优化。它是免费的:https://cloudplexo.com

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66085408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档