Terraform-Azure上的静态ip地址
我们需要为通过terraform在Azure中部署的vm配置静态私有ip。原因是我们需要通过Ansible管道在Ansible中使用它们 我在这里找到的一个解决方案是首先创建一个具有“动态”地址的nic,然后在Terraform的下一步中将其转换为“静态”ipTerraform-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
# 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