added heimdall and longhorn deplyoment

This commit is contained in:
2026-06-06 00:38:01 +02:00
parent 37395e3a4d
commit b61759c3c0
7 changed files with 3078 additions and 4 deletions
+87
View File
@@ -0,0 +1,87 @@
name: Deploy k8s Apps
on:
workflow_dispatch:
push:
branches:
- main
paths:
- 'k8s-apps/**'
- '.gitea/workflows/**'
pull_request:
branches:
- main
paths:
- 'k8s-apps/**'
- '.gitea/workflows/**'
jobs:
preview:
name: Pulumi Preview
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Restore Stack Config
run: echo "${{ secrets.K8S_APPS_DEV_YAML }}" | base64 -d > k8s-apps/Pulumi.dev.yaml
- name: Install Dependencies
run: npm install
working-directory: k8s-apps
- name: Preview
uses: pulumi/actions@v5
with:
command: preview
stack-name: dev
work-dir: k8s-apps
cloud-url: ${{ secrets.PULUMI_BACKEND_URL }}
env:
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
deploy:
name: Pulumi Deploy
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Restore Stack Config
run: echo "${{ secrets.K8S_APPS_DEV_YAML }}" | base64 -d > k8s-apps/Pulumi.dev.yaml
- name: Install Dependencies
run: npm install
working-directory: k8s-apps
- name: Refresh State
uses: pulumi/actions@v5
with:
command: refresh
stack-name: dev
work-dir: k8s-apps
cloud-url: ${{ secrets.PULUMI_BACKEND_URL }}
env:
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
- name: Deploy
uses: pulumi/actions@v5
with:
command: up
stack-name: dev
work-dir: k8s-apps
cloud-url: ${{ secrets.PULUMI_BACKEND_URL }}
env:
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
+23 -4
View File
@@ -3,7 +3,6 @@ import * as k8s from "@pulumi/kubernetes";
const config = new pulumi.Config();
//fetch credentials from k8s-bootstrap
const infraRef = new pulumi.StackReference(
`${pulumi.getOrganization()}/k8s-bootstrap/dev`,
);
@@ -20,7 +19,7 @@ const opts = (extras?: pulumi.ResourceOptions): pulumi.ResourceOptions => ({
...extras,
});
// ── 1. NFS CSI Driver ────────────────────────────────────────────────────────
// ── NFS CSI Driver ────────────────────────────────────────────────────────
const nfsCsiDriver = new k8s.helm.v3.Release(
"nfs-csi-driver",
@@ -57,7 +56,7 @@ new k8s.storage.v1.StorageClass(
opts({ dependsOn: [nfsCsiDriver] }),
);
// ── 2. cert-manager ──────────────────────────────────────────────────────────
// ── cert-manager ──────────────────────────────────────────────────────────
const certManager = new k8s.helm.v3.Release(
"cert-manager",
@@ -75,7 +74,7 @@ const certManager = new k8s.helm.v3.Release(
opts(),
);
// ── 3. Cloudflare token secret + ClusterIssuer ───────────────────────────────
// ── Cloudflare token secret + ClusterIssuer ───────────────────────────────
const cfSecret = new k8s.core.v1.Secret(
"cloudflare-token",
@@ -115,4 +114,24 @@ new k8s.apiextensions.CustomResource(
opts({ dependsOn: [certManager, cfSecret] }),
);
// ── Longhorn ──────────────────────────────────────────────────────────────
new k8s.helm.v3.Release(
"longhorn",
{
name: "longhorn",
chart: "longhorn",
repositoryOpts: { repo: "https://charts.longhorn.io" },
namespace: "longhorn-system",
createNamespace: true,
version: "1.12.0",
values: {
defaultSettings: {
defaultReplicaCount: 3,
},
},
},
opts(),
);
export const storageClass = "truenas-nfs";
+6
View File
@@ -0,0 +1,6 @@
name: k8s-apps
description: Application workloads for the k3s homelab cluster
runtime:
name: nodejs
options:
packagemanager: npm
+133
View File
@@ -0,0 +1,133 @@
import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";
const config = new pulumi.Config();
//fetch credentials from k8s-bootstrap
const bootstrapRef = new pulumi.StackReference(
`${pulumi.getOrganization()}/k8s-bootstrap/dev`,
);
const kubeconfig = bootstrapRef.requireOutput("kubeconfig");
const domain = config.require("domain");
const k8sProvider = new k8s.Provider("k3s", { kubeconfig });
const opts = (extras?: pulumi.ResourceOptions): pulumi.ResourceOptions => ({
provider: k8sProvider,
...extras,
});
const ns = new k8s.core.v1.Namespace(
"heimdall",
{ metadata: { name: "heimdall" } },
opts(),
);
const pvc = new k8s.core.v1.PersistentVolumeClaim(
"heimdall-config",
{
metadata: { name: "heimdall-config", namespace: ns.metadata.name },
spec: {
accessModes: ["ReadWriteOnce"],
storageClassName: "longhorn",
resources: { requests: { storage: "50Mi" } },
},
},
opts(),
);
const labels = { app: "heimdall" };
new k8s.apps.v1.Deployment(
"heimdall",
{
metadata: {
name: "heimdall",
namespace: ns.metadata.name,
annotations: { "pulumi.com/patchForce": "true" },
},
spec: {
replicas: 1,
selector: { matchLabels: labels },
template: {
metadata: { labels },
spec: {
containers: [
{
name: "heimdall",
image: "lscr.io/linuxserver/heimdall:latest",
env: [
{ name: "PUID", value: "1000" },
{ name: "PGID", value: "1000" },
],
ports: [{ containerPort: 80 }],
volumeMounts: [{ name: "config", mountPath: "/config" }],
},
],
volumes: [
{
name: "config",
persistentVolumeClaim: { claimName: pvc.metadata.name },
},
],
terminationGracePeriodSeconds: 5,
},
},
},
},
opts(),
);
const svc = new k8s.core.v1.Service(
"heimdall",
{
metadata: { name: "heimdall", namespace: ns.metadata.name },
spec: {
selector: labels,
ports: [{ port: 80, targetPort: 80 }],
type: "ClusterIP",
},
},
opts(),
);
const host = pulumi.interpolate`heimdall.${domain}`;
new k8s.networking.v1.Ingress(
"heimdall",
{
metadata: {
name: "heimdall",
namespace: ns.metadata.name,
annotations: {
"cert-manager.io/cluster-issuer": "letsencrypt-prod",
},
},
spec: {
ingressClassName: "traefik",
tls: [{ hosts: [host], secretName: "heimdall-tls" }],
rules: [
{
host,
http: {
paths: [
{
path: "/",
pathType: "Prefix",
backend: {
service: {
name: svc.metadata.name,
port: { number: 80 },
},
},
},
],
},
},
],
},
},
opts(),
);
export const ingressHost = host;
+2799
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
{
"name": "k8s-apps",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/kubernetes": "^4.0.0",
"@pulumi/pulumi": "^3.113.0"
}
}
+18
View File
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2020",
"module": "nodenext",
"moduleResolution": "nodenext",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}