为Golang项目创建Azure DevOps CI/CD流水线

为Golang项目创建Azure DevOps CI/CD流水线 我正在使用Azure DevOps为我的Go项目创建CI/CD流水线。我想使用Azure Key Vault来存储数据库连接字符串中使用的密钥。

请帮助我了解在运行流水线时,如何在我的代码中使用这些密钥。

1 回复

更多关于为Golang项目创建Azure DevOps CI/CD流水线的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Azure DevOps流水线中集成Azure Key Vault并安全使用密钥,可以通过以下方式实现:

1. 在Azure DevOps中配置Key Vault服务连接

首先在Azure DevOps项目设置中创建Azure Resource Manager服务连接,确保该服务主体对Key Vault有读取权限。

2. 在流水线中引用Key Vault

azure-pipelines.yml中配置Key Vault任务:

variables:
  - group: 'KeyVault-Variables'  # 变量组名称

stages:
- stage: Build
  jobs:
  - job: BuildGo
    pool:
      vmImage: 'ubuntu-latest'
    
    steps:
    # 从Key Vault获取密钥
    - task: AzureKeyVault@2
      inputs:
        azureSubscription: 'Your-Service-Connection'
        KeyVaultName: 'your-keyvault-name'
        SecretsFilter: '*'
        RunAsPreJob: true
    
    # 构建Go应用
    - task: GoTool@0
      inputs:
        version: '1.21'
    
    - script: |
        go build -o myapp ./cmd/main.go
      displayName: 'Build Go application'
    
    # 使用环境变量访问密钥
    - script: |
        echo "Testing database connection"
        # 密钥已作为环境变量可用
        echo "DB_HOST: $(db-host)"
        echo "DB_PASSWORD: $(db-password)"
      displayName: 'Test environment variables'
      env:
        DB_HOST: $(db-host)
        DB_PASSWORD: $(db-password)

3. 在Go代码中访问环境变量

创建配置文件或直接在代码中读取环境变量:

package config

import (
    "os"
    "log"
)

type DatabaseConfig struct {
    Host     string
    Port     string
    User     string
    Password string
    Database string
}

func LoadConfigFromEnv() *DatabaseConfig {
    return &DatabaseConfig{
        Host:     getEnv("DB_HOST", "localhost"),
        Port:     getEnv("DB_PORT", "5432"),
        User:     getEnv("DB_USER", "postgres"),
        Password: getEnv("DB_PASSWORD", ""), // 从Key Vault获取
        Database: getEnv("DB_NAME", "mydb"),
    }
}

func getEnv(key, defaultValue string) string {
    value := os.Getenv(key)
    if value == "" {
        return defaultValue
    }
    return value
}

4. 数据库连接示例

package main

import (
    "database/sql"
    "fmt"
    "log"
    "your-project/config"
    _ "github.com/lib/pq"
)

func main() {
    cfg := config.LoadConfigFromEnv()
    
    connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
        cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.Database)
    
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    // 测试连接
    err = db.Ping()
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("Successfully connected to database")
}

5. 完整的流水线示例

trigger:
  branches:
    include:
    - main

variables:
  - group: 'Production-Secrets'

stages:
- stage: BuildAndTest
  jobs:
  - job: Build
    steps:
    - task: AzureKeyVault@2
      inputs:
        azureSubscription: 'Azure-Service-Connection'
        KeyVaultName: 'prod-keyvault-001'
        SecretsFilter: 'db-*'
    
    - task: GoTool@0
      inputs:
        version: '1.21'
    
    - script: |
        go mod download
        go build -v ./...
        go test ./...
      env:
        DB_HOST: $(db-host)
        DB_PASSWORD: $(db-password)
        DB_USER: $(db-user)
        DB_NAME: $(db-name)
    
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(System.DefaultWorkingDirectory)'
        ArtifactName: 'drop'

- stage: Deploy
  dependsOn: BuildAndTest
  jobs:
  - deployment: DeployToAzure
    environment: 'production'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureKeyVault@2
            inputs:
              azureSubscription: 'Azure-Service-Connection'
              KeyVaultName: 'prod-keyvault-001'
              SecretsFilter: 'db-*'
          
          - script: |
              # 部署脚本,使用环境变量中的密钥
              echo "Deploying application..."
          env:
            DB_HOST: $(db-host)
            DB_PASSWORD: $(db-password)

通过这种方式,密钥在流水线执行期间作为环境变量注入,不会存储在代码或构建产物中,确保安全性。

回到顶部