preparing new 3rd pve node #30

Merged
kasun merged 4 commits from add-3rd-proxmox-node into main 2026-07-28 22:28:11 +02:00
+90 -21
View File
@@ -6,9 +6,12 @@ import * as pfsense from "@pulumi/pfsense";
const config = new pulumi.Config(); const config = new pulumi.Config();
const pve1Endpoint = config.requireSecret("pve1Endpoint"); const pve1Endpoint = config.requireSecret("pve1Endpoint");
const pve1ApiToken = config.requireSecret("pve1ApiToken");
const pve2Endpoint = config.requireSecret("pve2Endpoint"); const pve2Endpoint = config.requireSecret("pve2Endpoint");
const pve3Endpoint = config.requireSecret("pve3Endpoint");
const pve1ApiToken = config.requireSecret("pve1ApiToken");
const pve2ApiToken = config.requireSecret("pve2ApiToken"); const pve2ApiToken = config.requireSecret("pve2ApiToken");
const pve3ApiToken = config.requireSecret("pve3ApiToken");
const pfSenseUrl = config.requireSecret("pfSenseUrl"); const pfSenseUrl = config.requireSecret("pfSenseUrl");
const pfSenseUser = config.requireSecret("pfSenseUser"); const pfSenseUser = config.requireSecret("pfSenseUser");
@@ -16,9 +19,11 @@ const pfSensePassword = config.requireSecret("pfSensePassword");
const master1Ip = config.requireSecret("master1Ip"); const master1Ip = config.requireSecret("master1Ip");
const master2Ip = config.requireSecret("master2Ip"); const master2Ip = config.requireSecret("master2Ip");
const worker1Ip = config.requireSecret("worker1Ip");
const master3Ip = config.requireSecret("master3Ip"); const master3Ip = config.requireSecret("master3Ip");
const worker1Ip = config.requireSecret("worker1Ip");
const worker2Ip = config.requireSecret("worker2Ip"); const worker2Ip = config.requireSecret("worker2Ip");
const worker3Ip = config.requireSecret("worker3Ip");
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Providers — one per standalone Proxmox machine // Providers — one per standalone Proxmox machine
@@ -36,6 +41,18 @@ const pveBckpProvider = new proxmox.Provider("pve-bckp", {
insecure: true, insecure: true,
}); });
const pveEsprimoProvider = new proxmox.Provider("pve-esprimo", {
endpoint: pve3Endpoint,
apiToken: pve3ApiToken,
insecure: true,
});
const pveNodes = {
"pve-b550": { nodeName: "pve", isoStore: "pve-local-ext1", dataStore: "local-lvm" },
"pve-optiplex": { nodeName: "pve-bckp", isoStore: "local", dataStore: "local" },
"pve-esprimo": { nodeName: "pve", isoStore: "local", dataStore: "local-lvm" },
} as const;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Providers — PfSense // Providers — PfSense
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -66,8 +83,8 @@ const ubuntuNobleUrl =
const ubuntuImagePve = new proxmox.download.File( const ubuntuImagePve = new proxmox.download.File(
"ubuntu-noble-pve", "ubuntu-noble-pve",
{ {
nodeName: "pve", nodeName: pveNodes["pve-b550"].nodeName,
datastoreId: "pve-local-ext1", datastoreId: pveNodes["pve-b550"].isoStore,
contentType: "import", contentType: "import",
fileName: "noble-server-cloudimg-amd64.qcow2", fileName: "noble-server-cloudimg-amd64.qcow2",
url: ubuntuNobleUrl, url: ubuntuNobleUrl,
@@ -80,8 +97,8 @@ const ubuntuImagePve = new proxmox.download.File(
const ubuntuImagePveBckp = new proxmox.download.File( const ubuntuImagePveBckp = new proxmox.download.File(
"ubuntu-noble-pve-bckp", "ubuntu-noble-pve-bckp",
{ {
nodeName: "pve-bckp", nodeName: pveNodes["pve-optiplex"].nodeName,
datastoreId: "local", datastoreId: pveNodes["pve-optiplex"].isoStore,
contentType: "import", contentType: "import",
fileName: "noble-server-cloudimg-amd64.qcow2", fileName: "noble-server-cloudimg-amd64.qcow2",
url: ubuntuNobleUrl, url: ubuntuNobleUrl,
@@ -91,6 +108,20 @@ const ubuntuImagePveBckp = new proxmox.download.File(
{ provider: pveBckpProvider }, { provider: pveBckpProvider },
); );
const ubuntuImagePveEsprimo = new proxmox.download.File(
"ubuntu-noble-pve-esprimo",
{
nodeName: pveNodes["pve-esprimo"].nodeName,
datastoreId: pveNodes["pve-esprimo"].isoStore,
contentType: "import",
fileName: "noble-server-cloudimg-amd64.qcow2",
url: ubuntuNobleUrl,
overwrite: false,
overwriteUnmanaged: true,
},
{ provider: pveEsprimoProvider },
);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// VM templates — one per node, cloned from the downloaded cloud image. // VM templates — one per node, cloned from the downloaded cloud image.
// Templates are not started and have no cloud-init config; that is applied // Templates are not started and have no cloud-init config; that is applied
@@ -127,7 +158,7 @@ const pveTemplate = new proxmox.VmLegacy(
disks: [ disks: [
{ {
interface: "scsi0", interface: "scsi0",
datastoreId: "local-lvm", datastoreId: pveNodes["pve-b550"].dataStore,
importFrom: pulumi.interpolate`${ubuntuImagePve.datastoreId}:import/${ubuntuImagePve.fileName}`, importFrom: pulumi.interpolate`${ubuntuImagePve.datastoreId}:import/${ubuntuImagePve.fileName}`,
size: 10, size: 10,
ssd: true, ssd: true,
@@ -147,7 +178,7 @@ const pveBckpTemplate = new proxmox.VmLegacy(
disks: [ disks: [
{ {
interface: "scsi0", interface: "scsi0",
datastoreId: "local", datastoreId: pveNodes["pve-optiplex"].dataStore,
importFrom: pulumi.interpolate`${ubuntuImagePveBckp.datastoreId}:import/${ubuntuImagePveBckp.fileName}`, importFrom: pulumi.interpolate`${ubuntuImagePveBckp.datastoreId}:import/${ubuntuImagePveBckp.fileName}`,
size: 10, size: 10,
ssd: true, ssd: true,
@@ -158,6 +189,26 @@ const pveBckpTemplate = new proxmox.VmLegacy(
{ provider: pveBckpProvider, ignoreChanges: ["disks"] }, { provider: pveBckpProvider, ignoreChanges: ["disks"] },
); );
const pveEsprimoTemplate = new proxmox.VmLegacy(
"k3s-template-pve-esprimo",
{
...templateSettings,
nodeName: "pve",
name: "k3s-ubuntu-noble-template",
disks: [
{
interface: "scsi0",
datastoreId: pveNodes["pve-esprimo"].dataStore,
importFrom: pulumi.interpolate`${ubuntuImagePveEsprimo.datastoreId}:import/${ubuntuImagePveEsprimo.fileName}`,
size: 10,
ssd: true,
discard: "on",
},
],
},
{ provider: pveEsprimoProvider, ignoreChanges: ["disks"] },
);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// k3s nodes — full clones of their respective templates // k3s nodes — full clones of their respective templates
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -180,50 +231,60 @@ const nodeConfigs: NodeConfig[] = [
{ {
name: "k3s-master-1", name: "k3s-master-1",
role: "master", role: "master",
nodeName: "pve", nodeName: pveNodes["pve-b550"].nodeName,
provider: pveProvider, provider: pveProvider,
template: pveTemplate, template: pveTemplate,
diskDatastore: "local-lvm", diskDatastore: pveNodes["pve-b550"].dataStore,
ip: master1Ip, ip: master1Ip,
}, },
{ {
name: "k3s-master-2", name: "k3s-master-2",
role: "master", role: "master",
nodeName: "pve", nodeName: pveNodes["pve-esprimo"].nodeName,
provider: pveProvider, provider: pveEsprimoProvider,
template: pveTemplate, template: pveTemplate,
diskDatastore: "local-lvm", diskDatastore: pveNodes["pve-esprimo"].dataStore,
ip: master2Ip, ip: master2Ip,
}, },
{ {
name: "k3s-worker-1", name: "k3s-worker-1",
role: "worker", role: "worker",
nodeName: "pve", nodeName: pveNodes["pve-b550"].nodeName,
provider: pveProvider, provider: pveProvider,
template: pveTemplate, template: pveTemplate,
diskDatastore: "local-lvm", diskDatastore: pveNodes["pve-b550"].dataStore,
ip: worker1Ip, ip: worker1Ip,
longhornDiskSize: 50, longhornDiskSize: 50,
}, },
{ {
name: "k3s-master-3", name: "k3s-master-3",
role: "master", role: "master",
nodeName: "pve-bckp", nodeName: pveNodes["pve-optiplex"].nodeName,
provider: pveBckpProvider, provider: pveBckpProvider,
template: pveBckpTemplate, template: pveBckpTemplate,
diskDatastore: "local", diskDatastore: pveNodes["pve-optiplex"].dataStore,
ip: master3Ip, ip: master3Ip,
}, },
{ {
name: "k3s-worker-2", name: "k3s-worker-2",
role: "worker", role: "worker",
nodeName: "pve-bckp", nodeName: pveNodes["pve-optiplex"].nodeName,
provider: pveBckpProvider, provider: pveBckpProvider,
template: pveBckpTemplate, template: pveBckpTemplate,
diskDatastore: "local", diskDatastore: pveNodes["pve-optiplex"].dataStore,
ip: worker2Ip, ip: worker2Ip,
longhornDiskSize: 50, longhornDiskSize: 50,
}, },
{
name: "k3s-worker-3",
role: "worker",
nodeName: pveNodes["pve-esprimo"].nodeName,
provider: pveEsprimoProvider,
template: pveEsprimoTemplate,
diskDatastore: pveNodes["pve-esprimo"].dataStore,
ip: worker3Ip,
longhornDiskSize: 50,
},
]; ];
const k3sVms = nodeConfigs.map( const k3sVms = nodeConfigs.map(
@@ -321,11 +382,19 @@ export const vmIds = {
worker1: k3sVms[2].vmId, worker1: k3sVms[2].vmId,
master3: k3sVms[3].vmId, master3: k3sVms[3].vmId,
worker2: k3sVms[4].vmId, worker2: k3sVms[4].vmId,
worker3: k3sVms[5].vmId,
}; };
// CI runner SSH private key — consumed by k8s-bootstrap via StackReference. // CI runner SSH private key — consumed by k8s-bootstrap via StackReference.
export const ciRunnerPrivateKey = pulumi.secret(ciRunnerKey.privateKeyOpenssh); export const ciRunnerPrivateKey = pulumi.secret(ciRunnerKey.privateKeyOpenssh);
export { pve1Endpoint, pve1ApiToken, pve2Endpoint, pve2ApiToken }; export {
pve1Endpoint,
pve1ApiToken,
pve2Endpoint,
pve2ApiToken,
pve3Endpoint,
pve3ApiToken,
};
export { master1Ip, master2Ip, worker1Ip, master3Ip, worker2Ip }; export { master1Ip, master2Ip, worker1Ip, master3Ip, worker2Ip, worker3Ip };