Terraform 学习总结(5)—— 简单记录 Azure CN 上 Terraform Provider 配置的一个坑

本文档介绍了在使用Terraform与Azure中国版交互时遇到的认证错误,特别是关于ServicePrincipal和ClientSecret的配置。通过详细步骤展示了如何正确配置provider.tf文件,包括设置environment参数为'china',以解决因登录Azure全球版URI导致的认证失败问题。最终成功创建了Azure资源组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

根据 Terraform 官方文档关于 Azure Provider 的使用说明,首先你得先配置一下 Azure 相关的认证信息。其实就跟平时使用 Azure 一样,想要使用 Azure,那第一步就是你必须打开 Azure portal 进行登录,就是使用你的用户名和密码认证登录到 Azure 上去,然后开始干活。现在你要用 Terraform 来操作 Azure 资源,那你得告诉 Terraform 怎么才能登录到 Azure,方便它替你干活。那接下来,我们就一起看一下在使用 Terraform 的时候,怎么来配置 Azure provider。关于 Azure 认证方式,Terraform 官方,其实应该是微软给出了四种认证方式,你可以在 terraform 中配置,如下图所示:

 详细信息,请移步:https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure。第一种方式:Azure Provider: Authenticating using the Azure CLI

这个比较直接,首先你需要安装Azure CLI,然后运行:

PS C:\lab> az login

然后会跳出来一个网页,输入你的用户名密码即可,然后你就可以愉快的使用 Terraform 和 Azure 了,你登录 Azure 的相关信息以及缓存到你本地电脑上了。所以这种方式最简单,也不用在 Terraform 的代码里提及你的 Azure 认证信息,但是你换一台电脑,再跑一下你的代码,是跑不通的,你必须先安装 Azure CLI,再执行 az login 命令,然后跟着提示登录 Azure。至于第二种和第三种方式这里先不介绍了,这次踩坑是用第四种方式:Authenticating using a Service Principal with a Client Secret。所以这里详细说明一下这一种方式。这种方式有个前提,你必须先在Azure上面创建Service Principal,具体详细步骤请参考这个链接:https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret#creating-a-service-principal-in-the-azure-portal。Service Principal 创建好之后,按照官网参考文档,在 provider.tf 文件里,就可以配置 provider azurerm 的相关信息了,整个项目文件结构如下:

PS C:\lab\dev>tree
     ───dev
         │───main.tf
         │───provider.tf

provider.tf 文件内容格式如下:

provider "azurerm" {  
# Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used  
 version         = "=2.4.0"
   subscription_id = "00000000-0000-0000-0000-000000000000"  
   client_id       = "00000000-0000-0000-0000-000000000000"  
   client_secret   = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
   tenant_id       = "00000000-0000-0000-0000-000000000000"
   features {}
  }

说明一下:

- subscription_id:你的Azure订阅ID

- client_id:创建Service Principal后的Application (client) ID

- client_secret:创建Service Principal后,创建application secret

- tenant_id:创建Service Principal后,application的Directory (tenant) ID

main.tf 文件内容如下:

resource "azurerm_resource_group" "azure-tf-rg" {    
 name = "terraform-eval"    
 location = "chinaeast2"    
 tags = {      
  "env" = "dev"      
  "location" = "China East2"    
  }
}

随后 terraform init 走起,初始化没问题。

PS C:\lab\dev> terraform init

Initializing the backend...
Initializing provider plugins...
- Using previously-installed hashicorp/azurerm v2.40.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to seeany changes that are required for your infrastructure. All Terraform commandsshould now work.

If you ever set or change modules or backend configuration for Terraform,rerun this command to reinitialize your working directory. If you forget, othercommands will detect it and remind you to do so if necessary.

接着执行 terraform plan

PS C:\lab\dev> terraform plan

Refreshing Terraform state in-memory prior to plan...

The refreshed state will be used to calculate this plan, but will not bepersisted to local or remote state storage.
------------------------------------------------------------------------
Error: Error building account: 
Error getting authenticated object ID: 
Error listing Service Principals: autorest.DetailedError{
Original:adal.tokenRefreshError{
message:"adal: Refresh request failed. 
Status Code = '400'. 
Response body: {
\"error\":\"invalid_request\",\"
error_description\":\"AADSTS90002: 
Tenant '00000000-0000-0000-0000-000000000000' not found. 
This may happen if there are no active subscriptions for the tenant. Check to make sure you have the correct tenant ID. Check with your subscription administrator.\\r\\n
Trace ID: xxxx-1fxxx95-xxx6-xxx4-xxxxxx00\\r\\n
Correlation ID: xxxxxxx-xxx-xxxxx\\r\\n
Timestamp: 2020-12-11 07:02:40Z\",\"
error_codes\":[90002],\"
timestamp\":\"2020-12-11 07:02:40Z\",\"
trace_id\":\"xxxx-1fxxx95-xxx6-xxx4-xxxxxx00\",\"
correlation_id\":\"xxxx-1fxxx95-xxx6-xxx4xxxxxx00\",\"
error_uri\":\"https://login.microsoftonline.com/error?code=90002\"}", 
resp:(*http.Response)(0xc0011c4b40)},  PackageType:"azure.BearerAuthorizer",  Method:"WithAuthorization",  StatusCode:400,  Message:"Failed to refresh the Token for request to  https://graph.windows.net/xxxx/servicePrincipals?%24filter=appId+eq+%xxxxxx00&api-version=1.6",  ServiceError:[]uint8(nil),  Response:(*http.Response)(0xc0011c4b40)}
  
  on provider.tf line 1, in provider "azurerm":   
  1: provider "azurerm" {

认证出问题了,说 Tenant id 找不到,这都是 copy 的,不可能出错。接着往下看:error_uri":"https://login.microsoftonline.com。就是这里,我是在 Azure 中国版上面创建的 Service Principal,terraform 去登录的时候用的是 Azure 海外版的 URI,那问题就出在这里了。再回去看看 Terraform 官网关于 Azurerm Provider 的介绍:

 这下明白了,environment 虽然是 optional 的,但是默认用的是 public,也就是 Azure 海外版。问题根源找到了,改 terraform 代码吧!添加 environment 参数,值设为 china 即可。最终代码如下:

provider "azurerm" {  
# Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used  
 version         = "=2.4.0"
 environment     = "china"
   subscription_id = "00000000-0000-0000-0000-000000000000"  
   client_id       = "00000000-0000-0000-0000-000000000000"  
   client_secret   = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
   tenant_id       = "00000000-0000-0000-0000-000000000000"
   features {}
  } 

再来一把 terraform plan

PS C:\lab\dev> terraform plan

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
------------------------------------------------------------------------
An execution plan has been generated and is shown below.Resource actions are indicated with the following symbols:  
+ create
Terraform will perform the following actions:  
# azurerm_resource_group.azure-tf-rg will be created  
+ resource "azurerm_resource_group" "azure-tf-rg" {      
    + id       = (known after apply)      
    + location = "chinaeast2"      
    + name     = "terraform-eval"      
    + tags     = {          
    + "env"      = "dev"          
    + "location" = "China East2"        
 }    
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraformcan't guarantee that exactly these actions will be performed if"terraform apply" is subsequently run.

没报错,提示会 add 1 个新 resource,接着走一个 terraform apply

PS C:\lab\dev> terraform apply

An execution plan has been generated and is shown below.Resource actions are indicated with the following symbols:  
+ create
Terraform will perform the following actions:  
# azurerm_resource_group.azure-tf-rg will be created  
+ resource "azurerm_resource_group" "azure-tf-rg" {      
    + id       = (known after apply)      
    + location = "chinaeast2"      
    + name     = "terraform-eval"      
    + tags     = {          
    + "env"      = "dev"          
    + "location" = "China East2"        
    }    
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?  Terraform will perform the actions described above.  Only 'yes' will be accepted to approve.  

Enter a value: yes

azurerm_resource_group.azure-tf-rg: Creating...
azurerm_resource_group.azure-tf-rg: Creation complete after 5s [id=/subscriptions/0000000-0000-0000-0000-0000000000/resourceGroups/terraform-eval]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

登录到 Azure 中国 portal,去 resource group 里看看,terraform-eval 这个 resource group 被成功创建。其实,这个坑只有在使用 Azure 中国版/美国政府版/德国版的时候才会踩,使用Azure 海外版就不用担心这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯甜酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值