使用 AWS Codebuild 时如何读取 SSM 参数?

Posted

技术标签:

【中文标题】使用 AWS Codebuild 时如何读取 SSM 参数?【英文标题】:How to read SSM parameters when using AWS Codebuild? 【发布时间】:2018-10-05 13:42:31 【问题描述】:

我目前成功地将 codebuild 用于简单的构建任务(在非 vpc 配置中)。

但现在我正在尝试运行读取 SSM 参数值的构建任务,但它失败了,因为它无法加载任何凭据,明显的原因是:

com.amazonaws.auth.InstanceProfileCredentialsProvider@5754b242: Unable to load credentials from service endpoint

我分配给 codebuild 项目的 IAM 服务角色确实对我正在尝试读取的参数具有 ssm:GetParameters 权限(如果这是问题所在,我希望看到 unauthorized消息,而不是unable to load credentials)。

我正在使用 Java SDK 执行 SSM GetParameter 调用,我已经确认在从 EC2 实例运行时读取 SSM 参数确实有效,所以我很确定这里的问题是 Codebuild。

为了进一步诊断问题,我尝试添加一个构建命令来针对 AWS 实例元数据地址执行 curl

curl 169.254.169.254/latest/meta-data/iam/info

它不会像从普通 EC2 环境那样返回实例元数据,而是会超时。

所以问题的根源似乎是代码构建环境不适用于 AWS 元数据查找地址,这导致 AWS 提供商链无法查找凭证。

如何从 codebuild 读取我的 SSM 参数(无需硬编码或使用 SDK 凭据的环境变量)?

【问题讨论】:

【参考方案1】:

请问您为什么不使用AWS CodeBuild 的内置方法?您可以通过AWS CodeBuild 项目的构建规范从SSM 中获取参数。在这种情况下,通过 Java SDK 进行的额外调用已过时。

version: 0.2

env:
  parameter-store:
    key: "value"
    key: "value"

phases:
  build:
    commands:
      - command
      - command

parameter-store:如果指定了 env 并且您想要 检索存储在 Amazon EC2 系统中的自定义环境变量 管理器参数存储。包含键/值标量的映射, 其中每个映射代表一个自定义环境变量 存储在 Amazon EC2 Systems Manager 参数存储中。关键是名字 您稍后将在构建命令中使用来引用此自定义 环境变量,value是自定义环境的名称 存储在 Amazon EC2 Systems Manager 参数存储中的变量。

更多信息请查看Build Specification Reference for AWS CodeBuild

【讨论】:

【参考方案2】:

您的 AWS Java 开发工具包可能已过期。在 CodeBuild 中检索凭证的最低版本是 1.11.16。 https://docs.aws.amazon.com/codebuild/latest/userguide/troubleshooting.html#troubleshooting-versions

【讨论】:

CodeBuild 使用容器来运行构建,因此您需要使用 AWS 容器元数据端点,而不是实例元数据端点。尝试运行:curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 查看我的其他答案。如果其他人再次出现,这可能值得添加为常见问题解答。【参考方案3】:

MaiKaY 的回答是解决“如何将 SSM 参数值放入您的构建”问题的最佳解决方案(最好将构建规范绑定到 SSM 参数的名称而不是代码或构建脚本)。

但万一其他人在处理同一问题时偶然发现了这个问题 - 问题出在最初问题的基础代码上,与Clare Liguori 的答案有点相关。

我使用的是最新的 AWS 开发工具包 - 但我没有以正确的方式使用它。我正在使用 AWSSimpleSystemsManagementClient 类的简单构造函数,这很少是正确的做法。 构建客户端的更好方法是使用 AWSSimpleSystemsManagementClientBuilder 类,例如:

AWSSimpleSystemsManagementClientBuilder.standard().build()

【讨论】:

【参考方案4】:

添加到MaiKaY 答案,确保 ssm 参数存储中的参数是 secureString 格式,而不是 string。我为此苦苦挣扎了好几天,最后通过Codebuild console 添加了变量,它自动存储在secureString中

【讨论】:

以上是关于使用 AWS Codebuild 时如何读取 SSM 参数?的主要内容,如果未能解决你的问题,请参考以下文章