- Вопрос или проблема
- Ответ или решение
- Azure DevOps Pipelines: Инициализация Terraform с различной подпиской и федерацией идентификации рабочего процесса
- Проблема: Инициализация Terraform с другой подпиской
- Решение: использование AzureCLI для настройки окружения
- Пример конфигурации YAML для Azure DevOps Pipeline
- Заключение
Вопрос или проблема
У меня есть YAML-пайплайн Azure DevOps, и я хочу развернуть ресурсы с помощью Terraform в Azure. Первым шагом мне нужно выполнить terraform init. Для этого я хочу использовать TerraformTaskV4
(https://github.com/microsoft/azure-pipelines-terraform/blob/main/Tasks/TerraformTask/TerraformTaskV4/README.md):
- task: TerraformTaskV4@4
displayName: Инициализация Terraform
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'ваша-служба-подключения'
backendAzureRmResourceGroupName: 'ваше-имя-rg'
backendAzureRmStorageAccountName: 'ваше-имя-stg'
backendAzureRmContainerName: 'ваше-имя-контейнера'
backendAzureRmKey: 'state.tfstate'
Но есть две проблемы:
- Я хочу использовать другую подписку Azure, отличную от той, что связана со службой подключения. Служебная учётная запись службы подключения имеет доступ к нескольким подпискам
- Я использую службу подключения с учётной записью службы, использующей федерацию идентичности рабочего процесса
Как я могу выполнить terraform init соответствующим образом?
- Насколько я знаю, невозможно выбрать подписку с помощью
TerraformTaskV4@4
. Она всегда берёт подписку, связанную со службой подключения. Поэтому я переключился на использованиеAzureCLI@2
(https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-cli-v2?view=azure-pipelines) - На первом этапе необходимо получить доступ к учётной записи службы (через
addSpnToEnvironment
) в задачеAzureCLI@2
и добавить переменные окружения (https://developer.hashicorp.com/terraform/language/backend/azurerm#backend-azure-ad-service-principal-or-user-assigned-managed-identity-via-oidc-workload-identity-federation) в окружение. Это должно происходить в первой и отдельной задаче. Затем вы можете создать последующую задачу (в том же задании) для, например, terraform init
Пример:
...
- task: AzureCLI@2
displayName: "Установить переменные окружения"
inputs:
azureSubscription: "${{ variables.service_connection_name }}"
addSpnToEnvironment: true
scriptType: pscore
scriptLocation: inlineScript
workingDirectory: $(System.DefaultWorkingDirectory)/terraform
inlineScript: |
Write-Host "##vso[task.setvariable variable=ARM_USE_OIDC]true"
Write-Host "##vso[task.setvariable variable=ARM_OIDC_TOKEN]$env:idToken"
Write-Host "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=ARM_SUBSCRIPTION_ID]$(subscriptionId)"
Write-Host "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId"
- task: TerraformInstaller@1
displayName: Установка Terraform
inputs:
terraformVersion: ${{ variables.terraform_version }}
- task: AzureCLI@2
displayName: "Terraform init"
inputs:
azureSubscription: "${{ variables.service_connection_name }}"
addSpnToEnvironment: true
scriptType: pscore
scriptLocation: inlineScript
workingDirectory: $(System.DefaultWorkingDirectory)/terraform
inlineScript: |
terraform init -backend-config="resource_group_name=$(terraformBackendResourceGroupName)" -backend-config="storage_account_name=$(terraformBackendStorageAccountName)" -backend-config="container_name=$(terraformBackendContainerName)" -backend-config="key=$(terraformBackendKey)"
...
Ответ или решение
Azure DevOps Pipelines: Инициализация Terraform с различной подпиской и федерацией идентификации рабочего процесса
При использовании Azure DevOps для развертывания ресурсов с помощью Terraform могут возникать сложности, особенно если вы хотите инициализировать Terraform с использованием другой подписки Azure, отличной от той, что указана в подключении службы. В этой статье мы подробно рассмотрим, как справиться с этой задачей, уделяя особое внимание использованию TerraformTaskV4
и AzureCLI@2
, а также концепции федерации идентификации рабочего процесса.
Проблема: Инициализация Terraform с другой подпиской
Как вы правильно заметили, TerraformTaskV4
не предоставляет возможности выбора подписки, связанной с используемым подключением службы. Большинство операций происходит в контексте подписки, указанной в этом подключении. Однако можно обойти это ограничение, используя AzureCLI@2
, что позволяет вручную управлять окружением и настраивать желаемое значение подписки для Terraform.
Решение: использование AzureCLI для настройки окружения
Чтобы управлять подписками и инициализировать Terraform с другими параметрами, выполните следующие шаги:
-
Установите переменные окружения для идентификации:
ИспользуйтеAzureCLI@2
для добавления переменных окружения с помощью командыaddSpnToEnvironment
. Это упростит использование идентификатора службы (Service Principal) для аутентификации Terraform. -
Инициализация Terraform:
После того как окружение будет настроено, выполните командуterraform init
, передав необходимые параметры для конфигурации бэкенда.
Пример конфигурации YAML для Azure DevOps Pipeline
Вот пример того, как может выглядеть ваша конфигурация YAML:
variables:
service_connection_name: 'your-service-connection'
terraform_version: '1.0.0'
subscriptionId: 'your-target-subscription-id'
terraformBackendResourceGroupName: 'your-rg-name'
terraformBackendStorageAccountName: 'your-stg-name'
terraformBackendContainerName: 'your-container-name'
terraformBackendKey: 'state.tfstate'
jobs:
- job: TerraformDeployment
pool:
vmImage: 'ubuntu-latest'
steps:
- task: AzureCLI@2
displayName: "Настройка переменных окружения"
inputs:
azureSubscription: "$(service_connection_name)"
addSpnToEnvironment: true
scriptType: pscore
scriptLocation: inlineScript
workingDirectory: $(System.DefaultWorkingDirectory)/terraform
inlineScript: |
Write-Host "##vso[task.setvariable variable=ARM_USE_OIDC]true"
Write-Host "##vso[task.setvariable variable=ARM_OIDC_TOKEN]$env:idToken"
Write-Host "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId"
Write-Host "##vso[task.setvariable variable=ARM_SUBSCRIPTION_ID]$(subscriptionId)"
Write-Host "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId"
- task: TerraformInstaller@1
displayName: Установка Terraform
inputs:
terraformVersion: "$(terraform_version)"
- task: AzureCLI@2
displayName: "Инициализация Terraform"
inputs:
azureSubscription: "$(service_connection_name)"
addSpnToEnvironment: true
scriptType: pscore
scriptLocation: inlineScript
workingDirectory: $(System.DefaultWorkingDirectory)/terraform
inlineScript: |
terraform init -backend-config="resource_group_name=$(terraformBackendResourceGroupName)" -backend-config="storage_account_name=$(terraformBackendStorageAccountName)" -backend-config="container_name=$(terraformBackendContainerName)" -backend-config="key=$(terraformBackendKey)"
Заключение
Использование Azure DevOps для работы с Terraform может быть простым и удобным, если вы правильно настроите ваше окружение и разберетесь с подключениями. Выбор AzureCLI@2
для управления переменными окружения и выбора подписки позволит вам эффективно использовать существующие сервисные подключения и упростить процесс развертывания ресурсов. Федерация идентификации рабочего процесса значительно улучшает безопасность и управление доступом для серверов, использующих идентификаторы служб. С помощью приведенного выше примера вы сможете успешно реализовать операцию инициализации Terraform, даже когда вам требуется работать с другой подпиской Azure.