Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Terraform-Azure上的静态ip地址_Azure_Ansible_Terraform_Terraform Provider Azure - Fatal编程技术网

Terraform-Azure上的静态ip地址

Terraform-Azure上的静态ip地址,azure,ansible,terraform,terraform-provider-azure,Azure,Ansible,Terraform,Terraform Provider Azure,我们需要为通过terraform在Azure中部署的vm配置静态私有ip。原因是我们需要通过Ansible管道在Ansible中使用它们 我在这里找到的一个解决方案是首先创建一个具有“动态”地址的nic,然后在Terraform的下一步中将其转换为“静态”ip # Create network interfaces with Private IP's resource "azurerm_network_interface" "nic" { for_ea

我们需要为通过terraform在Azure中部署的vm配置静态私有ip。原因是我们需要通过Ansible管道在Ansible中使用它们

我在这里找到的一个解决方案是首先创建一个具有“动态”地址的nic,然后在Terraform的下一步中将其转换为“静态”ip

# Create network interfaces with Private IP's
resource "azurerm_network_interface" "nic" {
  for_each = { for vm in var.vms : vm.hostname => vm }
  name                = "${each.value.hostname}-NIC"
  location            = var.network_location
  resource_group_name = var.vm_resource_group
  ip_configuration {
    name                          = "monitoringConfg"
    subnet_id                     = data.azurerm_subnet.vm_subnet.id
    private_ip_address_allocation = "dynamic"
  }
  tags = each.value.extra_tag
}

#Convert Dynamic Private IP's to Static
resource "azurerm_network_interface" "staticnic" {
  for_each = { for vm in var.vms : vm.hostname => vm }
  name                = "${each.value.hostname}-NIC"
  location            = var.network_location
  resource_group_name = var.vm_resource_group
  ip_configuration {
    name                          = "monitoringConfg"
    subnet_id                     = data.azurerm_subnet.vm_subnet.id
    private_ip_address_allocation = "static"
    private_ip_address            = azurerm_network_interface.nic[each.key].private_ip_address    
  }
  tags = each.value.extra_tag
但是,当我运行此命令时,会出现以下错误:

ID为“/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx-xxxxxxxx/resourceGroups/xxxxxxxxxxxxxx/providers/Microsoft.networkInterfaces/xxxxxxxxxxxxxxxx-NIC”的资源已存在-要通过Terraform管理此资源需要导入状态。有关更多信息,请参阅“azurerm_网络_接口”的资源文档。 在.././modules/main.tf第58行的资源“azurerm_网络_接口”“staticnic”中: 58:资源“azurerm_网络_接口”“静态NIC”{

有没有人知道我做错了什么,或者有没有更好的方法来处理这个问题

亲切问候,,
RB

在网络接口连接到正在运行的虚拟机(或其他资源)之前,Azure不会分配动态IP地址。,请参阅。因此,我认为在创建虚拟机之前,我们无法将动态IP转换为静态IP,因为该IP地址暂时不存在

相反,我们可以通过在该子网范围内分配一些IP地址,将一些静态IP地址直接关联到Azure VM。读取分配方法

Azure保留每个子网地址范围中的前四个地址。 无法将地址分配给资源。例如,如果 子网的地址范围为10.0.0.0/16,地址范围为10.0.0.0-10.0.0.3和 10.0.255.255不可用

例如,您可以参考此模板为VM配置静态专用ip:

variable "vmlist" {
  type = map(object({
    hostname = string
    IP_address = string
  }))
  default = {
    vm1 ={
    hostname = "vma"
    IP_address = "10.0.2.4"
    },
    vm2 = {
    hostname = "vmb"
    IP_address = "10.0.2.5"
    }
  }
}

#...

resource "azurerm_network_interface" "staticnic" {
  for_each = var.vmlist
  name                = "${each.value.hostname}-nic"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name

  ip_configuration {
    name                          = "testconfiguration1"
    subnet_id                     = azurerm_subnet.internal.id
    private_ip_address_allocation = "Static"
    private_ip_address            = each.value.IP_address
  }
}

 #...

resource "azurerm_virtual_machine" "main" {
  for_each = var.vmlist
  name                  = each.value.hostname
  location              = azurerm_resource_group.main.location
  resource_group_name   = azurerm_resource_group.main.name
  network_interface_ids = [azurerm_network_interface.staticnic[each.key].id]
  vm_size               = "Standard_DS1_v2"

  # Uncomment this line to delete the OS disk automatically when deleting the VM
  # delete_os_disk_on_termination = true

  # Uncomment this line to delete the data disks automatically when deleting the VM
  # delete_data_disks_on_termination = true

  storage_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2016-Datacenter"
    version   = "latest"
  }

  storage_os_disk {
    name              = "${each.value.hostname}-osdisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }
  os_profile {
    computer_name  = each.value.hostname
    admin_username = "testadmin"
    admin_password = "Password1234!"
  }

   os_profile_windows_config {
    provision_vm_agent = "true"
  }

}
我正在使用

Terraform v0.14.7
+ provider registry.terraform.io/hashicorp/azurerm v2.52.0

更新 如果您想让Azure分配动态IP,然后将其转换为静态IP,则可以在创建资源后使用调用本地可执行文件

resource "null_resource" "example" {

  for_each = var.vmlist
    provisioner "local-exec" {

   command = <<EOT

      $Nic = Get-AzNetworkInterface -ResourceGroupName ${azurerm_resource_group.main.name} -Name ${azurerm_network_interface.nic[each.key].name}
      $Nic.IpConfigurations[0].PrivateIpAllocationMethod = "Static"
      Set-AzNetworkInterface -NetworkInterface $Nic
   EOT
   
   interpreter = ["PowerShell", "-Command"]
  
  }
}
resource“null\u资源”示例{
for_each=var.vmlist
供应人“本地执行官”{

command=为了便于阅读,这就是所做的

首先,我使用这里列出的步骤在azure中创建了一个服务原则

变量。TF

resource "azurerm_network_interface" "nic" {
  for_each = { for vm in var.vms : vm.hostname => vm }
  name                = "${each.value.hostname}-NIC"
  location            = var.network_location
  resource_group_name = var.vm_resource_group
  ip_configuration {
    name                          = var.nic_ip_config
    subnet_id                     = data.azurerm_subnet.vm_subnet.id
    private_ip_address_allocation = "dynamic"
  }
  tags = each.value.extra_tag
}
命令输出作为变量添加到variables.TF

variable APP_ID {
  default = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
}
variable SP_PASSWORD {
  default = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
variable TENANT_ID {
  default = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
此服务主体变量将用于在windows worker agent上运行az网络命令之前进行az登录

Main.TF

resource "azurerm_network_interface" "nic" {
  for_each = { for vm in var.vms : vm.hostname => vm }
  name                = "${each.value.hostname}-NIC"
  location            = var.network_location
  resource_group_name = var.vm_resource_group
  ip_configuration {
    name                          = var.nic_ip_config
    subnet_id                     = data.azurerm_subnet.vm_subnet.id
    private_ip_address_allocation = "dynamic"
  }
  tags = each.value.extra_tag
}
将上述动态ip的tp转换为静态

# Convert All Private IP's from Dynamic to Static using powershell
resource "null_resource" "StaticIPsPrivateVMs" {
  for_each = { for vm in var.vms : vm.hostname => vm }
    provisioner "local-exec" {
      command = <<EOT
      az login --service-principal --username ${var.APP_ID} --password ${var.SP_PASSWORD} --tenant ${var.TENANT_ID}
      az network nic ip-config update -g ${var.vm_resource_group} --nic-name ${azurerm_network_interface.nic[each.key].name} --name ${var.nic_ip_config} --set privateIpAllocationMethod="Static"
      EOT
    interpreter = ["powershell", "-Command"]
  }
  depends_on = [
    azurerm_virtual_machine.vm
  ]
}

#AZ logout
resource "null_resource" "AzLogout" {
    provisioner "local-exec" {
      command = <<EOT
      az logout
      EOT
    interpreter = ["powershell", "-Command"]
  }
  depends_on = [
    null_resource.StaticIPsPrivateVMs
  ]
}

继续讨论什么是“vm.hostname”?可能这有重复的名称,这会导致您的错误?如果是,您可以使用PowerShell脚本将其作为我的更新进行管理。谢谢Nancy,这看起来很有希望。我尝试过,但出现了错误:':exec:“PowerShell”:在$PATH.Output中未找到可执行文件:。我正在使用Ubuntu Azure代理。我甚至尝试使用pwsh而不是powershell作为解释器。我有一个带有验证和部署阶段的Azure-pipelines.yml文件(用于terraform)然后是一个powershell脚本,用于从代理复制主机文件。我认为我无法在部署后在Yaml文件中运行powershell脚本,因为管道不知道terraform生成的变量/ip地址。内联运行它会更有意义,因为我可以使用变量。是否有其他指针来完成此操作?这是最后一个对我来说,这是一个关键点。我不熟悉Azure DevOps服务。上面的脚本可以在我的本地windows计算机上正常工作。对于ubuntu代理,如果该代理上安装了az CLI,则可以使用provisioner“local exec”
az network nic ip config update-g--nic name--name--set privateIpAllocationMethod=“Static”运行CLI命令
,阅读了解更多详细信息。谢谢Nancy。我最终将池vmImage更改为windows最新版本。在main.tf中,我在空资源中添加了以下
az登录--服务主体--用户名${var.APP_ID}--密码${var.SP_密码}--租户${var.tenant_ID}az网络nic ip配置更新-g${var.vm\u resource\u group}--nic name${azurerm\u network\u interface.publicnic[each.key].name}--name${var.nic\u ip\u config}--set privateIpAllocationMethod=“Static”
最后是一个带有
az logout
的空资源。使用的所有资源
解释器=[“powershell”,“-Command”]
- stage: deploy
    jobs:
    - deployment: deploy
      pool:
        vmImage: 'windows-latest'
      continueOnError: false