Я пытаюсь развернуть виртуальную машину в существующей группе доступности и VNET/SNET в определенной существующей группе ресурсов. Я использую Terraform с открытым исходным кодом, и мой файл состояния хранится в контейнере для хранения.
Это мой файл конвейера ниже
variables:
- group: infra-variables
trigger:
branches:
include:
- master
paths:
include:
- Terraform-Test
exclude:
- README.md
stages:
- stage: Validate
displayName: Validate
jobs:
- job: validate
pool:
vmImage: ubuntu-latest
steps:
- checkout : self
# - task: AzureCLI@2
# displayName :
# inputs:
# azureSubscription: 'PalTest'
# scriptType: 'bash'
# scriptLocation: 'inlineScript'
# inlineScript: |
# az account set --subscription $AZURE_SUBSCRIPTION_ID
# az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID
# STORAGE_ACCOUNT_KEY=$(az storage account keys list -g $(Terraform_Backend_RG) -n $(TF_STATE_BLOB_ACCOUNT_NAME) | jq ".[0].value" -r)
# echo "setting storage account key variable"
# echo "##vso[task.setvariable variable=ARM_ACCESS_KEY;issecret=true]$ARM_ACCESS_KEY"
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller@0
displayName: Install Terraform
inputs:
terraformVersion: 'latest'
# Init
- task: TerraformCLI@0
displayName: Terraform Init
inputs:
backendType : 'azurerm'
command: 'init'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
backendServiceArm: 'Pallab-ADO-Setup'
backendAzureRmResourceGroupName: $(Terraform_Backend_RG)
backendAzureRmStorageAccountName: $(TF_STATE_BLOB_ACCOUNT_NAME)
backendAzureRmContainerName: $(TF_STATE_BLOB_CONTAINER_NAME)
backendAzureRmKey: 'infrastructure/terraform.ntfstate'
# Validate
- task: TerraformCLI@0
displayName: Validate Config
inputs:
command: 'validate'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
- stage: Plan
displayName: Plan
jobs:
- job: plan
pool:
vmImage: ubuntu-latest
steps:
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller@0
displayName: Install Terraform
inputs:
terraformVersion: 'latest'
# Init
- task: TerraformCLI@0
displayName: Terraform Init
inputs:
backendType : 'azurerm'
command: 'init'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
backendServiceArm: 'Pallab-ADO-Setup'
backendAzureRmResourceGroupName: $(Terraform_Backend_RG)
backendAzureRmStorageAccountName: $(TF_STATE_BLOB_ACCOUNT_NAME)
backendAzureRmContainerName: $(TF_STATE_BLOB_CONTAINER_NAME)
backendAzureRmKey: 'infrastructure/terraform.ntfstate'
# Plan
- task: TerraformCLI@0
displayName: Plan Terraform Deployment
inputs:
backendType : 'azurerm'
command: 'plan'
commandOptions: '-input=false'
environmentServiceName : 'Pallab-ADO-Setup'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
# backendServiceArm: 'PalTest'
# backendAzureRmResourceGroupName: $(Terraform_Backend_RG)
# backendAzureRmStorageAccountName: $(TF_STATE_BLOB_ACCOUNT_NAME)
# backendAzureRmContainerName: $(TF_STATE_BLOB_CONTAINER_NAME)
# backendAzureRmKey: 'infrastructure/terraform.tfstate'
# Approve
- stage: Approve
displayName: Approve
jobs:
- job: approve
displayName: Wait for approval
pool: server
steps:
- task: ManualValidation@0
timeoutInMinutes: 60
inputs:
notifyUsers: '[email protected]'
instructions: 'Review the plan in the next hour'
- stage: Apply
displayName: Apply
jobs:
- job: apply
pool:
vmImage: ubuntu-latest
steps:
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller@0
displayName: Install Terraform
inputs:
terraformVersion: 'latest'
# Init
- task: TerraformCLI@0
displayName: TF Init
inputs:
command: 'init'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
commandOptions: '-backend-config=storage_account_name=$(TF_STATE_BLOB_ACCOUNT_NAME) -backend-config=container_name=$(TF_STATE_BLOB_CONTAINER_NAME) -backend-config=key=$(ARM_ACCESS_KEY)'
backendType: 'selfConfigured'
# Apply
- task: TerraformCLI@0
displayName: TF Apply
env:
ARM_SAS_TOKEN: $(ARM_ACCESS_KEY)
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)
ARM_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
ARM_TENANT_ID: $(AZURE_TENANT_ID)
inputs:
command: 'apply'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
commandOptions: '-auto-approve'
Это мой код Terraform:
terraform {
required_version = "~> 1.0"
backend "azurerm" {
key = "terraform.ntfstate"
}
required_providers {
azuread = "~> 2.0"
azurerm = "~> 2.0"
}
}
provider "azurerm" {
tenant_id = var.tenant_id
client_id = var.client_id
client_secret = var.client_secret
subscription_id = var.subscription_id
features {}
}
data "azurerm_resource_group" "az-rg-wu" {
name = "Great-Learning"
}
Я получаю эту ошибку на этапе планирования
Планирование провалилось. Terraform обнаружил ошибку при создании этого плана.
╷
building account: getting authenticated object ID: listing Service Principals: autorest.DetailedError{Original:adal.tokenRefreshError{message:"adal: Failed to unmarshal the service principal token during refresh. Error = 'invalid character '<' looking for beginning of value' JSON = '\r\n\r\n<!-- Copyright (C) Microsoft Corporation. All rights reserv
rror]Terraform command 'plan' failed with exit code '1'.
##[error]╷
│ Error: building account: getting authenticated object ID: listing Service Principals: autorest.DetailedError{Original:adal.tokenRefreshError{message:"adal: Failed to unmarshal the service principal token during refresh. Error = 'invalid character '<' looking for beginning of value' JSON = '\r\n\r\n<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->\r\n<!DOCTYPE html>\r\n<html dir=\"ltr\" class=\"\" lang=\"en\">\r\n<head>\r\n <title>Sign in to your account</title>\r\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\r\n
Если я закомментирую приведенные ниже строки, я не получу указанную выше ошибку, и мой план будет успешным.
provider "azurerm" {
# tenant_id = var.tenant_id
# client_id = var.client_id
# client_secret = var.client_secret
# subscription_id = var.subscription_id
features {}
}
Но затем на этапе применения я столкнулся с ошибкой ниже на этапе «tf init»:
Initializing the backend...
╷
│ Error: Error building ARM Config: obtain subscription() from Azure CLI: parsing json result from the Azure CLI: waiting for the Azure CLI: exit status 1: ERROR: Please run 'az login' to setup account.
│
│
╵
##[error]Terraform command 'init' failed with exit code '1'.
##[error]╷
│ Error: Error building ARM Config: obtain subscription() from Azure CLI: parsing json result from the Azure CLI: waiting for the Azure CLI: exit status 1: ERROR: Please run 'az login' to setup account.
Судя по вашему описанию, вы можете обойти первую ошибку, прокомментировав блок субъекта-службы в файле .tf
.
Ошибка: ошибка построения конфигурации ARM: получение подписки() из Azure CLI: анализ результата json из Azure CLI: ожидание Azure CLI: статус выхода 1: ОШИБКА: запустите «az login», чтобы настроить учетную запись.
Причина ошибки на этапе применения может заключаться в том, что вы не передали учетные данные подключения к службе на этапе инициализации terraform.
Блок кода:
- task: TerraformCLI@0
displayName: TF Init
inputs:
command: 'init'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
commandOptions: '-backend-config=storage_account_name=$(TF_STATE_BLOB_ACCOUNT_NAME) -backend-config=container_name=$(TF_STATE_BLOB_CONTAINER_NAME) -backend-config=key=$(ARM_ACCESS_KEY)'
backendType: 'selfConfigured'
Чтобы решить эту проблему, вам нужно изменить тип selfConfigured
на тип azurerm
на этапе инициализации Terraform. Вам также необходимо определить соединение службы на этапе применения terraform, чтобы убедиться, что оно может использовать правильный субъект службы.
Например:
stages:
- stage: Apply
displayName: Apply
jobs:
- job: apply
pool:
vmImage: ubuntu-latest
steps:
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller@0
displayName: Install Terraform
inputs:
terraformVersion: 'latest'
# Init
- task: TerraformCLI@0
displayName: TF Init
inputs:
command: 'init'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
backendType: 'azurerm'
backendServiceArm: 'Pallab-ADO-Setup'
backendAzureRmStorageAccountName: '$(TF_STATE_BLOB_ACCOUNT_NAME)'
backendAzureRmContainerName: '$(TF_STATE_BLOB_CONTAINER_NAME)'
backendAzureRmKey: '$(ARM_ACCESS_KEY)'
# Apply
- task: TerraformCLI@0
displayName: TF Apply
env:
ARM_SAS_TOKEN: $(ARM_ACCESS_KEY)
ARM_CLIENT_ID: $(AZURE_CLIENT_ID)
ARM_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
ARM_TENANT_ID: $(AZURE_TENANT_ID)
inputs:
command: 'apply'
workingDirectory: '$(System.DefaultWorkingDirectory)/Terraform-Test'
environmentServiceName: 'Pallab-ADO-Setup' #Add Correct Service Connection
runAzLogin: true
commandOptions: '-auto-approve'
Если вам нужно продолжать использовать тип selfConfigured
на этапе инициализации terraform, вы можете добавить дополнительные задачи перед этапом инициализации terraform, чтобы выполнить команду az login с правильным подключением к службе.
Например:
- task: AzureCLI@2
displayName: 'Azure CLI '
inputs:
azureSubscription: Pallab-ADO-Setup
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
echo "##vso[task.setvariable variable=ARM_CLIENT_ID]$servicePrincipalId"
echo "##vso[task.setvariable variable=ARM_CLIENT_SECRET]$servicePrincipalKey"
echo "##vso[task.setvariable variable=ARM_TENANT_ID]$tenantId"
addSpnToEnvironment: true
- bash: |
az login --service-principal --username $(ARM_CLIENT_ID) --password $(ARM_CLIENT_SECRET) --tenant $(ARM_TENANT_ID)
displayName: 'Az login to set account'
- task: TerraformCLI@0
displayName: TF Init