42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
|
|
// 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 },
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|