You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将GitLab CI的Vault集成封装为可复用的横向模板?

问题描述

我有一个可正常运行的GitLab CI配置,用于从Vault获取密钥:

variables:
  VAULT_SERVER_URL: https://my-vault.com
  VAULT_NAMESPACE: my-namespace  # Vault EE Only
  VAULT_AUTH_PATH: jwt
  VAULT_AUTH_ROLE: gitlab-ci

vault_test:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: $VAULT_SERVER_URL
  secrets:
    TEST_HELLO:
      vault:
        engine: 
          name: kv-v2
          path: gitlab-ci
        path: test
        field: hello
      file: false
  script:
    - echo $TEST_HELLO

现在需要将这段配置封装为可复用的模板,让多个仓库能引用并指定不同的path和field来获取特定密钥,期望的模板和引用方式如下(但不确定是否可行):

模板文件(/cicd/templates/vault/secrets.yaml):

variables:
  VAULT_SERVER_URL: https://my-vault.com
  VAULT_NAMESPACE: my-namespace  # Vault EE Only
  VAULT_AUTH_PATH: jwt
  VAULT_AUTH_ROLE: gitlab-ci

get_secret:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: $VAULT_SERVER_URL
  secrets:
    TEST_HELLO:
      vault:
        engine: 
          name: kv-v2
          path: gitlab-ci
        path: test
        field: hello
      file: false

引用仓库的gitlab.yml:

include: 
  - project: 'cicd/templates' 
    file: '/vault/secrets.yaml'

build:
  ## 希望传入参数引用模板获取特定密钥,比如类似这样的写法(目前不可用)
  ## secrets: !reference [.get_secret, path: test, field: hello]
  script:
    - echo $TEST_HELLO

请问有可行的实现思路或示例吗?

可行解决方案

GitLab CI的!reference语法不支持直接传递参数,但可以通过以下几种方式实现模板复用和动态密钥获取:

方法一:变量驱动的可扩展模板作业

将模板中的密钥参数定义为可覆盖的变量,引用时通过设置变量自定义密钥信息。

模板文件(/cicd/templates/vault/secrets.yaml)

variables:
  VAULT_SERVER_URL: https://my-vault.com
  VAULT_NAMESPACE: my-namespace  # Vault EE Only
  VAULT_AUTH_PATH: jwt
  VAULT_AUTH_ROLE: gitlab-ci
  # 默认参数,可被引用仓库覆盖
  VAULT_SECRET_ENV: TEST_HELLO
  VAULT_KV_ENGINE_PATH: gitlab-ci
  VAULT_KV_SECRET_PATH: test
  VAULT_KV_FIELD: hello

.get_secret_template:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: $VAULT_SERVER_URL
  secrets:
    $VAULT_SECRET_ENV:
      vault:
        engine: 
          name: kv-v2
          path: $VAULT_KV_ENGINE_PATH
        path: $VAULT_KV_SECRET_PATH
        field: $VAULT_KV_FIELD
      file: false

引用仓库的gitlab.yml

include: 
  - project: 'cicd/templates' 
    file: '/vault/secrets.yaml'

# 获取默认密钥
build:
  extends: .get_secret_template
  script:
    - echo $TEST_HELLO

# 获取自定义密钥
deploy:
  extends: .get_secret_template
  variables:
    VAULT_SECRET_ENV: DB_PASSWORD
    VAULT_KV_SECRET_PATH: prod/db
    VAULT_KV_FIELD: password
  script:
    - echo $DB_PASSWORD

方法二:复用认证逻辑,自定义密钥列表

将Vault认证的id_tokens部分单独作为模板,引用时复用认证逻辑,然后自定义需要获取的密钥。

模板文件(/cicd/templates/vault/secrets.yaml)

variables:
  VAULT_SERVER_URL: https://my-vault.com
  VAULT_NAMESPACE: my-namespace  # Vault EE Only
  VAULT_AUTH_PATH: jwt
  VAULT_AUTH_ROLE: gitlab-ci

.vault_auth_template:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: $VAULT_SERVER_URL

引用仓库的gitlab.yml

include: 
  - project: 'cicd/templates' 
    file: '/vault/secrets.yaml'

build:
  # 复用认证逻辑
  id_tokens: !reference [.vault_auth_template, id_tokens]
  # 自定义需要获取的多个密钥
  secrets:
    TEST_HELLO:
      vault:
        engine: 
          name: kv-v2
          path: gitlab-ci
        path: test
        field: hello
      file: false
    DB_PASSWORD:
      vault:
        engine: 
          name: kv-v2
          path: gitlab-ci
        path: prod/db
        field: password
      file: false
  script:
    - echo $TEST_HELLO
    - echo $DB_PASSWORD

方法三:Vault CLI动态获取(灵活度最高)

如果需要更复杂的密钥操作,可封装Vault认证脚本,通过CLI动态获取密钥,支持任意参数组合。

模板文件(/cicd/templates/vault/secrets.yaml)

variables:
  VAULT_SERVER_URL: https://my-vault.com
  VAULT_NAMESPACE: my-namespace  # Vault EE Only
  VAULT_AUTH_PATH: jwt
  VAULT_AUTH_ROLE: gitlab-ci

.vault_cli_setup:
  before_script:
    - |
      # 使用ID Token完成Vault认证
      curl -sSfL "$VAULT_SERVER_URL/v1/auth/$VAULT_AUTH_PATH/login" \
        -H "Content-Type: application/json" \
        -d '{"jwt":"'"$VAULT_ID_TOKEN"'","role":"'"$VAULT_AUTH_ROLE"'"}' \
        | jq -r '.auth.client_token' > /tmp/vault_token
      export VAULT_TOKEN=$(cat /tmp/vault_token)
      export VAULT_NAMESPACE="$VAULT_NAMESPACE"
  id_tokens:
    VAULT_ID_TOKEN:
      aud: $VAULT_SERVER_URL

引用仓库的gitlab.yml

include: 
  - project: 'cicd/templates' 
    file: '/vault/secrets.yaml'

build:
  extends: .vault_cli_setup
  script:
    # 动态获取指定密钥并设置为环境变量
    - export TEST_HELLO=$(vault kv get -field=hello gitlab-ci/test)
    - export DB_PASSWORD=$(vault kv get -field=password gitlab-ci/prod/db)
    - echo $TEST_HELLO
    - echo $DB_PASSWORD
方法对比
  • 方法一:适合标准化单密钥场景,配置简洁,完全基于GitLab CI原生特性,无需额外工具。
  • 方法二:适合多密钥场景,复用认证逻辑的同时保留密钥定义灵活性。
  • 方法三:灵活度最高,支持Vault高级操作(如批量获取、动态密钥),但需要安装Vault CLI和jq工具。

内容的提问来源于stack exchange,提问作者louis amoros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 10:39:51