简体   繁体   English

在 Azure 上使用 Terraform 部署具有托管标识的 VM 失败

[英]Deploying a VM with managed identity using Terraform on Azure fails

I am currently working on deploying a VM on Azure using Terraform. The VM deployed correctly when using client_id, subscription_id, client_secret and tenant_id in the AzureRM provider block.我目前正在使用 Terraform 在 Azure 上部署 VM。在 AzureRM 提供程序块中使用 client_id、subscription_id、client_secret 和 tenant_id 时,VM 已正确部署。 However, I want to make use of managed identities so I don't have to expose the client_secret.但是,我想使用托管身份,这样我就不必公开 client_secret。

Things I tried: For this, I followed this guide我尝试过的事情:为此,我遵循了本指南

I included the azuread provider block, used the "use_msi = true" to indicate that managed identities should be used.我包含了 azuread 提供程序块,使用“use_msi = true”来指示应使用托管身份。 Also included the azurerm_subscription block,azurerm_Client_config, as well as a resource definition.还包括 azurerm_subscription 块、azurerm_Client_config 以及资源定义。 Then added the role assignment to the VM.然后将角色分配添加到VM。

Code:代码:

terraform {
  required_providers {
    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
  features {}
  //client_id       = "XXXXXXXXXXXXXX"
  //client_secret   = "XXXXXXXXXXXXXX"
  //subscription_id = "XXXXXXXXXXXXXX"
  tenant_id       = "TENANT_ID"
  //use_msi         = true
}

provider "azuread" {
  use_msi   = true
  tenant_id = "TENANT_ID"

}


#Resource group definition
resource "azurerm_resource_group" "myVMachineRG" {
  name     = "testnew-resources"
  location = "westus2"
}

resource "azurerm_virtual_network" "myVNet" {
  name                = "testnew-network"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.myVMachineRG.location
  resource_group_name = azurerm_resource_group.myVMachineRG.name
}

resource "azurerm_subnet" "mySubnet" {
  name                 = "testnew-internal-subnet"
  resource_group_name  = azurerm_resource_group.myVMachineRG.name
  virtual_network_name = azurerm_virtual_network.myVNet.name
  #256 total IPs
  address_prefixes = ["10.0.2.0/24"]
}

resource "azurerm_network_interface" "myNIC" {
  name                = "testnew-nic"
  location            = azurerm_resource_group.myVMachineRG.location
  resource_group_name = azurerm_resource_group.myVMachineRG.name

  ip_configuration {
    name                          = "testconfiguration1"
    subnet_id                     = azurerm_subnet.mySubnet.id
    private_ip_address_allocation = "Dynamic"
  }
}

#ADDED HERE:


data "azurerm_subscription" "current" {}

data "azurerm_client_config" "example" {
}

resource "azurerm_virtual_machine" "example" {
  name                  = "testnew-vm"
  location              = azurerm_resource_group.myVMachineRG.location
  resource_group_name   = azurerm_resource_group.myVMachineRG.name
  network_interface_ids = ["${azurerm_network_interface.myNIC.id}"]
  vm_size               = "Standard_F2"

  #Option to delete disks when Terraform destroy is performed. 
  #This is to ensure that we don't keep wasting balance
  delete_os_disk_on_termination    = true
  delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }

  storage_os_disk {
    name              = "OSDISK"
    caching           = "Readwrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }

  #Just for testing purposes, would be better to use a KeyVault reference here instead.
  os_profile {
    computer_name  = "XXXXXXXXXXXXXX"
    admin_username = "XXXXXXXXXXXXXX"
    admin_password = "XXXXXXXXXXXXXX"
  }

  #Force password to authenticate
  os_profile_linux_config {
    disable_password_authentication = false
  }

  identity {
    type = "SystemAssigned"
  }
}

data "azurerm_role_definition" "contributor" {
  name = "Contributor"
}

resource "azurerm_role_assignment" "example" {
  //name               = azurerm_virtual_machine.example.name
  scope                = data.azurerm_subscription.current.id
  role_definition_name = "Contributor"
  //role_definition_id = "${data.azurerm_subscription.current.id}${data.azurerm_role_definition.contributor.id}"
  //principal_id = azurerm_virtual_machine.example.identity[0].principal_id
  principal_id = data.azurerm_client_config.example.object_id
}

Error:错误:

Error: building AzureRM Client: 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.
│
│   with provider["registry.terraform.io/hashicorp/azurerm"],
│   on main.tf line 9, in provider "azurerm":
│    9: provider "azurerm" {

I dont understand why it's still asking to use az login when I am trying to use Managed Identity for log-in.我不明白为什么当我尝试使用托管身份登录时它仍然要求使用 az login。

Redacted the tenantID for security purposes.出于安全目的编辑了 tenantID。

Any help would be greatly appreciated:)任何帮助将不胜感激:)

your provider block has usemsi commented out for azurerm (the one that's failing.) Is that just a code transfer mistake to this question?您的提供程序块已将 usemsi 注释掉用于 azurerm(失败的那个)。这只是这个问题的代码传输错误吗? Would have put this in comments but my reputation is not high enough.会把它放在评论中,但我的声誉不够高。

Looks like azurerm might also need the subscription id (unlike azuread) https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/managed_service_identity看起来 azurerm 可能还需要订阅 ID(与 azuread 不同) https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/managed_service_identity

The use_msi property should be in azurerm as well. use_msi 属性也应该在 azurerm 中。 From the above link: enter image description here从上面的链接:在此处输入图像描述

Also, just ot be sure, you've already configured the managed identity to use for this purpose, right?另外,请确定,您已经配置了用于此目的的托管标识,对吗?

I tried to reproduce the same requirement in my environment and was able to deploy it successfully.我尝试在我的环境中重现相同的需求,并且能够成功部署它。

Need to provide name of the managed identity if you are authenticating via managed identities in terraform.如果您在 terraform 中通过托管身份进行身份验证,则需要提供托管身份的名称。

Add msi_name under azuread provider .azuread provider添加msi_name

Note : As you have given, make sure that managed identities should have enough permissions (contributor role) to authenticate and create resources otherwise deployment will fail.注意正如您所给出的,确保托管身份应具有足够的权限(贡献者角色)来验证和创建资源,否则部署将失败。

main.tf主程序

data "azurerm_subscription" "current" {}
variable "subscription_id" {
  default = "xxxxxxxxxxxx"
}
provider "azurerm"{
features{}
subscription_id = var.subscription_id
}
provider "azuread"{
features{}
use_msi = true
msi-name = "jahnaviidentity" //Give Name of the Managed identity 
}

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_virtual_network" "main" {
  name                = "main-network"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "internal" {
  name                 = "internal"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_network_interface" "main" {
  name                = "main-nic"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  ip_configuration {
    name                          = "<configurationname>"
    subnet_id                     = azurerm_subnet.internal.id
    private_ip_address_allocation = "Dynamic"
  }
}

resource "azurerm_virtual_machine" "main" {
  name                  = "main-vm"
  location              = azurerm_resource_group.example.location
  resource_group_name   = azurerm_resource_group.example.name
  network_interface_ids = [azurerm_network_interface.main.id]
  vm_size               = "Standard_DS1_v2"


  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }
  storage_os_disk {
    name              = "osdisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }
  os_profile {
    computer_name  = "<computername>"
    admin_username = "<admin/username>"
    admin_password = "xxxxxx"
  }
  os_profile_linux_config {
    disable_password_authentication = false
  }
  identity {
    type = "SystemAssigned"
  }
}

Output: Output:

terraform init : terraform init

在此处输入图像描述

terraform plan : terraform plan

在此处输入图像描述

terraform apply : terraform apply

在此处输入图像描述

Deployed successfully in Azure Portal:在Azure传送门部署成功:

在此处输入图像描述

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

相关问题 使用托管标识从 VM 访问 Azure 存储 - Accessing Azure Storage from VM using Managed Identity Azure VM 关闭使用 Terraform 中的变量 - Azure VM shutdown using variables in Terraform 在使用 terraform 部署脚本以启用 Azure 数据工厂中的客户管理密钥时,我收到一个错误,我在下面说明了这一点 - On deploying Script to enable Customer Managed Key in Azure Data Factory using terraform, I am getting an error which I have stated below 将托管标识与 Azure 服务总线一起使用 - Using a managed identity with Azure Service Bus 使用托管标识从 Azure Runbook 运行 Get-AzADApplication - Run Get-AzADApplication from an Azure Runbook using a Managed Identity Azure - 尝试在 Terraform 中使用 JsonADDomainExtension 将 VM 加入域 - Azure - Trying to join VM to domain using JsonADDomainExtension in Terraform 使用 terraform 在 azure 虚拟机上部署 tanium 客户端 - Deploying tanium client on an azure virtual machine using terraform 使用托管标识从 Azure 应用服务调用图 - Call Graph from Azure App Service using Managed Identity Terraform Azure 托管磁盘 C & D 驱动器 - Terraform Azure managed disk C & D drives MassTransit:无法使用托管标识访问 Azure 服务总线 - MassTransit: Cannot access Azure Service Bus using managed Identity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM