HashiCorp Vault 集成
HashiCorp Vault 是一个安全存储您的令牌、密码、证书和加密密钥的地方。 您可以将敏感信息存储在 Vault 中,而不是存储在 TeamCity 参数和令牌中,然后设置 TeamCity 从 Vault 引擎(KV / KV2,AWS,Google Cloud 等等)安全访问这些数据。
常见信息
要设置与 HashiCorp Vault 的集成,您需要以下内容:
所需项目中的 HashiCorp Vault 连接(如果您希望任何 TeamCity 项目使用此连接,则使用 <Root project>)。
将存储到所需密钥的 Vault 路径的 参数。
在您的构建步骤中对此参数(
%\参数名称%
)的引用(例如,在执行terraform apply -var password=%myVaultParam%
行的命令行 运行器中)。
当使用此参数的构建开始时,TeamCity 服务器会使用 Vault 连接来请求一次性的 response wrapping token,然后将其传递给运行此构建的 TeamCity 代理。 构建代理使用此令牌请求 Vault 密钥,而且从不与 TeamCity 服务器共享获取的凭据。 当构建完成时,代理的令牌将被撤销。
由于所有与 Vault 的通信都由 TeamCity 服务器进行协调,因此这种集成具有高度的可扩展性,不会受到访问 Vault 秘密的构建代理数量的影响。 代理从 TeamCity 服务器收到的令牌不是租赁令牌(仅用于测试 Vault 连接),因此实际构建代理的数量并不会影响您的配额。 因此,只需要一份用于 TeamCity 服务器的 Vault 许可证。
设置 Vault 连接
导航至 管理 | <Your Project> | 连接,然后点击 Add Connection。
选择 HashiCorp Vault 作为连接类型。
指定基本连接设置:连接名称、Vault URL 和命名空间,以及可选的 ID。
Vault 命名空间允许您在一个 Vault Enterprise 实例中创建“金库中的金库” —— 单一 Vault Enterprise 实例内的隔离租户。 如果您在这个隔离的环境中存储 Vault 密钥,请在 Vault 命名空间 连接字段中指定其命名空间(例如,
TeamABC / secrets /
)。 否则,保持此设定为空。ID 是一个自定义字符串,用以识别此 Vault 连接。 如果您设置了多个 Vault 连接,并指定了特定参数应使用哪个连接,您可以指定此字段。 否则,将此字段留空。
Vault URL 是您的 Vault 实例的地址。 本地 Vault 安装(默认 URL 为
http://localhost:8200
)也得到了支持。
选择所需的身份验证方法。 TeamCity 可以使用 Vault 的 AppRole、AWS IAM 角色或目录访问协议(LDAP)对 HCP Vault 进行认证。
此认证方法需要您在 Vault 实例中启用 AppRole 认证方法,并创建一个 AppRole。 AppRoles 是 Vault 策略的一组,它们指定了用户(在这种情况下,是 TeamCity)可以访问哪些秘密。
Vault AppRole 认证方法要求您设置以下设置:
AppRole 授权端点路径 — 这是您的 Vault 实例中挂载 AppRole 授权端点的路径。 默认路径为
approle
(不包括前面的反斜杠字符)。AppRole 角色 ID 和 AppRole 秘密 ID—— 这些值可以使用以下命令在 CLI 中获取:
vault read -field=role_id auth/<AE>/role/<RN>/role-id vault write -f -field=secret_id auth/<AE>/role/<RN>/secret-id
在哪里<AE>
是您在上面指定的 auth 端点路径(例如,approle
)而<RN>
是您的角色名称(例如,my-teamcity-role
)。
请参考这些 Vault 文档文章,学习如何创建和设置 AppRoles:入门指南:策略,AppRole 授权方法。
这种方法可以用于启用了 LDAP auth method 的 Vault 实例。 这种身份验证选项需要用户名和密码。 Path设置存储了到LDAP认证端点的路径(例如,默认
auth/ldap/users/userA
和auth/ldap/groups/groupB
端点的ldap
)。请参考本文,了解更多有关在 Vault 中设置此认证方法的信息:LDAP 认证方法。
若您希望在代理无法获取 HashiCorp Vault 的密钥并将其写入 TeamCity parameters 时,以 "获取 HashiCorp Vault 数据时出错" 的消息导致构建失败,则勾选 若出错则失败。 请注意,即使这些参数从未使用,构建也会失败。 如果禁用此设置,构建将继续运行,空字符串会作为秘密参数值。
Kotlin DSL:
创建并设置参数
要开始在您的构建中使用 HCP Vault 的秘密值,创建一个 参数 用于两个目的:
存储一个路径到 Vault 密钥,需要获取其值
在 Vault 提供后存储秘密值
要创建这样的参数,请按照以下步骤操作:
前往 Administration | <Project or Build Configuration> | Parameters并点击Add new parameter。
选择 环境变量 类型,并输入参数名称。 例如,
env.AWS_ACCESS_KEY_ID
。点击 "Spec" 标签旁的 Edit...,并设置以下值:
类型:远程
远程连接类型:HashiCorp Vault 参数
参数命名空间:选择您希望用来检索此参数值的现有 Vault 连接。 这个下拉菜单显示了所有具有 ID 的连接的 显示名称。
Vault Query:秘密的路径
path!/key
格式。 例如,以下字符串将参数指向存储在 KV2 引擎中的 "awscreds" 密钥的 "access_key" 键:secret/data/awscreds!/access_key
。
点击 Save 关闭对话框。
Kotlin DSL:
更新旧版参数
如果您在 2023.11 版之前已经使用了 TeamCity Vault 插件,那么您可能有一些遗留参数,它们直接在各自的参数值中存储 Vault 密钥的路径(以 %vault:PATH!/KEY%
格式)。
与这些遗留参数相比,新的 "远程参数" 具有以下优点:
Vault 路径存储在 Vault Query 字段中,使得 Value 字段可用于默认/初始参数值。
秘密路径(查询)使用更直接的格式,而不带有
vault:
前缀。
此外,发出动态密钥的 Vault 引擎(例如,AWS 引擎)每当客户端(TeamCity)发送新请求时都会生成新的凭据。 出于这个原因,在同一构建中,您应避免混合访问相同动态秘密引擎的旧版和远程参数。
例如,如果您有一个远程参数,该参数从 Vault AWS 引擎获取 Access Key ID,以及一个从中检索相应 Secret Access Key 的旧参数,那么 TeamCity 将为每个参数发送单独的请求。 引擎将发出两组值,因此您的 ID / Secret 对将不匹配。
我们建议您将现有的旧版参数更新为其远程对应项。
Kotlin DSL
您可以在 Kotlin DSL 中将旧版 Vault 参数更新为新类型。 遗留的 Vault 参数像下面这样声明:
要更新这些参数,请用以下代码块替换它们:
请注意,与原始参数值不同,新参数的 查询
字段既没有 vault:
前缀,也没有百分号字符。
如果您的遗留参数采用了 % \vault:foobar:/path!/key %
格式,那么 "foobar" 部分就是用于标识此参数应使用哪个 Vault 连接来检索密钥的。 将此值移动到远程参数的 vaultId
字段: