feat: DynamicDNS | add to utility-services stack

This commit is contained in:
2025-11-22 19:30:34 +05:00
parent f46833571c
commit 772bcd441a
3 changed files with 142 additions and 102 deletions

View File

@@ -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"

View File

@@ -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",
},
],
},
],
},
},
},
});
}
}

View File

@@ -1,14 +1,14 @@
import * as path from "path";
import { DataKubernetesNamespaceV1 } from "@cdktf/provider-kubernetes/lib/data-kubernetes-namespace-v1"; import { DataKubernetesNamespaceV1 } from "@cdktf/provider-kubernetes/lib/data-kubernetes-namespace-v1";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider"; import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
import { HelmProvider } from "@cdktf/provider-helm/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 { Construct } from "constructs";
import { ValkeyCluster } from "./valkey"; import { ValkeyCluster } from "./valkey";
import { GiteaServer } from "./gitea"; import { GiteaServer } from "./gitea";
import { AuthentikServer } from "./authentik"; import { AuthentikServer } from "./authentik";
import { PostgresCluster } from "./postgres"; import { PostgresCluster } from "./postgres";
import { DynamicDNS } from "./dynamic-dns";
export class UtilityServices extends TerraformStack { export class UtilityServices extends TerraformStack {
constructor(scope: Construct, id: string) { constructor(scope: Construct, id: string) {
@@ -24,16 +24,24 @@ export class UtilityServices extends TerraformStack {
}, },
}); });
const homelabState = new DataTerraformRemoteStateLocal( const r2Endpoint = `${process.env.ACCOUNT_ID!}.r2.cloudflarestorage.com`;
this,
"homelab-state", const homelabState = new DataTerraformRemoteStateS3(this, "homelab-state", {
{ usePathStyle: true,
path: path.join( skipRegionValidation: true,
__dirname, skipCredentialsValidation: true,
"../cdktf.out/stacks/homelab/terraform.tfstate", 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 namespaceName = homelabState.getString("namespace-output");
const namespaceResource = new DataKubernetesNamespaceV1( const namespaceResource = new DataKubernetesNamespaceV1(
@@ -48,7 +56,19 @@ export class UtilityServices extends TerraformStack {
); );
const namespace = namespaceResource.metadata.name; 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", { const valkeyCluster = new ValkeyCluster(this, "valkey-cluster", {
namespace, namespace,