简体   繁体   English

Azure 管道 - terratest - 错误:请运行“az login”来设置帐户

[英]Azure pipeline - terratest - ERROR: Please run 'az login' to setup account

i'm facing a (it seams) recurent pbm in Azure Pipeline to run terratest.我在 Azure 管道中面临一个(接缝)经常性 pbm 来运行 terratest。

While resources are well created the destroyed, when I call an azure.ResourceGroupExists function (or whatever else azure.xxx function) i have the following error:虽然资源被很好地创建被破坏,但当我调用 azure.ResourceGroupExists function (或其他任何 azure.xxx 函数)时,我有以下错误:

--- FAIL: TestTerraform_RM_resource_group (102.30s)
    resourcegroup.go:15: 
            Error Trace:    resourcegroup.go:15
                                        RM_resource_group_test.go:108
            Error:          Received unexpected error:
                            Invoking Azure CLI failed with the following error: ERROR: Please run 'az login' to setup account.
            Test:           TestTerraform_RM_resource_group
FAIL

Regarding some forum, It seems to be some configuration issue, and I follow all these recomanded configuratoion:关于一些论坛,这似乎是一些配置问题,我遵循所有这些推荐的配置:

  • set environments variables for terraform: -- ARM_CLIENT_ID -- ARM_CLIENT_SECRET -- ARM_SUBSCRIPTION_ID -- ARM_TENANT_ID为 terraform 设置环境变量: -- ARM_CLIENT_ID -- ARM_CLIENT_SECRET -- ARM_SUBSCRIPTION_ID -- ARM_TENANT_ID
  • set the az login in AzureCli task outside the go task for terratest, as it seems that terratest needs 2 differents authentifications: (using service principal client id for this az login)在 terratest 的 go 任务之外的 AzureCli 任务中设置 az login,因为 terratest 似乎需要 2 个不同的身份验证:(为此 az 登录使用服务主体客户端 ID)
  • For Assert tests, needs the ARM_CLIENT authentification对于 Assert 测试,需要 ARM_CLIENT 身份验证
  • for Exists tests, needs the Service connection authentification对于 Exists 测试,需要服务连接认证

here the link I follow:这里是我关注的链接:

bellow my pipeline code, where the TF_VAR_ARM_CLIENT_SECRET is a secret variable of the pipeline波纹管我的管道代码,其中 TF_VAR_ARM_CLIENT_SECRET 是管道的秘密变量

runOnce:
  deploy:
    steps:
    - checkout: self

    - task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller@0
      displayName: 'Install Terraform $(TERRAFORM_VERSION)'
      inputs:
        terraformVersion: $(TERRAFORM_VERSION)

    - task: GoTool@0
      displayName: 'Use Go $(GOVERSION)'
      inputs:
        version: $(GOVERSION)
        goPath: $(GOPATH)
        goBin: $(GOBIN)

    - task: Go@0
      displayName: 'Install Go Terratest module'
      inputs:
        command: get
        arguments: '$(TF_LOG) github.com/gruntwork-io/terratest/modules/terraform'

    - task: Go@0
      displayName: 'Install Go Assert module'
      inputs:
        command: get
        arguments: '$(TF_LOG) github.com/stretchr/testify/assert'

    - task: Go@0
      displayName: 'Install Go Terratest Azure module'
      inputs:
        command: get
        arguments: '$(TF_LOG) github.com/gruntwork-io/terratest/modules/azure'

    - task: Go@0
      displayName: 'Install Go hashicorp/terraform-json module'
      inputs:
        command: get
        arguments: '$(TF_LOG) github.com/hashicorp/terraform-json'

    - task: Go@0
      displayName: 'Install Go azure-sdk-for-go module'
      inputs:
        command: get
        arguments: '$(TF_LOG) github.com/Azure/azure-sdk-for-go'

    - task: AzureCLI@2
      displayName: Azure CLI
      inputs:
        azureSubscription: $(serviceConnection)
        scriptType: ps
        scriptLocation: inlineScript
        inlineScript: |
          az login --service-principal --username $(TF_VAR_ARM_CLIENT_ID) --password $(TF_VAR_ARM_CLIENT_SECRET) --tenant 'f5ff14e7-93c8-49f7-9706-7beea059bd32'

    # Go test command
    - task: Go@0
      displayName: 'Run Go terratest for resource_Modules'
      inputs:
        command: test
        arguments: '$(TF_LOG) $(pathToTerraformRootModule)\resource_group\'
      env:
        ARM_CLIENT_SECRET: $(TF_VAR_ARM_CLIENT_SECRET) #pipeline secret variable
        ARM_CLIENT_ID: $(TF_VAR_ARM_CLIENT_ID)
        ARM_SUBSCRIPTION_ID: $(TF_VAR_ARM_SUBSCRIPTION_ID)
        ARM_TENANT_ID: $(TF_VAR_ARM_TENANT_ID)
        TF_VAR_SERVICE_PRINCIPAL_ID: $(TF_VAR_ARM_CLIENT_ID)
        TF_VAR_SERVICE_PRINCIPAL_SECRET: $(TF_VAR_ARM_CLIENT_ID)
        resource_group_name: $(storageAccountResourceGroup)
        storage_account_name: $(storageAccount)
        container_name: $(stateBlobContainer)
        key: '$(MODULE)-$(TF_VAR_APPLICATION)-${{ parameters.Environment }}.tfstate'

Bellow my go terratest code:波纹管我的 go terratest 代码:

package RM_resource_group_Test

import (
    "testing"
    "os"

    "github.com/gruntwork-io/terratest/modules/azure"
    "github.com/gruntwork-io/terratest/modules/terraform"
    "github.com/stretchr/testify/assert"
)

var (
    globalBackendConf = make(map[string]interface{})
    globalEnvVars = make(map[string]string)
)

func TestTerraform_RM_resource_group(t *testing.T) {
    t.Parallel()

    // terraform Directory
    fixtureFolder := "./"
    
    // input value
    inputStage       := "demo_we"
    inputEnvironment := "DEMO"
    inputApplication := "DEMO"

    // expected value
    expectedName := "z-adf-ftnd-shrd-dm-ew1-rgp42"


    // getting enVars from environment variables
    ARM_CLIENT_ID := os.Getenv("ARM_CLIENT_ID")
    ARM_CLIENT_SECRET := os.Getenv("ARM_CLIENT_SECRET")
    ARM_SUBSCRIPTION_ID := os.Getenv("ARM_SUBSCRIPTION_ID")
    ARM_TENANT_ID := os.Getenv("ARM_TENANT_ID")


    if ARM_CLIENT_ID != "" {
        globalEnvVars["ARM_USE_MSI"] = "false"
        globalEnvVars["ARM_CLIENT_ID"] = ARM_CLIENT_ID
        globalEnvVars["ARM_CLIENT_SECRET"] = ARM_CLIENT_SECRET
        globalEnvVars["ARM_SUBSCRIPTION_ID"] = ARM_SUBSCRIPTION_ID
        globalEnvVars["ARM_TENANT_ID"] = ARM_TENANT_ID
    }


    // getting backend vars from environment variables
    resource_group_name := os.Getenv("resource_group_name")
    storage_account_name := os.Getenv("storage_account_name")
    container_name := os.Getenv("container_name")
    key := os.Getenv("key")


    if resource_group_name != "" {
        globalBackendConf["use_msi"] = false
        globalBackendConf["resource_group_name"] = resource_group_name
        globalBackendConf["storage_account_name"] = storage_account_name
        globalBackendConf["container_name"] = container_name
        globalBackendConf["key"] = key
    }
    
    // User Terratest to deploy the infrastructure
    terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
        // The path to where our Terraform code is located
        TerraformDir: fixtureFolder,
        // Variables to pass to our Terraform code using -var options
        Vars: map[string]interface{}{
            "STAGE": inputStage,
            "ENVIRONMENT": inputEnvironment,
            "APPLICATION" : inputApplication,
        },


        EnvVars: globalEnvVars,

        // backend values to set when initialziing Terraform
        BackendConfig: globalBackendConf,
        
        // Disable colors in Terraform commands so its easier to parse stdout/stderr
        NoColor: true,

    })



    // website::tag::4::Clean up resources with "terraform destroy". Using "defer" runs the command at the end of the test, whether the test succeeds or fails.
    // At the end of the test, run `terraform destroy` to clean up any resources that were created
    defer terraform.Destroy(t, terraformOptions)

    // website::tag::2::Run "terraform init" and "terraform apply".
    // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
    terraform.InitAndApply(t, terraformOptions)
    actualName := terraform.Output(t, terraformOptions, "tested_name")
    actualReaderName := terraform.Output(t, terraformOptions, "tested_readerName")
    assert.Equal(t, expectedName, actualName)
    assert.Equal(t, expectedName, actualReaderName)
    
    subscriptionID :=  terraform.Output(t, terraformOptions, "current_subscription_id")
    exists := azure.ResourceGroupExists(t, expectedName, subscriptionID)
    assert.True(t, exists, "Resource group does not exist")
}

I'm sure I miss something in passing my parameters, as always I have the following error, after creating and destroying resources in Azure:在 Azure 中创建和销毁资源后,我确定我在传递参数时遗漏了一些东西,一如既往地出现以下错误:

--- FAIL: TestTerraform_RM_resource_group (90.75s)
resourcegroup.go:15: 
        Error Trace:    resourcegroup.go:15
                                    RM_resource_group_test.go:108
        Error:          Received unexpected error:
                        Invoking Azure CLI failed with the following error: ERROR: Please run 'az login' to setup account.
        Test:           TestTerraform_RM_resource_group

please, help.请帮忙。

and thank-you for answering..并感谢您的回答..

As I figure out earlier, it was a configuration mistake and, after having made some deep excavations on Go Terratest Azure module, I've found these lines that gives all the explanations:正如我之前发现的,这是一个配置错误,在对 Go Terratest Azure 模块进行了一些深入挖掘之后,我发现这些行给出了所有解释:

So I change my pipeline to this:所以我把我的管道改成这样:

# Go test command
- task: Go@0
  displayName: 'Run Go terratest for resource_Modules'
  inputs:
    command: test
    arguments: '$(TF_LOG) $(pathToTerraformRootModule)\...'
  env:
    ARM_SUBSCRIPTION_ID: $(TF_VAR_ARM_SUBSCRIPTION_ID)
    AZURE_CLIENT_ID: $(TF_VAR_ARM_CLIENT_ID)
    AZURE_TENANT_ID: $(TF_VAR_ARM_TENANT_ID)
    AZURE_CLIENT_SECRET: $(TF_VAR_ARM_CLIENT_SECRET)
    resource_group_name: $(storageAccountResourceGroup)
    storage_account_name: $(storageAccount)
    container_name: $(stateBlobContainer)
    key: '$(MODULE)-$(TF_VAR_APPLICATION)-${{ parameters.Environment }}.tfstate'

And my Go code to this (regarding the envVariables use):还有我的 Go 代码(关于 envVariables 的使用):

// getting enVars from environment variables
ARM_CLIENT_ID := os.Getenv("AZURE_CLIENT_ID")
ARM_CLIENT_SECRET := os.Getenv("AZURE_CLIENT_SECRET")
ARM_TENANT_ID := os.Getenv("AZURE_TENANT_ID")
ARM_SUBSCRIPTION_ID := os.Getenv("ARM_SUBSCRIPTION_ID")

// creating globalEnVars for terraform call through Terratest
if ARM_CLIENT_ID != "" {
    //globalEnvVars["ARM_USE_MSI"] = "true"
    globalEnvVars["ARM_CLIENT_ID"] = ARM_CLIENT_ID
    globalEnvVars["ARM_CLIENT_SECRET"] = ARM_CLIENT_SECRET
    globalEnvVars["ARM_SUBSCRIPTION_ID"] = ARM_SUBSCRIPTION_ID
    globalEnvVars["ARM_TENANT_ID"] = ARM_TENANT_ID
}


// getting backend vars from environment variables
resource_group_name := os.Getenv("resource_group_name")
storage_account_name := os.Getenv("storage_account_name")
container_name := os.Getenv("container_name")
key := os.Getenv("key")

// creating globalBackendConf for terraform call through Terratest
if resource_group_name != "" {
    //globalBackendConf["use_msi"] = true
    globalBackendConf["resource_group_name"] = resource_group_name
    globalBackendConf["storage_account_name"] = storage_account_name
    globalBackendConf["container_name"] = container_name
    globalBackendConf["key"] = key
}

// User Terratest to deploy the infrastructure
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
    // website::tag::1::Set the path to the Terraform code that will be tested.
    // The path to where our Terraform code is located
    TerraformDir: fixtureFolder,
    // Variables to pass to our Terraform code using -var options
    Vars: map[string]interface{}{
        "STAGE": inputStage,
        "ENVIRONMENT": inputEnvironment,
        "APPLICATION" : inputApplication,
        //"configuration" : inputConfiguration,
    },


    // globalvariables for user account 
    EnvVars: globalEnvVars,

    // backend values to set when initialziing Terraform
    BackendConfig: globalBackendConf,
    
    // Disable colors in Terraform commands so its easier to parse stdout/stderr
    NoColor: true,

})

And all goes right.一切顺利。 Hopes this could help others.希望这可以帮助其他人。

Thanks again.再次感谢。

[EDIT] To be more explicit: [编辑] 更明确地说:

Go and Terraform uses two differents methods for Azure authentification. Go 和 Terraform 使用两种不同的方法进行 Azure 身份验证。

** Terraform authentification is explained bellow: ** Terraform 认证解释如下:

** Go authentification is explained bellow: ** Go 认证解释如下:

** Terratest is using both authentification methods regarding the work it has to be done: ** Terratest 使用两种身份验证方法来处理它必须完成的工作:

so both authentification methods have to be implemented所以两种认证方法都必须实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Azure blob 存储部署:错误:请将“az 帐户集”运行到 select 活动帐户 - Azure blob storage deployment: ERROR: Please run 'az account set' to select active account 如何在 azure 管道中实现等效的 az login - How to implement the equivalent of az login in azure pipeline 无法从 az login 登录到 Azure 帐户 - 管理员启用了 MFA - Cannot login to Azure Account from az login - admin enabled MFA 无法在 Azure DevOps 管道中运行嵌套的 az cli 命令 - Unable to run nested az cli commands in Azure DevOps pipeline 使用租户登录 Azure az - Azure az login with tenant Jenkins azure 部署错误:az login error issuer - Jenkins azure deploy error: az login error issuer 在本地开发时,如何将 @azure/identity 与来自“az login”而不是服务帐户的 DefaultCredentials 一起使用? - How to use @azure/identity with DefaultCredentials from 'az login' instead of service account when developing locally? 从 Azure 管道中的 `az vm run-command` 获取退出代码 - Get exit code from `az vm run-command` in Azure pipeline az 登录错误:请确保您有网络连接。 错误详细信息:HTTPSConnectionPool(host='login.microsoftonline.com', port=443) - az login error: Please ensure you have network connection. Error detail: HTTPSConnectionPool(host='login.microsoftonline.com', port=443) Azure DevOps 管道导致 az 登录失败 - az login fails wih Azure DevOps Pipelines
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM