如何安全存取Terraform敏感输出以支撑前后端部署工作流
安全存储Terraform敏感输出并集成GitHub部署工作流的方案
一、Azure Key Vault方案(推荐)
这是云原生的安全方案,能直接和Terraform、GitHub Actions无缝集成,支持细粒度权限控制与密钥自动轮转,避免敏感信息在GitHub Secrets中持久存储。
1. Terraflow自动将敏感输出写入Key Vault
在你的Terraform配置中,直接定义azurerm_key_vault_secret资源,将Function App发布凭据、存储账户密钥等敏感输出存入已创建的Key Vault:
# 引用已存在的Key Vault data "azurerm_key_vault" "main" { name = "your-keyvault-name" resource_group_name = "your-rg-name" } # 存储Function App发布凭据 resource "azurerm_key_vault_secret" "funcapp_publish_profile" { name = "funcapp-publish-profile" value = azurerm_function_app.main.publish_profile key_vault_id = data.azurerm_key_vault.main.id depends_on = [azurerm_function_app.main] } # 存储账户访问密钥 resource "azurerm_key_vault_secret" "storage_account_key" { name = "storage-account-key" value = azurerm_storage_account.main.primary_access_key key_vault_id = data.azurerm_key_vault.main.id depends_on = [azurerm_storage_account.main] }
执行terraform apply后,敏感输出会自动加密存入Key Vault。
2. GitHub工作流读取Key Vault中的密钥
- 先在Azure中创建一个服务主体(SP),为其分配Key Vault的
Secrets User角色权限,允许读取密钥。 - 在GitHub仓库的Secrets中配置:
AZURE_CLIENT_ID(SP客户端ID)、AZURE_CLIENT_SECRET(SP密码)、AZURE_TENANT_ID(租户ID)。 - 在部署工作流中添加以下步骤:
name: Deploy Frontend & Backend on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 # 登录Azure - name: Azure Login uses: azure/login@v1 with: creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}' # 从Key Vault拉取敏感密钥 - name: Fetch secrets from Key Vault uses: azure/keyvault-secrets@v1 with: keyvault: "your-keyvault-name" secrets: "funcapp-publish-profile,storage-account-key" id: keyvault-secrets # 部署后端Python Function App - name: Deploy Function App uses: Azure/functions-action@v1 with: app-name: "your-function-app-name" publish-profile: ${{ steps.keyvault-secrets.outputs.funcapp-publish-profile }} package: ./backend # 部署前端静态网站到存储账户 - name: Deploy Frontend to Storage run: | az storage blob upload-batch -s ./frontend -d '$web' \ --account-name your-storage-account \ --account-key ${{ steps.keyvault-secrets.outputs.storage-account-key }}
二、GitHub Secrets修复方案
如果你更倾向于用GitHub Secrets,可通过以下步骤实现Terraform输出自动写入:
1. 准备GitHub PAT
创建一个拥有repo权限的Personal Access Token(PAT),将其存入GitHub仓库Secrets,命名为GH_PAT。
2. 在Terraform工作流中写入Secrets
在执行terraform apply的工作流中,添加以下步骤获取输出并加密写入GitHub Secrets:
- name: Extract Terraform outputs id: tf-outputs run: | terraform output -json > outputs.json echo "funcapp_profile=$(jq -r '.funcapp_publish_profile.value' outputs.json)" >> $GITHUB_OUTPUT echo "storage_key=$(jq -r '.storage_account_key.value' outputs.json)" >> $GITHUB_OUTPUT - name: Get GitHub repo public key id: get-pubkey run: | RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GH_PAT }}" https://api.github.com/repos/${{ github.repository }}/actions/secrets/public-key) echo "key_id=$(echo $RESPONSE | jq -r '.key_id')" >> $GITHUB_OUTPUT echo "key=$(echo $RESPONSE | jq -r '.key')" >> $GITHUB_OUTPUT - name: Update GitHub Secrets run: | # 加密发布凭据 ENCRYPTED_FUNCAPP=$(echo -n "${{ steps.tf-outputs.outputs.funcapp_profile }}" | openssl rsautl -encrypt -pubin -inkey <(echo "${{ steps.get-pubkey.outputs.key }}") | base64 -w 0) # 加密存储账户密钥 ENCRYPTED_STORAGE=$(echo -n "${{ steps.tf-outputs.outputs.storage_key }}" | openssl rsautl -encrypt -pubin -inkey <(echo "${{ steps.get-pubkey.outputs.key }}") | base64 -w 0) # 更新发布凭据Secret curl -X PUT -H "Authorization: token ${{ secrets.GH_PAT }}" \ -H "Content-Type: application/json" \ https://api.github.com/repos/${{ github.repository }}/actions/secrets/FUNCAPP_PUBLISH_PROFILE \ -d '{"encrypted_value": "'"$ENCRYPTED_FUNCAPP"'", "key_id": "'"${{ steps.get-pubkey.outputs.key_id }}"'"}' # 更新存储账户密钥Secret curl -X PUT -H "Authorization: token ${{ secrets.GH_PAT }}" \ -H "Content-Type: application/json" \ https://api.github.com/repos/${{ github.repository }}/actions/secrets/STORAGE_ACCOUNT_KEY \ -d '{"encrypted_value": "'"$ENCRYPTED_STORAGE"'", "key_id": "'"${{ steps.get-pubkey.outputs.key_id }}"'"}'
方案对比
- Azure Key Vault:适合中大型项目,密钥管理更专业,权限控制更细,无需在GitHub中存储敏感明文。
- GitHub Secrets:适合小型项目,配置相对简单,但需要维护PAT,且敏感信息会在GitHub Secrets中持久存储。
内容的提问来源于stack exchange,提问作者kurtening
相关产品推荐
相关产品推荐

