问题:来自凭证管理器的 Jenkins Terraform Secret 和 TF_VAR_

我一直在阅读的所有内容都表明我应该使用 TF_VAR_ 方法将我的客户端密码传递给 Terraform,但我不断收到此错误:

Error: No value for required variable

  on variables.tf line 1:
   1: variable "clientid" {

The root module input variable "clientid" is not set, and has no default
value. Use a -var or -var-file command line argument to provide a value for
this variable.

请注意,如果我直接传递值以使用 -var 标志应用,它工作正常。所以,这个问题是关于如何使用 TF_VAR_ 方法,而不是如何 az login。

詹金斯文件

//Jenkinsfile (Declarative Pipeline)
pipeline {
    agent { label 'docker-agent' }

    environment {
        AZURE_SUBSCRIPTION_ID='<......>'
        AZURE_TENANT_ID='<.......>'
        CONTAINER_REGISTRY='containerregistry'
        RESOURCE_GROUP='crrg'
        REPO="sftp01"
        IMAGE_NAME="sftptest"
        TAG="0.01"
    }
    
    stages {
        stage('build') {
            steps {
                //sh 'docker build -t containerregistry.azurecr.io/sftp01/sftptest:0.01 -f Dockerfile .'
                //sh 'echo built'
                
                withCredentials([usernamePassword(credentialsId: 'containerregistryCreds', passwordVariable: 'AZURE_CLIENT_SECRET', usernameVariable: 'AZURE_CLIENT_ID')]) {
                    
                    sh 'export TF_VAR_clientid=$AZURE_CLIENT_ID'
                    sh 'export TF_VAR_clientsecret=$AZURE_CLIENT_SECRET'
                    sh 'export TF_VAR_subscriptionid=$AZURE_SUBSCRIPTION_ID'
                    sh 'export TF_VAR_tenantid=$AZURE_TENANT_ID'
                    
                    //sh 'az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET -t $AZURE_TENANT_ID'
                    //sh 'az account set -s $AZURE_SUBSCRIPTION_ID'
                    //sh 'az acr login --name $CONTAINER_REGISTRY --resource-group $RESOURCE_GROUP'
                    //sh 'az acr build --image $REPO/$IMAGE_NAME:$TAG --registry $CONTAINER_REGISTRY --file Dockerfile . '
                    
                    sh 'terraform init'
                    sh 'terraform fmt'
                    sh 'terraform validate'
                    sh 'terraform apply -auto-approve -no-color'
                    
                    //If I pass the variables this way, it works fine.
                    //sh 'terraform apply -auto-approve -no-color -var clientid=$AZURE_CLIENT_ID -var clientsecret=$AZURE_CLIENT_SECRET -var subscriptionid=$AZURE_SUBSCRIPTION_ID -var tenantid=$AZURE_TENANT_ID'
                    
                    sh 'terraform show'
                    sh 'terraform state list'
                        }
            }
        }
    }
}

main.tf

# Configure the Azure provider
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0.2"
    }
  }
}

provider "azurerm" {
  client_id       = var.clientid
  client_secret   = var.clientsecret
  subscription_id = var.subscriptionid
  tenant_id       = var.tenantid
  features {}
}

resource "azurerm_resource_group" "resourceNameTFscopeOnly" {
  name     = "myTFResourceGroup"
  location = "westus2"
}

变量.tf

variable "clientid" {
  description = "Azure Client ID"
  type        = string
  sensitive   = true
}

variable "clientsecret" {
  description = "Azure Client Service Principal Secret"
  type        = string
  sensitive   = true
}

variable "subscriptionid" {
  description = "Azure Subscription ID"
  type        = string
  sensitive   = true
}

variable "tenantid" {
  description = "Azure Tenant ID"
  type        = string
  sensitive   = true
}

variable "testpassword" {
  description = "For testing (not relevant to question)"
  type        = string
  sensitive   = true
}

我究竟做错了什么?

解答

Jenkins Pipeline 中的withCredentials块已经将您的变量导出到其范围内的环境中。您可以额外修改env对象以获得其他环境变量,并从env对象访问当前环境变量(例如您在environment指令中分配的那些)。这就是 Terraform 在没有变量值时出错的原因:它们都没有在环境中正确设置。

// assign password and username environment variables within block arguments
withCredentials([usernamePassword(credentialsId: 'containerregistryCreds', passwordVariable: 'TF_VAR_clientsecret', usernameVariable: 'TF_VAR_clientid')]) {
  script {
    // re-assign other environment variables from environment directive to env object within block scope           
    env.TF_VAR_subscriptionid = env.AZURE_SUBSCRIPTION_ID
    env.TF_VAR_tenantid = env.AZURE_TENANT_ID
    ...
  }
}
Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐