从AWS账号B的Fargate任务部署账号A的CDK栈遇权限问题求助
问题背景
拥有AWS账号A和B,需在账号B的ECS Fargate任务中执行cdk synth和cdk deploy,将CDK栈部署到账号A。已完成操作:
- 在账号A创建管理员权限角色,信任策略允许账号B的root用户扮演该角色
- 在账号B的ECS任务中尝试通过
--role-arn参数指定账号A的角色执行CDK命令,执行失败
首次尝试代码
role_arn = "arn of Account A role which has admin access" print("Synthesizing stack...") sb.run(f"cdk --role-arn {role_arn} synth", shell=True) print("Deploying stack...") sb.run(f"cdk --role-arn {role_arn} deploy", shell=True)
报错信息
无法使用当前凭证(属于账号614863243217)扮演目标账号中的角色。用户:arn:aws:sts::<B_account_id>:assumed-role/ecs-fargate-role/65dd98a9c327410 无权执行:sts:AssumeRole 操作,资源为:arn:aws:iam::<A_account_id>:role/cdk-hnb659fds-deploy-role-473038482210-us-east-2。请确保该角色存在于目标账号中。若不存在,请使用最新版本的CDK CLI,通过正确的'--trust'参数重新初始化(bootstrap)环境。
账号A的角色配置
权限策略
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "*", "Resource": "*" } ] }
信任关系
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<AccountB>:root" }, "Action": "sts:AssumeRole" } ] }
后续尝试的两种方式
- 通过
aws configure写入凭证:
role_arn = stack_json["role_arn"] aws_region = stack_json["region"] assumed_role_object = sts_client.assume_role( RoleArn=role_arn, RoleSessionName="AssumeRoleSession1" ) credentials = assumed_role_object['Credentials'] p = Popen(['aws configure'], stdin=PIPE, shell=True) aws_configure_str = f"{credentials['AccessKeyId']}\n{credentials['SecretAccessKey']}\n{aws_region}\njson\n" p.communicate(input=bytes(aws_configure_str, 'utf-8'))
执行后日志显示凭证未正确加载:
AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [None]: Default output format [None]: Loaded stack_json
- 通过环境变量传递凭证:
sb.run(f"cdk deploy", shell=True, env={ "AWS_ACCESS_KEY_ID": credentials['AccessKeyId'], "AWS_SECRET_ACCESS_KEY": credentials['SecretAccessKey'], "AWS_DEFAULT_REGION": aws_region, })
报错:
部署失败:错误:需要为账号执行AWS调用,但未配置凭证
解决方案
1. 重新配置账号A的CDK Bootstrap环境
CDK的--role-arn参数用于CDK自身调用API,但部署过程中会使用Bootstrap创建的部署角色(即报错中的cdk-hnb659fds-deploy-role-xxx),需确保该角色信任从账号B扮演的账号A角色。
在账号A中执行以下命令重新Bootstrap:
# 信任整个账号B cdk bootstrap aws://<A_account_id>/<region> --trust <B_account_id> --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess # 或精准信任账号B的ECS任务角色 cdk bootstrap aws://<A_account_id>/<region> --trust arn:aws:iam::<B_account_id>:role/ecs-fargate-role --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
2. 正确传递STS临时凭证给CDK命令
不要使用aws configure(Fargate任务可能无持久化配置权限),需在环境变量中完整传递STS临时凭证的三个参数:
import subprocess as sb import boto3 sts_client = boto3.client('sts') role_arn = "arn:aws:iam::<A_account_id>:role/your-admin-role" aws_region = "us-east-2" # 扮演账号A的角色 assumed_role = sts_client.assume_role( RoleArn=role_arn, RoleSessionName="CDK-Deployment-Session" ) creds = assumed_role['Credentials'] # 构造完整环境变量,必须包含AWS_SESSION_TOKEN cdk_env = { **sb.os.environ, # 继承原有环境变量 "AWS_ACCESS_KEY_ID": creds['AccessKeyId'], "AWS_SECRET_ACCESS_KEY": creds['SecretAccessKey'], "AWS_SESSION_TOKEN": creds['SessionToken'], "AWS_DEFAULT_REGION": aws_region } # 执行synth和deploy sb.run("cdk synth", shell=True, env=cdk_env, check=True) sb.run("cdk deploy --require-approval never", shell=True, env=cdk_env, check=True)
- STS临时凭证的
AccessKeyId、SecretAccessKey、SessionToken三个参数缺一不可 - 继承原有环境变量避免丢失必要配置
check=True可在命令失败时抛出异常,便于调试
3. 优化账号A角色的信任策略
将信任关系中的Principal从账号B的root用户,改为账号B的ECS任务角色,最小化权限范围:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<B_account_id>:role/ecs-fargate-role" }, "Action": "sts:AssumeRole" } ] }
内容的提问来源于stack exchange,提问作者asm

