我们的构建系统使用容器化的TeamCity构建代理。一些构建步骤使用boto3并且为了避免必须自定义基本TeamCity构建代理映像以具有boto3,我们改为使用TeamCity的“在Docker容器中运行步骤”功能来指定具有boto3和一堆其他python模块的python映像安装。
运行构建步骤时,由于缺少权限,boto3错误,错误如:
botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
构建代理在AWS中运行,其“任务角色”具有足够的权限,为什么它不起作用?
答案 0 :(得分:0)
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角色,然后从容器元数据中提取当前IAM角色。对于在ECS下运行的容器,将自动设置env var AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
。
如果在非容器化构建步骤中运行这些命令,它将输出两个角色。如果你以相同的方式运行boto3,它会更喜欢容器角色(如果找到),然后回退到EC2角色。
现在勾选Docker容器中的" Run步骤"并指定任意基本图像,例如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 run参数:"将来自TeamCity docker容器的env var转发到它运行的docker容器中以执行构建步骤。编辑包含测试命令的构建步骤:
-e AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
现在构建步骤容器将正确继承构建代理容器的容器IAM角色,boto3将按预期工作。