// components/dns.ts // // Public A records for the foundation's hostnames → the VM (CONTRACT_001 hosts). // DNS-only (proxied:false): Git-over-SSH and Vault/RustFS need raw TCP, and ACME // DNS-01 doesn't want the Cloudflare proxy in front. Records are scoped to the // foundation's own names — they do not touch the zone's other (Pulumi-managed) // records. The Cloudflare token is read from the passphrase-encrypted config // secret (CONTRACT_001 §1.3), so no env var is needed at deploy time. import * as pulumi from "@pulumi/pulumi"; import * as cloudflare from "@pulumi/cloudflare"; import { DeployCtx } from "../lib/context"; export function deployDns(ctx: DeployCtx): cloudflare.Record[] { const { cfg } = ctx; const apiToken = new pulumi.Config("foundation").requireSecret("cloudflareApiToken"); const provider = new cloudflare.Provider("foundation-cloudflare", { apiToken }); const ip = cfg.vm.host; // for the test/initial deploy, vm.host is the VM's public IPv4 const hosts: { key: string; fqdn: string }[] = [ { key: "forge", fqdn: cfg.hosts.forge }, { key: "vault", fqdn: cfg.hosts.vault }, { key: "s3", fqdn: cfg.hosts.s3 }, { key: "git", fqdn: cfg.hosts.git }, ]; return hosts.map( (h) => new cloudflare.Record( `dns-${h.key}`, { zoneId: cfg.cloudflare.zoneId, name: h.fqdn, type: "A", content: ip, proxied: false, ttl: 300, }, { provider }, ), ); }