共用方式為


使用適用於 Azure 服務的受控識別來驗證 Terraform

Terraform 可讓您定義、預覽和部署雲端基礎結構。 使用 Terraform 時,您可以使用 HCL 語法來建立設定檔。 HCL 語法可讓您指定雲端提供者 (例如 Azure) 和構成雲端基礎結構的元素。 建立設定檔之後,您可以建立執行計畫,讓您先預覽基礎結構變更,之後再部署。 驗證變更之後,您可以套用執行計畫來部署基礎結構。

Azure 資源的 受控識別可用來向 Azure Active Directory 進行驗證。 如果您以非互動式方式執行 Terraform,HashiCorp 建議使用服務主體或受控識別。 有兩種受控識別:系統指派使用者指派。 在本文中,您將瞭解如何使用系統指派的身分識別。

定義系統指派的受控識別

若要使用系統指派的受控識別,請使用下列步驟:

  1. 指定區塊, identity 並將設定 typeSystemAssigned

    resource "azurerm_linux_virtual_machine" "example" {
      # ...
    
      identity {
        type = "SystemAssigned"
      }
    }
    
  2. Contributor 角色授與身分識別。

    data "azurerm_subscription" "current" {}
    
    data "azurerm_role_definition" "contributor" {
      name = "Contributor"
    }
    
    resource "azurerm_role_assignment" "example" {
      scope              = data.azurerm_subscription.current.id
      role_definition_name = "Contributor"
      principal_id       = azurerm_linux_virtual_machine.example.identity[0].principal_id
    }
    
  3. 使用環境變數進行設定,並指定您的 Azure 認證。

    export ARM_USE_MSI=true
    export ARM_SUBSCRIPTION_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    export ARM_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    

範例:使用受控識別建立虛擬機

  1. 建立目錄,然後在目錄中測試範例 Terraform 程式碼,並將其設為目前的目錄。

  2. 建立名為 providers.tf 的檔案,並插入下列程序代碼。

    terraform {
      required_version = ">=0.12"
    
      required_providers {
        azapi = {
          source  = "azure/azapi"
          version = "~>1.5"
        }
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>2.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  3. 建立名為 main.tf 的檔案,並插入下列程式碼:

    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
    }
    
    data "azurerm_subscription" "current" {}
    
    resource "azurerm_virtual_network" "example" {
      name                = "myVnet"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    resource "azurerm_subnet" "example" {
      name                 = "mySubnet"
      resource_group_name  = azurerm_resource_group.rg.name
      virtual_network_name = azurerm_virtual_network.example.name
      address_prefixes     = ["10.0.2.0/24"]
    }
    
    resource "azurerm_network_interface" "example" {
      name                = "myNic"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      ip_configuration {
        name                          = "internal"
        subnet_id                     = azurerm_subnet.example.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_linux_virtual_machine" "example" {
      name                = "myVm"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      size                = "Standard_F2"
      network_interface_ids = [
        azurerm_network_interface.example.id,
      ]
    
      computer_name  = "hostname"
      admin_username = var.username
    
      admin_ssh_key {
        username   = var.username
        public_key = azapi_resource_action.ssh_public_key_gen.output.publicKey
      }
    
      identity {
        type = "SystemAssigned"
      }
    
      os_disk {
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
      source_image_reference {
        publisher = "Canonical"
        offer     = "0001-com-ubuntu-server-jammy"
        sku       = "22_04-lts"
        version   = "latest"
      }
    }
    
    data "azurerm_role_definition" "contributor" {
      name = "Contributor"
    }
    
    resource "azurerm_role_assignment" "example" {
      scope              = data.azurerm_subscription.current.id
      role_definition_name = "Contributor"
      principal_id       = azurerm_linux_virtual_machine.example.identity[0].principal_id
    }
    
  4. 建立名為 ssh.tf 的檔案,並插入下列程序代碼。

    resource "random_pet" "ssh_key_name" {
      prefix    = "ssh"
      separator = ""
    }
    
    resource "azapi_resource_action" "ssh_public_key_gen" {
      type        = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      resource_id = azapi_resource.ssh_public_key.id
      action      = "generateKeyPair"
      method      = "POST"
    
      response_export_values = ["publicKey", "privateKey"]
    }
    
    resource "azapi_resource" "ssh_public_key" {
      type      = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      name      = random_pet.ssh_key_name.id
      location  = azurerm_resource_group.rg.location
      parent_id = azurerm_resource_group.rg.id
    }
    
    output "key_data" {
      value = azapi_resource_action.ssh_public_key_gen.output.publicKey
    }
        ```
    
    
  5. 建立名為 variables.tf 的檔案,並插入下列程式碼:

    variable "resource_group_location" {
      type        = string
      description = "Location of the resource group."
      default     = "eastus"
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
      default     = "rg"
    }
    
    variable "username" {
      type        = string
      description = "The username for the local account that will be created on the new VM."
      default     = "azureadmin"
    }
    
  6. 建立名為 outputs.tf 的檔案,並插入下列程式碼:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "azurerm_linux_virtual_machine_name" {
      value = azurerm_linux_virtual_machine.example.name
    }
    

下一步