diff --git a/cloudflare/ddns.yaml b/cloudflare/ddns.yaml deleted file mode 100644 index f4b8835..0000000 --- a/cloudflare/ddns.yaml +++ /dev/null @@ -1,90 +0,0 @@ ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: cloudflare-domains-config - namespace: homelab -data: - DOMAINS: "auth.dogar.dev" - PROXIED: "true" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: cloudflare-domains-config-non-proxied - namespace: homelab -data: - DOMAINS: "dogar.dev,git.dogar.dev,nix.dogar.dev,pip.dogar.dev,npm.dogar.dev" - PROXIED: "false" ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: cloudflare-ddns - namespace: homelab -spec: - replicas: 1 - selector: - matchLabels: - app: cloudflare-ddns - template: - metadata: - labels: - app: cloudflare-ddns - spec: - nodeSelector: - nodepool: worker - containers: - - name: cloudflare-ddns - image: favonia/cloudflare-ddns:latest - env: - - name: CLOUDFLARE_API_TOKEN - valueFrom: - secretKeyRef: - name: cloudflare-token - key: token - - name: DOMAINS - valueFrom: - configMapKeyRef: - name: cloudflare-domains-config - key: DOMAINS - - name: UPDATE_TIMEOUT - value: "30s" - - name: IP6_PROVIDER - value: "none" ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: cloudflare-ddns-non-proxied - namespace: homelab -spec: - replicas: 1 - selector: - matchLabels: - app: cloudflare-ddns - template: - metadata: - labels: - app: cloudflare-ddns - spec: - nodeSelector: - nodepool: worker - containers: - - name: cloudflare-ddns-non-proxied - image: favonia/cloudflare-ddns:latest - env: - - name: CLOUDFLARE_API_TOKEN - valueFrom: - secretKeyRef: - name: cloudflare-token - key: token - - name: DOMAINS - valueFrom: - configMapKeyRef: - name: cloudflare-domains-config-non-proxied - key: DOMAINS - - name: UPDATE_TIMEOUT - value: "30s" - - name: IP6_PROVIDER - value: "none" diff --git a/utility-services/dynamic-dns/index.ts b/utility-services/dynamic-dns/index.ts new file mode 100644 index 0000000..69715a3 --- /dev/null +++ b/utility-services/dynamic-dns/index.ts @@ -0,0 +1,110 @@ +import { Construct } from "constructs"; +import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; + +import { OnePasswordSecret } from "../../utils"; +import { ConfigMapV1 } from "@cdktf/provider-kubernetes/lib/config-map-v1"; +import { DeploymentV1 } from "@cdktf/provider-kubernetes/lib/deployment-v1"; + +type DynamicDNSOptions = { + provider: KubernetesProvider; + name: string; + namespace: string; + records: string[]; +}; + +export class DynamicDNS extends Construct { + constructor(scope: Construct, id: string, options: DynamicDNSOptions) { + super(scope, id); + + const { provider, name, namespace, records } = options; + + new OnePasswordSecret(this, "cloudflare-token", { + provider, + name: "ddns-cloudflare-token", + namespace: options.namespace, + itemPath: "vaults/Lab/items/cloudflare", + }); + + new ConfigMapV1(this, "ddns-configmap", { + provider, + metadata: { + name, + namespace, + }, + data: { + DOMAINS: records.join(","), + PROXIED: "false", + }, + }); + + new DeploymentV1(this, "ddns-deployment", { + provider, + metadata: { + name, + namespace, + }, + spec: { + selector: { + matchLabels: { + app: name, + }, + }, + template: { + metadata: { + labels: { + app: name, + }, + }, + spec: { + nodeSelector: { + nodepool: "worker", + }, + container: [ + { + name: "ddns-updater", + image: "favonia/cloudflare-ddns:latest", + env: [ + { + name: "CLOUDFLARE_API_TOKEN", + valueFrom: { + secretKeyRef: { + name: "ddns-cloudflare-token", + key: "token", + }, + }, + }, + { + name: "DOMAINS", + valueFrom: { + configMapKeyRef: { + name, + key: "DOMAINS", + }, + }, + }, + { + name: "PROXIED", + valueFrom: { + configMapKeyRef: { + name, + key: "PROXIED", + }, + }, + }, + { + name: "UPDATE_TIMEOUT", + value: "30s", + }, + { + name: "IP6_PROVIDER", + value: "none", + }, + ], + }, + ], + }, + }, + }, + }); + } +} diff --git a/utility-services/index.ts b/utility-services/index.ts index 83dbf1e..3ace5fa 100644 --- a/utility-services/index.ts +++ b/utility-services/index.ts @@ -1,14 +1,14 @@ -import * as path from "path"; import { DataKubernetesNamespaceV1 } from "@cdktf/provider-kubernetes/lib/data-kubernetes-namespace-v1"; import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; import { HelmProvider } from "@cdktf/provider-helm/lib/provider"; -import { DataTerraformRemoteStateLocal, TerraformStack } from "cdktf"; +import { DataTerraformRemoteStateS3, TerraformStack } from "cdktf"; import { Construct } from "constructs"; import { ValkeyCluster } from "./valkey"; import { GiteaServer } from "./gitea"; import { AuthentikServer } from "./authentik"; import { PostgresCluster } from "./postgres"; +import { DynamicDNS } from "./dynamic-dns"; export class UtilityServices extends TerraformStack { constructor(scope: Construct, id: string) { @@ -24,16 +24,24 @@ export class UtilityServices extends TerraformStack { }, }); - const homelabState = new DataTerraformRemoteStateLocal( - this, - "homelab-state", - { - path: path.join( - __dirname, - "../cdktf.out/stacks/homelab/terraform.tfstate", - ), + const r2Endpoint = `${process.env.ACCOUNT_ID!}.r2.cloudflarestorage.com`; + + const homelabState = new DataTerraformRemoteStateS3(this, "homelab-state", { + usePathStyle: true, + skipRegionValidation: true, + skipCredentialsValidation: true, + skipRequestingAccountId: true, + skipS3Checksum: true, + encrypt: true, + bucket: "terraform-state", + key: "core-services/terraform.tfstate", + endpoints: { + s3: `https://${r2Endpoint}`, }, - ); + region: "auto", + accessKey: process.env.ACCESS_KEY, + secretKey: process.env.SECRET_KEY, + }); const namespaceName = homelabState.getString("namespace-output"); const namespaceResource = new DataKubernetesNamespaceV1( @@ -48,7 +56,19 @@ export class UtilityServices extends TerraformStack { ); const namespace = namespaceResource.metadata.name; - const r2Endpoint = `${process.env.ACCOUNT_ID!}.r2.cloudflarestorage.com`; + new DynamicDNS(this, "dynamic-dns", { + provider: kubernetes, + namespace, + name: "cloudflare-ddns", + records: [ + "dogar.dev", + "auth.dogar.dev", + "git.dogar.dev", + "nix.dogar.dev", + "pip.dogar.dev", + "npm.dogar.dev", + ], + }); const valkeyCluster = new ValkeyCluster(this, "valkey-cluster", { namespace,