You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AWS CodeBuild中Boto3的凭据来源及跨账号ECS部署问题

解决AWS CodeBuild跨账号ECS部署的凭据问题

看起来你碰到了跨账号部署时凭据不生效的典型问题,我来一步步拆解原因和解决方案:

为什么printenv看不到你设置的AWS环境变量?

如果你的临时凭证是在Python脚本里通过os.environ设置的,那这些变量只会存在于当前Python进程的内存中,不会传递到外部的shell环境。而printenv是一个独立的shell命令,自然读取不到Python进程内部的环境变量。

如果想在shell层面看到这些变量,你需要在shell脚本里直接设置(比如用export命令),而不是在Python代码里设置。

为什么资源还是创建在dev账号?

核心问题是Boto3没有使用你获取的临时跨账号凭据,而是继续使用CodeBuild默认的执行角色(dev账号的)。这和Boto3的凭据优先级规则有关:
Boto3会按以下顺序查找凭据,找到第一个有效就用:

  1. 调用boto3.client()显式传入aws_access_key_id/aws_secret_access_key/aws_session_token参数
  2. 系统环境变量中的AWS_ACCESS_KEY_ID
  3. ~/.aws/credentials文件里的配置
  4. IAM角色(比如CodeBuild的执行角色,通过实例元数据服务自动获取)

所以如果你的临时凭据没有被Boto3读到,或者优先级低于默认的执行角色,就会继续用dev账号的权限创建资源。

最可靠的解决方案

方案1:显式在Boto3客户端调用中传入凭据(推荐)

这是最不容易出错的方式,直接跳过所有凭据优先级规则,强制使用跨账号临时凭证:

import boto3

# 先通过dev账号的角色获取prod账号的临时凭据
sts_client = boto3.client('sts')
assumed_role_resp = sts_client.assume_role(
    RoleArn="arn:aws:iam::PROD_ACCOUNT_ID:role/YourCrossAccountRole",
    RoleSessionName="CodeBuildCrossAccountDeploy"
)
temp_creds = assumed_role_resp['Credentials']

# 显式传入临时凭据创建ECS客户端
ecs_client = boto3.client(
    'ecs',
    aws_access_key_id=temp_creds['AccessKeyId'],
    aws_secret_access_key=temp_creds['SecretAccessKey'],
    aws_session_token=temp_creds['SessionToken']
)

# 接下来用这个ecs_client操作prod账号的资源就没问题了
ecs_client.register_task_definition(...)
ecs_client.update_service(...)

方案2:在shell层面设置环境变量,让Python继承

如果你不想每个客户端都显式传参,可以在buildspec.yml的shell命令里先获取临时凭证并设置环境变量,再执行Python脚本:

version: 0.2
phases:
  build:
    commands:
      # 通过AWS CLI获取跨账号临时凭证,用jq解析出密钥
      - |
        ASSUMED_ROLE=$(aws sts assume-role \
          --role-arn arn:aws:iam::PROD_ACCOUNT_ID:role/YourCrossAccountRole \
          --role-session-name CodeBuildCrossAccountDeploy)
        export AWS_ACCESS_KEY_ID=$(echo "$ASSUMED_ROLE" | jq -r '.Credentials.AccessKeyId')
        export AWS_SECRET_ACCESS_KEY=$(echo "$ASSUMED_ROLE" | jq -r '.Credentials.SecretAccessKey')
        export AWS_SESSION_TOKEN=$(echo "$ASSUMED_ROLE" | jq -r '.Credentials.SessionToken')
      # 这里执行printenv就能看到这些变量了
      - printenv | grep AWS_
      # 运行你的部署脚本,Python会自动继承这些环境变量
      - python your_deployment_script.py

这种方式下,Boto3会优先读取环境变量里的临时凭证,而不是用CodeBuild的执行角色。

额外检查:跨账号角色的信任策略

别忘了确认prod账号里的目标角色的信任策略是否允许dev账号的CodeBuild执行角色扮演它:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::DEV_ACCOUNT_ID:role/codebuild-YourProjectRole"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

内容的提问来源于stack exchange,提问作者Robin

火山引擎 最新活动