amazon-web-services - 在不同 AWS 账户中启动和停止 EC2 实例的 IAM 策略/角色设置
问题描述
我想从另一个 AWS 账户(账户:BBB)启动和停止 AWS 账户(账户:AAA)中的 EC2 实例。具体来说,我在 Account BBB 中的 ECS 上设置了一个 API 来执行此操作。当我测试用于启动和停止同一帐户中的帐户的 API 时,它运行良好。但是,我无法让 IAM 角色正确地跨多个账户工作。
我的 API 使用 boto3 并使用 describe_instance_status 来识别实例状态,然后使用 start_instances 或 stop_instances 来启动/停止。只要 EC2 实例与托管 API 的 ECS 位于同一账户中,所有这些都可以正常工作。
跨多个帐户工作。我做了以下,但我得到了错误:
"botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstanceStatus operation: You are not authorized to perform this operation.botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstanceStatus operation: You are not authorized to perform this operation."
我的设置如下:
- 在托管 EC2 实例的账户 AAA 中,我创建了一个如下所示的策略。BBB 代表托管运行 API 的 ECS 任务的帐户。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:DescribeInstanceStatus",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "arn:aws:ec2:*:AAA:instance/*",
"Condition": {
"StringEqualsIgnoreCase": {
"ec2:ResourceTag/ManagedBy": "API"
}
}
}
]
创建了一个角色 (ec2-instance-mgmt-role),该角色使用上述策略并与 Account: BBB 建立信任关系。
在 Account BBB 中,我创建了一个策略 (ec2-assume-managerole),如下所示,其中 AAA 是托管 EC2 实例的帐户的帐户名称。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::AAA:role/ec2-instance-mgmt-role"
}
}
- 在 Account BBB 中,我创建了一个附加了 (3) 中的策略的角色。此外,我为此角色创建了与 ecs-tasks 的信任关系。
我要开始的 boto3 代码片段如下:
ec2 = boto3.client('ec2', region_name=region_name)
resp = ec2.describe_instance_status(
InstanceIds=[str(instance_id)],
IncludeAllInstances=True)
print("Response = ",resp)
instance_status = resp['InstanceStatuses'][0]['InstanceState']['Code']
print("Instance status =", instance_status)
if instance_status == 80:
ec2.start_instances(InstanceIds=[instance_id])
print("Started instance with Instance_id",instance_id)
return {'message': 'instance started'}
else:
print("Instance not in a state to start")
return {'message': 'instance not in a state to be started'}
- 将步骤 (4) 中创建的角色分配为 ECS 任务的任务角色,该任务定义了为启动和停止 EC2 实例而构建的 API 的容器。ECS 实例在账户 BBB 中运行。
当我尝试调用此 API 时,我得到了开头描述的错误,该错误也粘贴在下面。
"botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstanceStatus operation: You are not authorized to perform this operation.botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstanceStatus operation: You are not authorized to perform this operation."
解决方案
最后,我能够解决这个问题。我错过的是我没有承担 boto3 代码中的角色。一旦添加它就可以了。以下代码显示了为承担角色而调用的函数,下面的代码显示了在承担角色后描述 ec2 实例状态的用法。
def assume_role(role_arn):
sts_client = boto3.client('sts')
letters = string.ascii_letters
session_name = f"AssumeRoleSession{random.choice(letters)}"
assumed_role_object=sts_client.assume_role(
RoleArn=role_arn,
RoleSessionName=session_name
)
credentials=assumed_role_object['Credentials']
print(f"Credentials: {credentials}")
ec2_resource=boto3.resource(
'ec2',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'],
)
return ec2_resource
ec2_resource = assume_role(assume_role_arn)
ec2 = ec2_resource.meta.client
resp = ec2.describe_instance_status(
InstanceIds=[str(instance_id)],
IncludeAllInstances=True)
推荐阅读
- dfa - DFA 可以有一个带有空字符串的箭头作为输入吗?
- c++ - 函数是否在返回值后立即终止,忽略其下一行?
- flutter - Flutter IconTheme 不适用
- windows - 聪明的。卡微型驱动程序测试库加载失败 - cmck
- jenkins - 如何简单地执行键的值,其中值是元素列表,每个元素执行应该在jenkins groovy中并行执行
- reactjs - (错误)AWS 作为后端安装放大库
- discord - 链接到 Discord.py Meme 命令中的 meme
- c# - JSON模型的多重继承的替代方案?
- laravel - 动态字段验证 (Livewire) - 有效但不能引用错误桶
- r - 为什么在 R 中总结线性模型并没有显示所有需要的级别?