shoc-frontend-new/infra/cdk/lib/tf-poc-shared-stack.ts

75 lines
2.6 KiB
TypeScript

import { CfnOutput, Fn, Stack, StackProps } from "aws-cdk-lib";
import * as acm from "aws-cdk-lib/aws-certificatemanager";
import * as route53 from "aws-cdk-lib/aws-route53";
import { Construct } from "constructs";
const TF_POC_DOMAIN = "frontend-tf-poc.seahaven.com";
export interface TfPocCertificateStackProps extends StackProps {
readonly hostedZone: route53.IHostedZone;
}
/**
* Temporary, isolated DNS zone for the production-shaped Terraform POC.
* Parent-zone delegation is deliberately excluded from this stack.
*/
export class TfPocZoneStack extends Stack {
public readonly hostedZone: route53.IHostedZone;
public readonly hostedZoneId: string;
public readonly hostedZoneName = TF_POC_DOMAIN;
public constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
this.hostedZone = new route53.PublicHostedZone(this, "HostedZone", {
zoneName: TF_POC_DOMAIN,
comment: "Temporary isolated hosted zone for frontend Terraform adoption rehearsal",
});
this.hostedZoneId = this.hostedZone.hostedZoneId;
const nameServers = this.hostedZone.hostedZoneNameServers;
if (!nameServers) {
throw new Error("Public hosted zone must expose delegation name servers.");
}
new CfnOutput(this, "HostedZoneId", {
value: this.hostedZone.hostedZoneId,
description: "Terraform aws_route53_zone import ID",
});
new CfnOutput(this, "HostedZoneName", { value: TF_POC_DOMAIN });
new CfnOutput(this, "DelegationNameServers", {
value: Fn.join(",", nameServers),
description:
"Evidence only. Add these NS values to the seahaven.com parent zone in a separately approved change.",
});
new CfnOutput(this, "DelegationRecordName", {
value: TF_POC_DOMAIN,
});
new CfnOutput(this, "DelegationRequiredAction", {
value:
"SEPARATE APPROVAL REQUIRED: create an NS record for frontend-tf-poc.seahaven.com in the parent seahaven.com zone",
});
}
}
/**
* Certificate is isolated so re-running the zone phase cannot remove it.
*/
export class TfPocCertificateStack extends Stack {
public readonly certificateArn: string;
public constructor(scope: Construct, id: string, props: TfPocCertificateStackProps) {
super(scope, id, props);
const certificate = new acm.Certificate(this, "Certificate", {
domainName: TF_POC_DOMAIN,
validation: acm.CertificateValidation.fromDns(props.hostedZone),
});
this.certificateArn = certificate.certificateArn;
new CfnOutput(this, "CertificateArn", {
value: certificate.certificateArn,
description: "Inventory-only certificate ARN for the frontend tf-poc root",
});
}
}