Boto3 将尝试使用通过 ECS 任务定义在容器上设置的 IAM 角色自动进行身份验证,如果失败,它将回退到使用与运行容器的 EC2 主机关联的 IAM 角色。
您可以通过将以下命令添加到构建步骤来查看每个角色上哪些 IAM 角色处于活动状态:
echo "EC2 IAM role"
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
echo
echo "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI = $AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
curl http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
这些 curl 命令从 EC2 元数据中提取当前 IAM 角色,然后从容器元数据中提取。 env var AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 是为在 ECS 下运行的容器自动设置的。
如果您在非容器化构建步骤中运行这些命令,它将输出这两个角色。如果您要以相同的方式运行 boto3,它会首选容器角色(如果找到),然后回退到 EC2 角色。
现在勾选“在 Docker 容器中运行步骤”并指定任意基础映像,例如 library/python:2.7.15-stretch。
这一次,您将看到输出了相同的 EC2 IAM 角色,但未设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI env var,因此找不到容器 IAM 角色。我们想要在 TeamCity 构建代理上设置的 IAM 角色。
在我们的例子中,由于 boto3 没有找到 ECS IAM 角色,它回退到 EC2 IAM 角色,并且该角色没有足够的权限来执行 boto 操作,因此失败了。
修复
修复方法是使用“附加 docker 运行参数:”将 env var 从 TeamCity docker 容器转发到它运行以执行构建步骤的 docker 容器。编辑包含测试命令的构建步骤:
-e AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
现在构建步骤容器将正确继承构建代理容器的容器 IAM 角色,并且 boto3 将按预期工作。