Skip to content

Instantly share code, notes, and snippets.

@doublecompile
Created September 29, 2022 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doublecompile/20619c4453b1614d8d8a688ddf68f1dd to your computer and use it in GitHub Desktop.
Save doublecompile/20619c4453b1614d8d8a688ddf68f1dd to your computer and use it in GitHub Desktop.
AWS CDK Stack for CrossAccountZoneDelegationRecord access
import { Construct } from "constructs";
import { Stack, StackProps, CfnOutput } from "aws-cdk-lib";
import {
IRole,
Role,
PolicyStatement,
AnyPrincipal,
ManagedPolicy,
Effect,
PrincipalWithConditions,
} from "aws-cdk-lib/aws-iam";
import { HostedZone, IHostedZone } from "aws-cdk-lib/aws-route53";
/**
* Constructor properties for the DnsStack.
*/
export interface DnsStackProps extends StackProps {
/**
* The AWS Organizations ID to permit access.
*/
readonly organizationId: string;
/**
* The actual domain to use e.g. hosted.example.com.
*/
readonly zoneName: string;
}
/**
* The Dns stack.
*/
export class DnsStack extends Stack {
/**
* The hosted zone.
*/
public readonly hostedZone: IHostedZone;
/**
* The role granting write access to the hosted zone.
*/
public readonly role: IRole;
constructor(scope: Construct, id: string, props: DnsStackProps) {
super(scope, id, { ...props });
const zoneName = props.zoneName;
const hostedZone = new HostedZone(this, "Zone", {
zoneName,
comment: `Contains DNS records for ${zoneName}`,
});
this.hostedZone = hostedZone;
const managedPolicy = new ManagedPolicy(this, "Policy", {
description: `Permits adding delegate records to the ${zoneName} hosted zone`,
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: ["route53:ChangeResourceRecordSets"],
resources: [hostedZone.hostedZoneArn],
}),
new PolicyStatement({
effect: Effect.ALLOW,
actions: ["route53:ListHostedZonesByName"],
resources: ["*"],
}),
],
});
const role = new Role(this, "Role", {
description:
"A role to be assumed by the CrossAccountZoneDelegationRecord CDK construct",
assumedBy: new PrincipalWithConditions(new AnyPrincipal(), {
StringEquals: {
"aws:PrincipalOrgID": props.organizationId,
},
}),
managedPolicies: [managedPolicy],
});
this.role = role;
new CfnOutput(this, "HostedZoneArn", {
value: this.hostedZone.hostedZoneArn,
});
new CfnOutput(this, "DelegationRoleArn", {
value: this.role.roleArn,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment