diff --git a/cert-manager/certificate.ts b/cert-manager/certificate.ts deleted file mode 100644 index ea2e34b..0000000 --- a/cert-manager/certificate.ts +++ /dev/null @@ -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, - ) { - super(scope, id, { - ...opts, - issuerRef: { - name: "cloudflare-issuer", - kind: "ClusterIssuer", - }, - }); - } -} diff --git a/cert-manager/index.ts b/core-services/cert-manager/index.ts similarity index 84% rename from cert-manager/index.ts rename to core-services/cert-manager/index.ts index 975a224..b8412d6 100644 --- a/cert-manager/index.ts +++ b/core-services/cert-manager/index.ts @@ -1,12 +1,11 @@ import * as fs from "fs"; +import * as path from "path"; import { HelmProvider } from "@cdktf/provider-helm/lib/provider"; import { Release } from "@cdktf/provider-helm/lib/release"; import { Construct } from "constructs"; import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest"; -export { CloudflareCertificate } from "./certificate"; - type CertManagerOptions = { providers: { kubernetes: KubernetesProvider; @@ -34,12 +33,14 @@ export class CertManager extends Construct { chart: "cert-manager", createNamespace: true, values: [ - fs.readFileSync("helm/values/cert-manager.values.yaml", { + fs.readFileSync(path.join(__dirname, "values.yaml"), { encoding: "utf8", }), ], }); + // "apiVersion=v1,kind=Secret,namespace=default,name=sample" + // Self-signed ClusterIssuer for initial CA new Manifest(this, "ca-issuer", { provider: kubernetes, @@ -53,7 +54,9 @@ export class CertManager extends Construct { selfSigned: {}, }, }, - }); + }).importFrom( + `apiVersion=${certManagerApiVersion},kind=ClusterIssuer,name=ca-issuer`, + ); // Self-signed CA Certificate 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 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 new Manifest(this, "cloudflare-issuer", { @@ -130,6 +137,8 @@ export class CertManager extends Construct { }, }, }, - }); + }).importFrom( + `apiVersion=${certManagerApiVersion},kind=ClusterIssuer,name=cloudflare-issuer`, + ); } } diff --git a/helm/values/cert-manager.values.yaml b/core-services/cert-manager/values.yaml similarity index 78% rename from helm/values/cert-manager.values.yaml rename to core-services/cert-manager/values.yaml index 71d84c1..bedeca1 100644 --- a/helm/values/cert-manager.values.yaml +++ b/core-services/cert-manager/values.yaml @@ -1,6 +1,6 @@ crds: enabled: true prometheus: - enabled: false + enabled: true webhook: timeoutSeconds: 4 diff --git a/core-services/index.ts b/core-services/index.ts new file mode 100644 index 0000000..1b4ef68 --- /dev/null +++ b/core-services/index.ts @@ -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, + }, + }); + } +} diff --git a/longhorn/index.ts b/core-services/longhorn/index.ts similarity index 76% rename from longhorn/index.ts rename to core-services/longhorn/index.ts index 02d794a..80271ae 100644 --- a/longhorn/index.ts +++ b/core-services/longhorn/index.ts @@ -1,9 +1,11 @@ import * as fs from "fs"; +import * as path from "path"; import { HelmProvider } from "@cdktf/provider-helm/lib/provider"; import { Release } from "@cdktf/provider-helm/lib/release"; import { Construct } from "constructs"; import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest"; import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; +import { IngressRoute } from "../../utils"; type LonghornOptions = { providers: { @@ -28,7 +30,7 @@ export class Longhorn extends Construct { chart: "longhorn", createNamespace: true, values: [ - fs.readFileSync("helm/values/longhorn.values.yaml", { + fs.readFileSync(path.join(__dirname, "values.yaml"), { 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"], + }); } } diff --git a/helm/values/longhorn.values.yaml b/core-services/longhorn/values.yaml similarity index 64% rename from helm/values/longhorn.values.yaml rename to core-services/longhorn/values.yaml index 32cd70a..c571d96 100644 --- a/helm/values/longhorn.values.yaml +++ b/core-services/longhorn/values.yaml @@ -16,12 +16,4 @@ metrics: serviceMonitor: enabled: true ingress: - enabled: true - 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" + enabled: false diff --git a/metallb/index.ts b/core-services/metallb/index.ts similarity index 100% rename from metallb/index.ts rename to core-services/metallb/index.ts diff --git a/traefik/index.ts b/core-services/traefik/index.ts similarity index 100% rename from traefik/index.ts rename to core-services/traefik/index.ts diff --git a/traefik/values.yaml b/core-services/traefik/values.yaml similarity index 100% rename from traefik/values.yaml rename to core-services/traefik/values.yaml diff --git a/helm/values/prometheus.values.yaml b/helm/values/prometheus.values.yaml deleted file mode 100644 index 87c6240..0000000 --- a/helm/values/prometheus.values.yaml +++ /dev/null @@ -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