Ansible集成Terraform操作Azure遇az login报错,求解决方案
解决Ansible中Terraform初始化Azure认证问题
我在使用Ansible、Azure和Terraform协作时,在Ansible角色里初始化Terraform遇到了认证报错。角色代码如下:
--- - name: Check in Azure azure.azcollection.azure_rm_resourcegroup_info: subscription_id: "{{ subs}}" client_id: "{{ client }}" secret: "{{ secret }}" tenant: "{{ tenant }}" name: "{{ resource_group }}" register: info - name: FAIL If Resource Group exists fail: msg: "The Resource Group exists!!!" when: (info.resourcegroups | length > 0) - name: Terraform start ansible.builtin.debug: msg: "Starting terraform" - name: Initializing terraform ansible.builtin.command: terraform init -input=false args: chdir: "{{ my_dir }}" - name: Create workspace ansible.builtin.shell: >- terraform workspace new my_workspace args: chdir: "{{ my_dir }}"
报错信息:
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.
我原本以为用azure_rm_resourcegroup_info模块完成认证后,Terraform会自动复用这个会话,但实际并非如此。尝试在Playbook中定义Azure相关环境变量也没生效:
--- - hosts: localhost gather_facts: no environment: azure_client_id: "{{ client }}" azure_secret: "{{ secret }}" azure_subscription_id: "{{ subs}}" azure_tenant: "{{ tenant }}" roles: - create-my-vm
解决方案
方法1:为Terraform任务传递正确的环境变量
Terraform的Azure Provider识别的是ARM_*前缀的环境变量,而非azure_*,之前的环境变量名错误导致不生效。需要直接在Terraform相关任务中指定正确的环境变量:
- name: Initializing terraform ansible.builtin.command: terraform init -input=false args: chdir: "{{ my_dir }}" environment: ARM_CLIENT_ID: "{{ client }}" ARM_CLIENT_SECRET: "{{ secret }}" ARM_SUBSCRIPTION_ID: "{{ subs }}" ARM_TENANT_ID: "{{ tenant }}" - name: Create workspace ansible.builtin.shell: >- terraform workspace new my_workspace args: chdir: "{{ my_dir }}" environment: ARM_CLIENT_ID: "{{ client }}" ARM_CLIENT_SECRET: "{{ secret }}" ARM_SUBSCRIPTION_ID: "{{ subs }}" ARM_TENANT_ID: "{{ tenant }}"
方法2:用Ansible执行Azure CLI服务主体登录
如果需要通过az login完成认证,可以用Ansible模块执行服务主体登录命令:
- name: Login to Azure via service principal ansible.builtin.command: >- az login --service-principal -u {{ client }} -p {{ secret }} --tenant {{ tenant }} changed_when: false - name: Set active Azure subscription ansible.builtin.command: az account set --subscription {{ subs }} changed_when: false
注意:此方法会在本地CLI留存登录会话,共享环境下需注意清理。
方法3:在Terraform配置中直接指定凭据
在Terraform的Azure Provider配置块中直接添加服务主体信息,或者通过变量传递:
# Terraform provider配置示例 provider "azurerm" { features {} client_id = var.client_id client_secret = var.client_secret subscription_id = var.subscription_id tenant_id = var.tenant_id }
然后在Ansible中通过变量传递给Terraform:
- name: Initialize Terraform with credentials ansible.builtin.command: >- terraform init -input=false -var="client_id={{ client }}" -var="client_secret={{ secret }}" -var="subscription_id={{ subs }}" -var="tenant_id={{ tenant }}" args: chdir: "{{ my_dir }}"
内容的提问来源于stack exchange,提问作者Fr0zt
相关产品推荐
相关产品推荐

