@muhlba91/pulumi-proxmoxve
Version:
A Pulumi package for creating and managing Proxmox Virtual Environment cloud resources.
426 lines • 20.3 kB
JavaScript
;
// *** WARNING: this file was generated by pulumi-language-nodejs. ***
// *** Do not edit by hand unless you're certain you know what you are doing! ***
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VmLegacy = void 0;
const pulumi = __importStar(require("@pulumi/pulumi"));
const utilities = __importStar(require("./utilities"));
/**
* Manages a virtual machine.
*
* ## Example Usage
*
* ```typescript
* import * as pulumi from "@pulumi/pulumi";
* import * as proxmoxve from "@muhlba91/pulumi-proxmoxve";
* import * as random from "@pulumi/random";
* import * as std from "@pulumi/std";
* import * as tls from "@pulumi/tls";
*
* export = async () => {
* const latestUbuntu22JammyQcow2Img = new proxmoxve.download.FileLegacy("latest_ubuntu_22_jammy_qcow2_img", {
* contentType: "import",
* datastoreId: "local",
* nodeName: "pve",
* url: "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img",
* fileName: "jammy-server-cloudimg-amd64.qcow2",
* });
* const ubuntuVmPassword = new random.RandomPassword("ubuntu_vm_password", {
* length: 16,
* overrideSpecial: "_%@",
* special: true,
* });
* const ubuntuVmKey = new tls.PrivateKey("ubuntu_vm_key", {
* algorithm: "RSA",
* rsaBits: 2048,
* });
* const ubuntuVm = new proxmoxve.VmLegacy("ubuntu_vm", {
* serialDevices: [{}],
* name: "terraform-provider-proxmox-ubuntu-vm",
* description: "Managed by Pulumi",
* tags: [
* "terraform",
* "ubuntu",
* ],
* nodeName: "first-node",
* vmId: 4321,
* agent: {
* enabled: false,
* },
* stopOnDestroy: true,
* startup: {
* order: 3,
* upDelay: 60,
* downDelay: 60,
* },
* cpu: {
* cores: 2,
* type: "x86-64-v2-AES",
* },
* memory: {
* dedicated: 2048,
* floating: 2048,
* },
* disks: [{
* datastoreId: "local-lvm",
* importFrom: latestUbuntu22JammyQcow2Img.id,
* "interface": "scsi0",
* }],
* initialization: {
* ipConfigs: [{
* ipv4: {
* address: "dhcp",
* },
* }],
* userAccount: {
* keys: [std.trimspaceOutput({
* input: ubuntuVmKey.publicKeyOpenssh,
* }).apply(invoke => invoke.result)],
* password: ubuntuVmPassword.result,
* username: "ubuntu",
* },
* userDataFileId: cloudConfig.id,
* },
* networkDevices: [{
* bridge: "vmbr0",
* }],
* operatingSystem: {
* type: "l26",
* },
* tpmState: {
* version: "v2.0",
* },
* virtiofs: [{
* mapping: "data_share",
* cache: "always",
* directIo: true,
* }],
* });
* return {
* ubuntuVmPassword: ubuntuVmPassword.result,
* ubuntuVmPrivateKey: ubuntuVmKey.privateKeyPem,
* ubuntuVmPublicKey: ubuntuVmKey.publicKeyOpenssh,
* };
* }
* ```
*
* ## Qemu guest agent
*
* Qemu-guest-agent is an application which can be installed inside guest VM, see
* [Proxmox Wiki](https://pve.proxmox.com/wiki/Qemu-guest-agent) and [Proxmox
* Documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_qemu_agent)
*
* For VM with `agent.enabled = false`, Proxmox uses ACPI for `Shutdown` and
* `Reboot`, and `qemu-guest-agent` is not needed inside the VM. For some VMs,
* the shutdown process may not work, causing the VM to be stuck on destroying.
* Add `stopOnDestroy = true` to the VM configuration to stop the VM instead of
* shutting it down.
*
* Setting `agent.enabled = true` informs Proxmox that the guest agent is expected
* to be *running* inside the VM. Proxmox then uses `qemu-guest-agent` instead of
* ACPI to control the VM. If the agent is not running, Proxmox operations
* `Shutdown` and `Reboot` time out and fail. The failing operation gets a lock on
* the VM, and until the operation times out, other operations like `Stop` and
* `Reboot` cannot be used.
*
* Do **not** run VM with `agent.enabled = true`, unless the VM is configured to
* automatically **start** `qemu-guest-agent` at some point.
*
* "Monitor" tab in Proxmox GUI can be used to send low-level commands to `qemu`.
* See the [documentation](https://www.qemu.org/docs/master/system/monitor.html).
* Commands `systemPowerdown` and `quit` have proven useful in shutting down VMs
* with `agent.enabled = true` and no agent running.
*
* Cloud images usually do not have `qemu-guest-agent` installed. It is possible to
* install and *start* it using cloud-init, e.g. using custom `userDataFileId`
* file.
*
* This provider requires `agent.enabled = true` to populate `ipv4Addresses`,
* `ipv6Addresses` and `networkInterfaceNames` output attributes.
*
* Setting `agent.enabled = true` without running `qemu-guest-agent` in the VM will
* also result in long timeouts when using the provider, both when creating VMs,
* and when refreshing resources. The provider has no way to distinguish between
* "qemu-guest-agent not installed" and "very long boot due to a disk check", it
* trusts the user to set `agent.enabled` correctly and waits for
* `qemu-guest-agent` to start.
*
* ## AMD SEV
*
* AMD SEV (-ES, -SNP) are security features for AMD processors. SEV-SNP support
* is included in Proxmox version **8.4**, see Proxmox Wiki
* and [Proxmox Documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_memory_encryption)
* for more information.
*
* `amd-sev` requires root and therefore `root@pam` auth.
*
* SEV-SNP requires `bios = OVMF` and a supported AMD CPU (`EPYC-v4` for instance), `machine = q35` is also advised. No EFI disk is required since SEV-SNP uses consolidated read-only firmware. A configured EFI will be ignored.
*
* All changes made to `amdSev` will trigger reboots. Removing or adding the `amdSev` block will force a replacement of the resource. Modifying the `amdSev` block will not trigger replacements.
*
* `allowSmt` is by default set to `true` even if `snp` is not the selected type. Proxmox will ignore this value when `snp` is not in use. Likewise `noKeySharing` is `false` by default but ignored by Proxmox when `snp` is in use.
*
* ## High Availability
*
* When managing a virtual machine in a multi-node cluster, the VM's HA settings can
* be managed using the `proxmoxve.HaresourceLegacy` resource.
*
* ```typescript
* import * as pulumi from "@pulumi/pulumi";
* import * as proxmoxve from "@muhlba91/pulumi-proxmoxve";
*
* const ubuntuVm = new proxmoxve.VmLegacy("ubuntu_vm", {
* name: "terraform-provider-proxmox-ubuntu-vm",
* vmId: 4321,
* });
* const ubuntuVmHaresourceLegacy = new proxmoxve.HaresourceLegacy("ubuntu_vm", {
* resourceId: pulumi.interpolate`vm:${ubuntuVm.vmId}`,
* group: "node1",
* state: "started",
* comment: "Managed by Pulumi",
* });
* ```
*
* ### HA-Aware Migration
*
* When changing the `nodeName` of an HA-managed VM, the provider automatically
* handles the migration in an HA-aware manner:
*
* - **Running HA VMs**: Uses the HA manager's migrate endpoint for live migration
* - **Stopped HA VMs**: Temporarily removes from HA, performs standard migration,
* then re-adds to HA with the original configuration preserved
*
* > **PVE 9.x Required**: HA-aware migration requires Proxmox VE 9.x due to API
* changes. On PVE 8.x, migrating HA-managed VMs will fail. As a workaround,
* manually remove the VM from HA before changing `nodeName`, then re-add after
* apply.
*
* ## Important Notes
*
* ### `local-lvm` Datastore
*
* The `local-lvm` is the **default datastore** for many configuration blocks, including `initialization` and `tpmState`, which may not seem to be related to "storage".
* If you do not have `local-lvm` configured in your environment, you may need to explicitly set the `datastoreId` in such blocks to a different value.
*
* ### Cloning
*
* When cloning an existing virtual machine, whether it's a template or not, the
* resource will inherit the disks and other configuration from the source VM.
*
* *If* you modify any attributes of an existing disk in the clone, you also need to\
* explicitly provide values for any other attributes that differ from the schema defaults\
* in the source (e.g., `size`, `discard`, `cache`, `aio`).\
* Otherwise, the schema defaults will take effect and override the source values.
*
* Furthermore, when cloning from one node to a different one, the behavior changes
* depening on the datastores of the source VM. If at least one non-shared
* datastore is used, the VM is first cloned to the source node before being
* migrated to the target node. This circumvents a limitation in the Proxmox clone
* API.
*
* Because the migration step after the clone tries to preserve the used
* datastores by their name, it may fail if a datastore used in the source VM is
* not available on the target node (e.g. `local-lvm` is used on the source node in
* the VM but no `local-lvm` datastore is available on the target node). In this
* case, it is recommended to set the `datastoreId` argument in the `clone` block
* to force the migration step to migrate all disks to a specific datastore on the
* target node. If you need certain disks to be on specific datastores, set
* the `datastoreId` argument of the disks in the `disks` block to move the disks
* to the correct datastore after the cloning and migrating succeeded.
*
* ## Import
*
* Instances can be imported using the `nodeName` and the `vmId`, e.g.,
*
* ```sh
* $ pulumi import proxmoxve:index/vmLegacy:VmLegacy ubuntu_vm first-node/4321
* ```
*/
class VmLegacy extends pulumi.CustomResource {
/**
* Get an existing VmLegacy resource's state with the given name, ID, and optional extra
* properties used to qualify the lookup.
*
* @param name The _unique_ name of the resulting resource.
* @param id The _unique_ provider ID of the resource to lookup.
* @param state Any extra arguments used during the lookup.
* @param opts Optional settings to control the behavior of the CustomResource.
*/
static get(name, id, state, opts) {
return new VmLegacy(name, state, { ...opts, id: id });
}
/** @internal */
static __pulumiType = 'proxmoxve:index/vmLegacy:VmLegacy';
/**
* Returns true if the given object is an instance of VmLegacy. This is designed to work even
* when multiple copies of the Pulumi SDK have been loaded into the same process.
*/
static isInstance(obj) {
if (obj === undefined || obj === null) {
return false;
}
return obj['__pulumiType'] === VmLegacy.__pulumiType;
}
constructor(name, argsOrState, opts) {
let resourceInputs = {};
opts = opts || {};
if (opts.id) {
const state = argsOrState;
resourceInputs["acpi"] = state?.acpi;
resourceInputs["agent"] = state?.agent;
resourceInputs["amdSev"] = state?.amdSev;
resourceInputs["audioDevice"] = state?.audioDevice;
resourceInputs["bios"] = state?.bios;
resourceInputs["bootOrders"] = state?.bootOrders;
resourceInputs["cdrom"] = state?.cdrom;
resourceInputs["clone"] = state?.clone;
resourceInputs["cpu"] = state?.cpu;
resourceInputs["deleteUnreferencedDisksOnDestroy"] = state?.deleteUnreferencedDisksOnDestroy;
resourceInputs["description"] = state?.description;
resourceInputs["disks"] = state?.disks;
resourceInputs["efiDisk"] = state?.efiDisk;
resourceInputs["hookScriptFileId"] = state?.hookScriptFileId;
resourceInputs["hostpcis"] = state?.hostpcis;
resourceInputs["hotplug"] = state?.hotplug;
resourceInputs["initialization"] = state?.initialization;
resourceInputs["ipv4Addresses"] = state?.ipv4Addresses;
resourceInputs["ipv6Addresses"] = state?.ipv6Addresses;
resourceInputs["keyboardLayout"] = state?.keyboardLayout;
resourceInputs["kvmArguments"] = state?.kvmArguments;
resourceInputs["macAddresses"] = state?.macAddresses;
resourceInputs["machine"] = state?.machine;
resourceInputs["memory"] = state?.memory;
resourceInputs["migrate"] = state?.migrate;
resourceInputs["name"] = state?.name;
resourceInputs["networkDevices"] = state?.networkDevices;
resourceInputs["networkInterfaceNames"] = state?.networkInterfaceNames;
resourceInputs["nodeName"] = state?.nodeName;
resourceInputs["numas"] = state?.numas;
resourceInputs["onBoot"] = state?.onBoot;
resourceInputs["operatingSystem"] = state?.operatingSystem;
resourceInputs["poolId"] = state?.poolId;
resourceInputs["protection"] = state?.protection;
resourceInputs["purgeOnDestroy"] = state?.purgeOnDestroy;
resourceInputs["reboot"] = state?.reboot;
resourceInputs["rebootAfterUpdate"] = state?.rebootAfterUpdate;
resourceInputs["rngs"] = state?.rngs;
resourceInputs["scsiHardware"] = state?.scsiHardware;
resourceInputs["serialDevices"] = state?.serialDevices;
resourceInputs["smbios"] = state?.smbios;
resourceInputs["started"] = state?.started;
resourceInputs["startup"] = state?.startup;
resourceInputs["stopOnDestroy"] = state?.stopOnDestroy;
resourceInputs["tabletDevice"] = state?.tabletDevice;
resourceInputs["tags"] = state?.tags;
resourceInputs["template"] = state?.template;
resourceInputs["timeoutClone"] = state?.timeoutClone;
resourceInputs["timeoutCreate"] = state?.timeoutCreate;
resourceInputs["timeoutMigrate"] = state?.timeoutMigrate;
resourceInputs["timeoutMoveDisk"] = state?.timeoutMoveDisk;
resourceInputs["timeoutReboot"] = state?.timeoutReboot;
resourceInputs["timeoutShutdownVm"] = state?.timeoutShutdownVm;
resourceInputs["timeoutStartVm"] = state?.timeoutStartVm;
resourceInputs["timeoutStopVm"] = state?.timeoutStopVm;
resourceInputs["tpmState"] = state?.tpmState;
resourceInputs["usbs"] = state?.usbs;
resourceInputs["vga"] = state?.vga;
resourceInputs["virtiofs"] = state?.virtiofs;
resourceInputs["vmId"] = state?.vmId;
resourceInputs["watchdog"] = state?.watchdog;
}
else {
const args = argsOrState;
if (args?.nodeName === undefined && !opts.urn) {
throw new Error("Missing required property 'nodeName'");
}
resourceInputs["acpi"] = args?.acpi;
resourceInputs["agent"] = args?.agent;
resourceInputs["amdSev"] = args?.amdSev;
resourceInputs["audioDevice"] = args?.audioDevice;
resourceInputs["bios"] = args?.bios;
resourceInputs["bootOrders"] = args?.bootOrders;
resourceInputs["cdrom"] = args?.cdrom;
resourceInputs["clone"] = args?.clone;
resourceInputs["cpu"] = args?.cpu;
resourceInputs["deleteUnreferencedDisksOnDestroy"] = args?.deleteUnreferencedDisksOnDestroy;
resourceInputs["description"] = args?.description;
resourceInputs["disks"] = args?.disks;
resourceInputs["efiDisk"] = args?.efiDisk;
resourceInputs["hookScriptFileId"] = args?.hookScriptFileId;
resourceInputs["hostpcis"] = args?.hostpcis;
resourceInputs["hotplug"] = args?.hotplug;
resourceInputs["initialization"] = args?.initialization;
resourceInputs["keyboardLayout"] = args?.keyboardLayout;
resourceInputs["kvmArguments"] = args?.kvmArguments;
resourceInputs["macAddresses"] = args?.macAddresses;
resourceInputs["machine"] = args?.machine;
resourceInputs["memory"] = args?.memory;
resourceInputs["migrate"] = args?.migrate;
resourceInputs["name"] = args?.name;
resourceInputs["networkDevices"] = args?.networkDevices;
resourceInputs["nodeName"] = args?.nodeName;
resourceInputs["numas"] = args?.numas;
resourceInputs["onBoot"] = args?.onBoot;
resourceInputs["operatingSystem"] = args?.operatingSystem;
resourceInputs["poolId"] = args?.poolId;
resourceInputs["protection"] = args?.protection;
resourceInputs["purgeOnDestroy"] = args?.purgeOnDestroy;
resourceInputs["reboot"] = args?.reboot;
resourceInputs["rebootAfterUpdate"] = args?.rebootAfterUpdate;
resourceInputs["rngs"] = args?.rngs;
resourceInputs["scsiHardware"] = args?.scsiHardware;
resourceInputs["serialDevices"] = args?.serialDevices;
resourceInputs["smbios"] = args?.smbios;
resourceInputs["started"] = args?.started;
resourceInputs["startup"] = args?.startup;
resourceInputs["stopOnDestroy"] = args?.stopOnDestroy;
resourceInputs["tabletDevice"] = args?.tabletDevice;
resourceInputs["tags"] = args?.tags;
resourceInputs["template"] = args?.template;
resourceInputs["timeoutClone"] = args?.timeoutClone;
resourceInputs["timeoutCreate"] = args?.timeoutCreate;
resourceInputs["timeoutMigrate"] = args?.timeoutMigrate;
resourceInputs["timeoutMoveDisk"] = args?.timeoutMoveDisk;
resourceInputs["timeoutReboot"] = args?.timeoutReboot;
resourceInputs["timeoutShutdownVm"] = args?.timeoutShutdownVm;
resourceInputs["timeoutStartVm"] = args?.timeoutStartVm;
resourceInputs["timeoutStopVm"] = args?.timeoutStopVm;
resourceInputs["tpmState"] = args?.tpmState;
resourceInputs["usbs"] = args?.usbs;
resourceInputs["vga"] = args?.vga;
resourceInputs["virtiofs"] = args?.virtiofs;
resourceInputs["vmId"] = args?.vmId;
resourceInputs["watchdog"] = args?.watchdog;
resourceInputs["ipv4Addresses"] = undefined /*out*/;
resourceInputs["ipv6Addresses"] = undefined /*out*/;
resourceInputs["networkInterfaceNames"] = undefined /*out*/;
}
opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts);
super(VmLegacy.__pulumiType, name, resourceInputs, opts);
}
}
exports.VmLegacy = VmLegacy;
//# sourceMappingURL=vmLegacy.js.map