0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 10:33:46 +00:00

feat: Add support for custom cloud-init vendor data file (#162)

* feat: Add support for custom cloud-init vendor data file

Add new argument `initialization`.`vendor_data_file_id` to specify a file ID form snippets.

* add vendor cloud-init to examples

* add missing `vendor` to unmarshal

* remove debug lines
This commit is contained in:
Pavel Boldyrev 2022-11-17 20:33:41 -05:00 committed by GitHub
parent bfdc61e06b
commit 9e34dfb362
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 17 deletions

View File

@ -7,4 +7,4 @@ staleness:
path:
pullrequest: true
paths:
.: 'docs'
docs: 'documentation'

View File

@ -216,6 +216,7 @@ output "ubuntu_vm_public_key" {
* `username` - (Optional) The SSH username.
* `user_data_file_id` - (Optional) The identifier for a file containing custom user data (conflicts
with `user_account`).
* `vendor_data_file_id` - (Optional) The identifier for a file containing all vendor data passed to the VM via cloud-init.
* `keyboard_layout` - (Optional) The keyboard layout (defaults to `en-us`).
* `da` - Danish.
* `de` - German.

View File

@ -2,7 +2,7 @@
# Cloud Config (cloud-init)
#===============================================================================
resource "proxmox_virtual_environment_file" "cloud_config" {
resource "proxmox_virtual_environment_file" "user_config" {
content_type = "snippets"
datastore_id = element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local"))
node_name = data.proxmox_virtual_environment_datastores.example.node_name
@ -15,8 +15,6 @@ chpasswd:
ubuntu:example
expire: false
hostname: terraform-provider-proxmox-example
packages:
- qemu-guest-agent
users:
- default
- name: ubuntu
@ -27,10 +25,31 @@ users:
sudo: ALL=(ALL) NOPASSWD:ALL
EOF
file_name = "terraform-provider-proxmox-example-cloud-config.yaml"
file_name = "terraform-provider-proxmox-example-user-config.yaml"
}
}
resource "proxmox_virtual_environment_file" "vendor_config" {
content_type = "snippets"
datastore_id = element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local"))
node_name = data.proxmox_virtual_environment_datastores.example.node_name
source_raw {
data = <<EOF
#cloud-config
runcmd:
- apt update
- apt install -y qemu-guest-agent
- systemctl enable qemu-guest-agent
- systemctl start qemu-guest-agent
- echo "done" > /tmp/vendor-cloud-init-done
EOF
file_name = "terraform-provider-proxmox-example-vendor-config.yaml"
}
}
#===============================================================================
# Ubuntu Cloud Image
#===============================================================================

View File

@ -8,7 +8,7 @@ resource "proxmox_virtual_environment_vm" "example_template" {
disk {
datastore_id = element(data.proxmox_virtual_environment_datastores.example.datastore_ids, index(data.proxmox_virtual_environment_datastores.example.datastore_ids, "local-lvm"))
file_id = proxmox_virtual_environment_file.ubuntu_cloud_image.id
interface = "scsi0"
interface = "virtio0"
discard = "on"
iothread = true
}
@ -17,7 +17,6 @@ resource "proxmox_virtual_environment_vm" "example_template" {
# datastore_id = "nfs"
# interface = "scsi1"
# discard = "ignore"
# iothread = true
# file_format = "raw"
# }
@ -34,13 +33,8 @@ resource "proxmox_virtual_environment_vm" "example_template" {
}
}
user_account {
keys = [trimspace(tls_private_key.example.public_key_openssh)]
password = "example"
username = "ubuntu"
}
user_data_file_id = proxmox_virtual_environment_file.cloud_config.id
user_data_file_id = proxmox_virtual_environment_file.user_config.id
vendor_data_file_id = proxmox_virtual_environment_file.vendor_config.id
}
name = "terraform-provider-proxmox-example-template"

View File

@ -19,7 +19,7 @@ func main() {
opts := &plugin.ServeOpts{
Debug: debug,
ProviderAddr: "registry.terraform.io/bpg/terraform",
ProviderAddr: "registry.terraform.io/bpg/proxmox",
ProviderFunc: func() *schema.Provider {
return proxmoxtf.Provider()
},

View File

@ -48,6 +48,7 @@ type CustomCloudInitFiles struct {
MetaVolume *string `json:"meta,omitempty" url:"meta,omitempty"`
NetworkVolume *string `json:"network,omitempty" url:"network,omitempty"`
UserVolume *string `json:"user,omitempty" url:"user,omitempty"`
VendorVolume *string `json:"vendor,omitempty" url:"vendor,omitempty"`
}
// CustomCloudInitIPConfig handles QEMU cloud-init IP configuration parameters.
@ -221,7 +222,7 @@ type VirtualEnvironmentVMCloneRequestBody struct {
VMIDNew int `json:"newid" url:"newid"`
}
// VirtualEnvironmentVMCreateRequestBody contains the data for an virtual machine create request.
// VirtualEnvironmentVMCreateRequestBody contains the data for a virtual machine create request.
type VirtualEnvironmentVMCreateRequestBody struct {
ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"`
@ -623,7 +624,7 @@ func (r CustomAudioDevices) EncodeValues(key string, v *url.Values) error {
return nil
}
// EncodeValues converts a CustomCloudInitConfig struct to multiple URL vlaues.
// EncodeValues converts a CustomCloudInitConfig struct to multiple URL values.
func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
if r.Files != nil {
var volumes []string
@ -640,6 +641,10 @@ func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
volumes = append(volumes, fmt.Sprintf("user=%s", *r.Files.UserVolume))
}
if r.Files.VendorVolume != nil {
volumes = append(volumes, fmt.Sprintf("vendor=%s", *r.Files.VendorVolume))
}
if len(volumes) > 0 {
v.Add("cicustom", strings.Join(volumes, ","))
}
@ -1279,6 +1284,8 @@ func (r *CustomCloudInitFiles) UnmarshalJSON(b []byte) error {
r.MetaVolume = &v[1]
case "user":
r.UserVolume = &v[1]
case "vendor":
r.VendorVolume = &v[1]
}
}
}

View File

@ -65,6 +65,7 @@ const (
dvResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway = ""
dvResourceVirtualEnvironmentVMInitializationUserAccountPassword = ""
dvResourceVirtualEnvironmentVMInitializationUserDataFileID = ""
dvResourceVirtualEnvironmentVMInitializationVendorDataFileID = ""
dvResourceVirtualEnvironmentVMInitializationType = ""
dvResourceVirtualEnvironmentVMKeyboardLayout = "en-us"
dvResourceVirtualEnvironmentVMMemoryDedicated = 512
@ -160,6 +161,7 @@ const (
mkResourceVirtualEnvironmentVMInitializationUserAccountPassword = "password"
mkResourceVirtualEnvironmentVMInitializationUserAccountUsername = "username"
mkResourceVirtualEnvironmentVMInitializationUserDataFileID = "user_data_file_id"
mkResourceVirtualEnvironmentVMInitializationVendorDataFileID = "vendor_data_file_id"
mkResourceVirtualEnvironmentVMIPv4Addresses = "ipv4_addresses"
mkResourceVirtualEnvironmentVMIPv6Addresses = "ipv6_addresses"
mkResourceVirtualEnvironmentVMKeyboardLayout = "keyboard_layout"
@ -741,6 +743,14 @@ func resourceVirtualEnvironmentVM() *schema.Resource {
Default: dvResourceVirtualEnvironmentVMInitializationUserDataFileID,
ValidateDiagFunc: getFileIDValidator(),
},
mkResourceVirtualEnvironmentVMInitializationVendorDataFileID: {
Type: schema.TypeString,
Description: "The ID of a file containing vendor data",
Optional: true,
ForceNew: true,
Default: dvResourceVirtualEnvironmentVMInitializationVendorDataFileID,
ValidateDiagFunc: getFileIDValidator(),
},
mkResourceVirtualEnvironmentVMInitializationType: {
Type: schema.TypeString,
Description: "The cloud-init configuration format",
@ -2087,6 +2097,15 @@ func resourceVirtualEnvironmentVMGetCloudInitConfig(d *schema.ResourceData) (*pr
}
}
initializationVendorDataFileID := initializationBlock[mkResourceVirtualEnvironmentVMInitializationVendorDataFileID].(string)
if initializationVendorDataFileID != "" {
if initializationConfig.Files == nil {
initializationConfig.Files = &proxmox.CustomCloudInitFiles{}
}
initializationConfig.Files.VendorVolume = &initializationVendorDataFileID
}
initializationType := initializationBlock[mkResourceVirtualEnvironmentVMInitializationType].(string)
if initializationType != "" {
@ -2817,8 +2836,14 @@ func resourceVirtualEnvironmentVMReadCustom(ctx context.Context, d *schema.Resou
} else {
initialization[mkResourceVirtualEnvironmentVMInitializationUserDataFileID] = ""
}
if vmConfig.CloudInitFiles.VendorVolume != nil {
initialization[mkResourceVirtualEnvironmentVMInitializationVendorDataFileID] = *vmConfig.CloudInitFiles.VendorVolume
} else {
initialization[mkResourceVirtualEnvironmentVMInitializationVendorDataFileID] = ""
}
} else if len(initialization) > 0 {
initialization[mkResourceVirtualEnvironmentVMInitializationUserDataFileID] = ""
initialization[mkResourceVirtualEnvironmentVMInitializationVendorDataFileID] = ""
}
if vmConfig.CloudInitType != nil {