diff --git a/docs/resources/vm_qemu.md b/docs/resources/vm_qemu.md index 19511d05..87023eb0 100644 --- a/docs/resources/vm_qemu.md +++ b/docs/resources/vm_qemu.md @@ -39,7 +39,7 @@ parameter to create based on [a Cloud-init configuration file](https://cloudinit.readthedocs.io/en/latest/topics/examples.html) or use the Proxmox variable `ciuser`, `cipassword`, `ipconfig0`, `ipconfig1`, `ipconfig2`, `ipconfig3`, `ipconfig4`, `ipconfig5`, `ipconfig6`, `ipconfig7`, `ipconfig8`, `ipconfig9`, `ipconfig10`, `ipconfig11`, `ipconfig12`, `ipconfig13`, -`ipconfig14`,`ipconfig15`, `searchdomain`, `nameserver` and `sshkeys`. +`ipconfig14`,`ipconfig15`, `searchdomain`, `nameserver` and `sshkeys`. A variable amount of static IPs can be configured using the dynamic [`ipconfig` block](#ipconfig-block) to list multiple IP addresses. For more information, see the [Cloud-init guide](../guides/cloud_init.md). @@ -164,6 +164,12 @@ details. | `queues` | `int` | `1` | Number of packet queues to be used on the device. Requires `virtio` model to have an effect. | | `link_down` | `bool` | `false` | Whether this interface should be disconnected (like pulling the plug). | +### Ipconfig Block + +The `ipconfig` block is used to configure multiple static IP addresses. It may be specified multiple times. +| Argument | Type | Default Value | Description | +| `config` | `str` | | IP address to assign to the guest. Format: [gw=] [,gw6=] [,ip=] [,ip6=]. | + ### Disk Block The `disk` block is used to configure the disk devices. It may be specified multiple times. The order in which the diff --git a/proxmox/resource_vm_qemu.go b/proxmox/resource_vm_qemu.go index 10fed659..4787529a 100755 --- a/proxmox/resource_vm_qemu.go +++ b/proxmox/resource_vm_qemu.go @@ -1385,6 +1385,7 @@ func resourceVmQemuUpdate(ctx context.Context, d *schema.ResourceData, meta inte "searchdomain", "nameserver", "sshkeys", + "ipconfig", "ipconfig0", "ipconfig1", "ipconfig2", @@ -1651,6 +1652,7 @@ func resourceVmQemuRead(ctx context.Context, d *schema.ResourceData, meta interf d.Set("searchdomain", config.Searchdomain) d.Set("nameserver", config.Nameserver) d.Set("sshkeys", config.Sshkeys) + d.Set("ipconfig", config.Ipconfig) d.Set("ipconfig0", config.Ipconfig[0]) d.Set("ipconfig1", config.Ipconfig[1]) d.Set("ipconfig2", config.Ipconfig[2]) @@ -2259,8 +2261,8 @@ func initConnInfo(ctx context.Context, if config.HasCloudInit() { log.Print("[DEBUG][initConnInfo] vm has a cloud-init configuration") logger.Debug().Int("vmid", vmr.VmId()).Msgf(" vm has a cloud-init configuration") - _, ipconfig0Set := d.GetOk("ipconfig0") - if ipconfig0Set { + _, ipconfigSet := d.GetOk("ipconfig") + if ipconfigSet { vmState, err := client.GetVmState(vmr) log.Printf("[DEBUG][initConnInfo] cloudinitcheck vm state %v", vmState) logger.Debug().Int("vmid", vmr.VmId()).Msgf("cloudinitcheck vm state %v", vmState) @@ -2270,16 +2272,17 @@ func initConnInfo(ctx context.Context, return diag.FromErr(err) } - if d.Get("ipconfig0").(string) != "ip=dhcp" || vmState["agent"] == nil || vmState["agent"].(float64) != 1 { - // parse IP address out of ipconfig0 - ipMatch := rxIPconfig.FindStringSubmatch(d.Get("ipconfig0").(string)) + ipConfig := d.Get("ipconfig").(map[int]string) + if ipConfig[0] != "ip=dhcp" || vmState["agent"] == nil || vmState["agent"].(float64) != 1 { + // parse IP address out of ipconfig + ipMatch := rxIPconfig.FindStringSubmatch(ipConfig[0]) if sshHost == "" { sshHost = ipMatch[1] } ipconfig0 := net.ParseIP(strings.Split(ipMatch[1], ":")[0]) interfaces, err = client.GetVmAgentNetworkInterfaces(vmr) - log.Printf("[DEBUG][initConnInfo] ipconfig0 interfaces: %v", interfaces) - logger.Debug().Int("vmid", vmr.VmId()).Msgf("ipconfig0 interfaces %v", interfaces) + log.Printf("[DEBUG][initConnInfo] ipconfig[0] interfaces: %v", interfaces) + logger.Debug().Int("vmid", vmr.VmId()).Msgf("ipconfig[0] interfaces %v", interfaces) if err != nil { return diag.FromErr(err) } else {