当 运行 在容器构建代理上的容器构建步骤中时,boto3 在 TeamCity 构建步骤中不起作用
boto3 not working in TeamCity build step when running in a container build step on a container build agent
我们的构建系统使用容器化的 TeamCity 构建代理。一些构建步骤使用 boto3 并且为了避免必须自定义基本 TeamCity 构建代理图像以具有 boto3,我们改为使用 TeamCity 的 "Run step within Docker container" 功能来指定具有 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 中是 运行,具有足够权限的 "Task Role",为什么它不起作用?
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 角色,然后从容器元数据中提取。环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
是为 ECS 下的容器 运行ning 自动设置的。
如果您 运行 在非容器化构建步骤中使用这些命令,它将输出这两个角色。如果您以相同的方式 运行 boto3,如果找到它会更喜欢容器角色,然后回退到 EC2 角色。
现在勾选 "Run step within Docker container" 并指定任意基本图像,例如 library/python:2.7.15-stretch
。
这一次,您会看到输出了相同的 EC2 IAM 角色,但未设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
env var,因此找不到容器 IAM 角色。我们想要在 TeamCity 构建代理上设置的 IAM 角色。
在我们的例子中,由于 boto3 没有找到 ECS IAM 角色,它退回到 EC2 IAM 角色,而该角色没有足够的权限来执行 boto 操作,因此失败。
修正
解决方法是使用 "Additional docker run arguments:" 将环境变量从 TeamCity docker 容器转发到 docker 容器,它 运行 执行构建步骤.将包含测试命令的构建步骤编辑为:
-e AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
现在构建步骤容器将正确继承构建代理容器的容器 IAM 角色,boto3 将按预期工作。
我们的构建系统使用容器化的 TeamCity 构建代理。一些构建步骤使用 boto3 并且为了避免必须自定义基本 TeamCity 构建代理图像以具有 boto3,我们改为使用 TeamCity 的 "Run step within Docker container" 功能来指定具有 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 中是 运行,具有足够权限的 "Task Role",为什么它不起作用?
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 角色,然后从容器元数据中提取。环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
是为 ECS 下的容器 运行ning 自动设置的。
如果您 运行 在非容器化构建步骤中使用这些命令,它将输出这两个角色。如果您以相同的方式 运行 boto3,如果找到它会更喜欢容器角色,然后回退到 EC2 角色。
现在勾选 "Run step within Docker container" 并指定任意基本图像,例如 library/python:2.7.15-stretch
。
这一次,您会看到输出了相同的 EC2 IAM 角色,但未设置 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
env var,因此找不到容器 IAM 角色。我们想要在 TeamCity 构建代理上设置的 IAM 角色。
在我们的例子中,由于 boto3 没有找到 ECS IAM 角色,它退回到 EC2 IAM 角色,而该角色没有足够的权限来执行 boto 操作,因此失败。
修正
解决方法是使用 "Additional docker run arguments:" 将环境变量从 TeamCity docker 容器转发到 docker 容器,它 运行 执行构建步骤.将包含测试命令的构建步骤编辑为:
-e AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
现在构建步骤容器将正确继承构建代理容器的容器 IAM 角色,boto3 将按预期工作。