feat: CoreServices | move into separate stack

This commit is contained in:
2025-11-22 19:30:09 +05:00
parent 1671f9619c
commit f46833571c
10 changed files with 101 additions and 118 deletions

View File

@@ -1,85 +0,0 @@
import { Construct } from "constructs";
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
export interface CertificateOptions {
provider: KubernetesProvider;
/** Namespace to create the Certificate in */
namespace: string;
/** Required name of the certificate (and CRD name) */
name: string;
/** Secret name for storing the issued TLS cert */
secretName: string;
/** One or more DNS names the certificate should cover */
dnsNames: string[];
/** Reference to the cert-manager issuer */
issuerRef: {
name: string;
kind?: string; // ClusterIssuer or Issuer
};
/** Optional duration (default: cert-manager default) */
duration?: string;
/** Optional renewBefore (default: cert-manager default) */
renewBefore?: string;
}
class Certificate extends Construct {
public readonly manifest: Manifest;
constructor(scope: Construct, id: string, opts: CertificateOptions) {
super(scope, id);
const manifest: any = {
apiVersion: "cert-manager.io/v1",
kind: "Certificate",
metadata: {
name: opts.name,
namespace: opts.namespace,
},
spec: {
secretName: opts.secretName,
dnsNames: opts.dnsNames,
issuerRef: {
name: opts.issuerRef.name,
kind: opts.issuerRef.kind ?? "ClusterIssuer",
},
},
};
if (opts.duration) {
manifest.spec.duration = opts.duration;
}
if (opts.renewBefore) {
manifest.spec.renewBefore = opts.renewBefore;
}
this.manifest = new Manifest(this, id, {
provider: opts.provider,
manifest,
});
}
}
export class CloudflareCertificate extends Certificate {
constructor(
scope: Construct,
id: string,
opts: Omit<CertificateOptions, "issuerRef">,
) {
super(scope, id, {
...opts,
issuerRef: {
name: "cloudflare-issuer",
kind: "ClusterIssuer",
},
});
}
}

View File

@@ -1,12 +1,11 @@
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path";
import { HelmProvider } from "@cdktf/provider-helm/lib/provider"; import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
import { Release } from "@cdktf/provider-helm/lib/release"; import { Release } from "@cdktf/provider-helm/lib/release";
import { Construct } from "constructs"; import { Construct } from "constructs";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest"; import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
export { CloudflareCertificate } from "./certificate";
type CertManagerOptions = { type CertManagerOptions = {
providers: { providers: {
kubernetes: KubernetesProvider; kubernetes: KubernetesProvider;
@@ -34,12 +33,14 @@ export class CertManager extends Construct {
chart: "cert-manager", chart: "cert-manager",
createNamespace: true, createNamespace: true,
values: [ values: [
fs.readFileSync("helm/values/cert-manager.values.yaml", { fs.readFileSync(path.join(__dirname, "values.yaml"), {
encoding: "utf8", encoding: "utf8",
}), }),
], ],
}); });
// "apiVersion=v1,kind=Secret,namespace=default,name=sample"
// Self-signed ClusterIssuer for initial CA // Self-signed ClusterIssuer for initial CA
new Manifest(this, "ca-issuer", { new Manifest(this, "ca-issuer", {
provider: kubernetes, provider: kubernetes,
@@ -53,7 +54,9 @@ export class CertManager extends Construct {
selfSigned: {}, selfSigned: {},
}, },
}, },
}); }).importFrom(
`apiVersion=${certManagerApiVersion},kind=ClusterIssuer,name=ca-issuer`,
);
// Self-signed CA Certificate // Self-signed CA Certificate
new Manifest(this, "selfsigned-ca", { new Manifest(this, "selfsigned-ca", {
@@ -80,7 +83,9 @@ export class CertManager extends Construct {
}, },
}, },
}, },
}); }).importFrom(
`apiVersion=${certManagerApiVersion},kind=Certificate,name=selfsigned-ca,namespace=${options.namespace}`,
);
// CA-based ClusterIssuer // CA-based ClusterIssuer
new Manifest(this, "cluster-issuer", { new Manifest(this, "cluster-issuer", {
@@ -97,7 +102,9 @@ export class CertManager extends Construct {
}, },
}, },
}, },
}); }).importFrom(
`apiVersion=${certManagerApiVersion},kind=ClusterIssuer,name=cluster-issuer`,
);
// Cloudflare ACME ClusterIssuer // Cloudflare ACME ClusterIssuer
new Manifest(this, "cloudflare-issuer", { new Manifest(this, "cloudflare-issuer", {
@@ -130,6 +137,8 @@ export class CertManager extends Construct {
}, },
}, },
}, },
}); }).importFrom(
`apiVersion=${certManagerApiVersion},kind=ClusterIssuer,name=cloudflare-issuer`,
);
} }
} }

View File

@@ -1,6 +1,6 @@
crds: crds:
enabled: true enabled: true
prometheus: prometheus:
enabled: false enabled: true
webhook: webhook:
timeoutSeconds: 4 timeoutSeconds: 4

69
core-services/index.ts Normal file
View File

@@ -0,0 +1,69 @@
import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
import { NamespaceV1 } from "@cdktf/provider-kubernetes/lib/namespace-v1";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
import { TerraformOutput, TerraformStack } from "cdktf";
import { Construct } from "constructs";
import { Longhorn } from "./longhorn";
import { MetalLB } from "./metallb";
import { Traefik } from "./traefik";
import { CertManager } from "./cert-manager";
export class CoreServices extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
const kubernetes = new KubernetesProvider(this, "kubernetes", {
configPath: "~/.kube/config",
});
const helm = new HelmProvider(this, "helm", {
kubernetes: {
configPath: "~/.kube/config",
},
});
const namespace = "homelab";
new NamespaceV1(this, "namespace", {
provider: kubernetes,
metadata: {
name: namespace,
},
}).importFrom("homelab");
new TerraformOutput(this, "namespace-output", {
value: namespace,
});
new Longhorn(this, "longhorn", {
name: "longhorn",
providers: {
kubernetes,
helm,
},
});
new MetalLB(this, "metallb", {
provider: helm,
name: "metallb",
namespace: "metallb-system",
});
new Traefik(this, "traefik", {
provider: helm,
namespace,
name: "traefik",
});
new CertManager(this, "cert-manager", {
certManagerApiVersion: "cert-manager.io/v1",
name: "cert-manager",
namespace,
version: "1.18.2",
providers: {
kubernetes,
helm,
},
});
}
}

View File

@@ -1,9 +1,11 @@
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path";
import { HelmProvider } from "@cdktf/provider-helm/lib/provider"; import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
import { Release } from "@cdktf/provider-helm/lib/release"; import { Release } from "@cdktf/provider-helm/lib/release";
import { Construct } from "constructs"; import { Construct } from "constructs";
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest"; import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
import { IngressRoute } from "../../utils";
type LonghornOptions = { type LonghornOptions = {
providers: { providers: {
@@ -28,7 +30,7 @@ export class Longhorn extends Construct {
chart: "longhorn", chart: "longhorn",
createNamespace: true, createNamespace: true,
values: [ values: [
fs.readFileSync("helm/values/longhorn.values.yaml", { fs.readFileSync(path.join(__dirname, "values.yaml"), {
encoding: "utf8", encoding: "utf8",
}), }),
], ],
@@ -51,5 +53,16 @@ export class Longhorn extends Construct {
}, },
}, },
}); });
new IngressRoute(this, "ingress", {
provider: kubernetes,
name: "longhorn",
namespace,
serviceName: "longhorn-frontend",
servicePort: 80,
host: "longhorn.dogar.dev",
tlsSecretName: "longhorn-tls",
entryPoints: ["websecure"],
});
} }
} }

View File

@@ -16,12 +16,4 @@ metrics:
serviceMonitor: serviceMonitor:
enabled: true enabled: true
ingress: ingress:
enabled: true enabled: false
ingressClassName: traefik
host: longhorn.dogar.dev
tls: true
tlsSecretName: longhorn-tls
annotations:
cert-manager.io/cluster-issuer: cloudflare-issuer
cert-manager.io/acme-challenge-type: dns01
cert-manager.io/private-key-size: "4096"

View File

@@ -1,15 +0,0 @@
grafana:
enabled: true
ingress:
enabled: true
ingressClassName: traefik
annotations:
cert-manager.io/cluster-issuer: cloudflare-issuer
cert-manager.io/acme-challenge-type: dns01
cert-manager.io/private-key-size: "4096"
hosts:
- grafana.dogar.dev
tls:
- secretName: grafana-tls
hosts:
- grafana.dogar.dev