【问题标题】:Import resources and create VM from image using terraform使用 terraform 从映像导入资源并创建 VM
【发布时间】:2021-05-05 23:32:08
【问题描述】:

我正在尝试导入资源并从 Azure 上的现有映像创建 VM。所有导入都成功,但是当我运行 terraform apply 时,出现以下错误: enter image description here

代码如下:

provider "azurerm" {
    version = "2.0.0"
    subscription_id = var.subscriptionID

    features {}
}
resource "azurerm_resource_group" "TerraformResourceGroup" {

}

resource "azurerm_network_security_group" "TerraformSecurityGroup" {

}

resource "azurerm_virtual_network" "TerraformVirtualNetwork" {

}

resource "azurerm_network_interface" "TerraformNetworkInterface" {

}

resource "azurerm_virtual_machine" "TerraformVM" {
  name                  = var.VM
  location              = var.location
  resource_group_name   = azurerm_resource_group.TerraformResourceGroup.name
  network_interface_ids = [azurerm_network_interface.TerraformNetworkInterface.id]
  vm_size               = "Standard_DS1_v2"

 storage_image_reference {
    id  = "/subscriptions/--/resourceGroups/TerraformResourceGroup/providers/Microsoft.Compute/images/TerraformVM-image-20210201164126"
}

  storage_os_disk {
    name              = "disk1"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
    }

  os_profile {
    computer_name  = var.name
    admin_username = var.username
    admin_password = var.password
  }

  os_profile_windows_config {
     provision_vm_agent = true
  }

  tags = {
    environment = "staging"
  }
}

请帮忙

好吧,让我解释清楚一点。我创建了一个 rg 并使用 terraform 部署了一个 vm,然后捕获了该 VM。现在我需要在同一个 rg 中使用该图像部署一个 vm。我需要使用导入源还是数据源?如果我使用数据源,我得到以下信息:删除虚拟网络“xx”(资源组“yy”)时出错:network.VirtualNetworksClient#Delete:发送请求失败:StatusCode=400 -- 原始错误:Code="InUseSubnetCannotBeDeleted" Message="子网 xx 正在被 /subscriptions/--/resourceGroups/yy/providers/Microsoft.Network/networkInterfaces/xx/ipConfigurations/internal 使用,无法删除。要删除子网,请删除子网内的所有资源子网。 使用数据源的代码

provider "azurerm" {
    version = "2.0.0"
    subscription_id = var.subscriptionID

    features {}
}
data "azurerm_resource_group" "TerraformResourceGroup" {
  name     = var.resourceGroupName
}

data "azurerm_network_security_group" "TerraformSecurityGroup" {
  name                = var.securityGroup
  resource_group_name = data.azurerm_resource_group.TerraformResourceGroup.name
}

data "azurerm_virtual_network" "TerraformVirtualNetwork" {
  name                = var.virtualNetwork
  resource_group_name = data.azurerm_resource_group.TerraformResourceGroup.name
}

data "azurerm_subnet" "TerraformSubNet" {
  name                 = var.subnet
  virtual_network_name = var.virtualNetwork
  resource_group_name  = data.azurerm_resource_group.TerraformResourceGroup.name
}

# Create public IPs
resource "azurerm_public_ip" "test" {
    name                         = var.publicIP
    location                     = "${data.azurerm_resource_group.TerraformResourceGroup.location}"
    resource_group_name          = "${data.azurerm_resource_group.TerraformResourceGroup.name}"
    allocation_method            = "Static"

}

# create a network interface
resource "azurerm_network_interface" "TerraformNetworkInterface" {
  name                = var.networkInterface
  location            = "${data.azurerm_resource_group.TerraformResourceGroup.location}"
  resource_group_name = "${data.azurerm_resource_group.TerraformResourceGroup.name}"

  ip_configuration {
    name                          = "testconfiguration1"
    subnet_id                     = "${data.azurerm_subnet.TerraformSubNet.id}"
    private_ip_address_allocation = "dynamic"
   // public_ip_address_id          = "${azurerm_public_ip.test.id}"
  }
}

resource "azurerm_virtual_machine" "TerraformVM" {
  name                  = var.VM
  location              = var.location
  resource_group_name   = data.azurerm_resource_group.TerraformResourceGroup.name
  network_interface_ids = [azurerm_network_interface.TerraformNetworkInterface.id]
  vm_size               = "Standard_DS1_v2"

 storage_image_reference {
    id  = "/subscriptions/----/resourceGroups/TerraformResourceGroup/providers/Microsoft.Compute/images/TerraformVM-image-20210202111108"
    }

  storage_os_disk {
    name              = "Imagedisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
    }

  os_profile {
    computer_name  = var.name
    admin_username = var.username
    admin_password = var.password
  }

  os_profile_windows_config {
     provision_vm_agent = true
  }

  tags = {
    environment = "staging"
  }
}

你能帮忙吗

【问题讨论】:

    标签: azure terraform virtual-machine terraform-provider-azure


    【解决方案1】:

    根据错误消息,您在 azurerm_network_interface 中缺少参数。

    您需要在resource "azurerm_network_interface"中添加location和resource_group_name:

    这是一个例子:

        provider "azurerm" {
            version = "2.0.0"
            subscription_id = var.subscriptionID
        
            features {}
        }
    
        variable "prefix" {
             default = "tfvmex"
         }
    
        resource "azurerm_resource_group" "TerraformResourceGroup" {
          name     = "${var.prefix}-resources"
          location = "West US 2"
        }
       resource "azurerm_network_security_group" "TerraformSecurityGroup" {
    
       }
        
        resource "azurerm_virtual_network" "TerraformVirtualNetwork" {
          name                = "${var.prefix}-network"
          address_space       = ["10.0.0.0/16"]
          location            = azurerm_resource_group.main.location
          resource_group_name = azurerm_resource_group.main.name
        }
        
        resource "azurerm_network_interface" "TerraformNetworkInterface" {
          name                = "${var.prefix}-nic"
          location            = azurerm_resource_group.main.location
          resource_group_name = azurerm_resource_group.main.name
        
    
        }
        
        ......
    

    更详细的信息,你可以参考这个关于Terraform azurerm_virtual_machine的文档。

    【讨论】:

      【解决方案2】:

      Terraform import 命令不会生成 Terraform 资源配置。相反,它会将您现有的资源导入 Terraform 的状态。

      将现有资源导入状态文件后。您需要参考状态提供的信息手动创建相应的资源配置文件,并使用 Terraform 管理您现有的基础设施。

      例如,您可以运行terraform show,它提供来自状态或计划文件的人类可读输出。

      然后你可以复制name和location的属性和内容来填充块

      resource "azurerm_resource_group" "TerraformResourceGroup" {
          location = "westeurope"
          name     = "nancyexample-resources"
      }
      

      你可以用同样的方法填充剩余的方块。之后,您可以通过运行terraform plan 命令检查配置中的错误。 Terraform 计划向您显示如果您使用 terraform apply 命令应用配置将发生的更改。如果缺少或未设置任何参数,您可以修改配置文件以满足要求。

      验证配置后,您可以运行terraform apply 来创建新资源。如需更多信息,请参阅Import Terraform configuration。

      【讨论】:

      • 在这种情况下,您可以在部署新资源时使用数据源查询现有资源。如果你想保留原有资源,你应该重命名或删除原有文件terraform.tfstate并运行terrafrom init,计划,然后申请。
      • 您是否尝试过删除旧的 terraform.tfstate 然后再次运行 terraform 命令?
      • 您能否展示更多重现此问题的步骤?
      猜你喜欢
      • 2019-03-14
      • 2019-07-14
      • 2021-12-27
      • 2022-07-24
      • 2018-01-10
      • 2019-12-13
      • 2021-03-13
      • 2021-01-21
      • 2020-11-18
      相关资源
      最近更新 更多