Terraform - Azure 上的静态 IP 地址 [英] Terraform - Static ip addresses on Azure
问题描述
我们需要为通过 terraform 部署在 Azure 中的 vm 配置静态私有 ip.原因是我们需要通过 ansible 管道在 Ansible 中使用这些.
我在这里找到的一个解决方案是创建一个具有动态"功能的网卡.地址,然后将其转换为静态"ip 在 Terraform 的下一步中.
# 使用私有 IP 创建网络接口资源azurerm_network_interface"尼克"{for_each = { for vm in var.vms : vm.hostname =>虚拟机 }name = "${each.value.hostname}-NIC";位置 = var.network_locationresource_group_name = var.vm_resource_groupip_configuration {name = "monitoringConfg";subnet_id = data.azurerm_subnet.vm_subnet.idprivate_ip_address_allocation = 动态";}标签 = each.value.extra_tag}#将动态私有 IP 转换为静态资源azurerm_network_interface"静电"{for_each = { for vm in var.vms : vm.hostname =>虚拟机 }name = "${each.value.hostname}-NIC";位置 = var.network_locationresource_group_name = var.vm_resource_groupip_configuration {name = "monitoringConfg";subnet_id = data.azurerm_subnet.vm_subnet.idprivate_ip_address_allocation = 静态";private_ip_address = azurerm_network_interface.nic[each.key].private_ip_address}标签 = each.value.extra_tag
但是当我运行这个时,我收到以下错误:
ID 为/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxxxxxx/providers/Microsoft.Network/networkInterfaces/xxxxxxxxxxxxxxxxxxx-NIC"的资源已经存在 - 要通过 Terraform 进行管理,此资源需要导入到状态中.请参阅azurerm_network_interface"的资源文档.想要查询更多的信息.在 ../../modules/main.tf 第 58 行,在资源azurerm_network_interface"中静电":58:资源azurerm_network_interface";静电"{
有没有人知道我做错了什么或有更好的方法来处理这个问题?
亲切的问候,RB
在网络接口连接到正在运行的虚拟机(或其他资源)之前,Azure 不会分配动态 IP 地址,请参阅到
更新
如果想让 Azure 分配动态 IP,然后将其转换为静态 IP,可以使用 local-exec Provisioner 在创建资源后调用本地可执行文件.
资源null_resource";示例"{for_each = var.vmlist供应商本地执行"{命令 = <<EOT$Nic = Get-AzNetworkInterface -ResourceGroupName ${azurerm_resource_group.main.name} -Name ${azurerm_network_interface.nic[each.key].name}$Nic.IpConfigurations[0].PrivateIpAllocationMethod = 静态"Set-AzNetworkInterface -NetworkInterface $NicEOT解释器 = [PowerShell",-Command"]}}
We have a requirement to configure static private ip's for the vm's that get deployed in Azure via terraform. Tjhe reason is that we then need to use these in Ansible via an ansible pipeline.
One solution I found here was to create a nic with a "dynamic" address first and then convert that to a "static" ip in the next step in Terraform.
# 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
But when I run this, I get the following error:
A resource with the ID "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxxxxxxx/providers/Microsoft.Network/networkInterfaces/xxxxxxxxxxxxxxxxxxx-NIC" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_network_interface" for more information. on ../../modules/main.tf line 58, in resource "azurerm_network_interface" "staticnic": 58: resource "azurerm_network_interface" "staticnic" {
Does anyone have any idea what i am doing wrong or a better way to handle this?
Kind Regards, RB
Azure does not assign a Dynamic IP Address until the Network Interface is attached to a running Virtual Machine (or other resource), refer to this. So I think that we can't convert the Dynamic IP to the Static one before the VM created because the IP address does not exist for that time being.
Instead, we could directly associate some static IP addresses to the Azure VM by assigning some IP address in that subnet range. Read private IP allocation method.
Azure reserves the first four addresses in each subnet address range. The addresses can't be assigned to resources. For example, if the subnet's address range is 10.0.0.0/16, addresses 10.0.0.0-10.0.0.3 and 10.0.255.255 are unavailable.
For example, you may refer this template to configure static private ip's for the vms:
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"
}
}
I am using
Terraform v0.14.7
+ provider registry.terraform.io/hashicorp/azurerm v2.52.0
Update
If you want to let Azure assign the dynamic IP and then convert it to a static one, you can use local-exec Provisioner to invoke a local executable after a resource is created.
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"]
}
}
这篇关于Terraform - Azure 上的静态 IP 地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!