All files / lib dns.ts

95% Statements 19/20
87.5% Branches 7/8
100% Functions 3/3
95% Lines 19/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 831x 1x 1x                                                     1x         1x 1x 1x   1x 1x               1x 1x 1x 3x 3x 2x       1x       1x                         1x       1x          
import * as cdk from "@aws-cdk/core";
import * as iam from "@aws-cdk/aws-iam";
import * as route53 from "@aws-cdk/aws-route53";
import {IAccountProps} from "./account";
 
/**
 * Properties for RootDns
 */
export interface RootDnsProps {
  /**
   * An array storing details about each stage accounts
   */
  readonly stagesDetails: Array<IAccountProps>;
 
  /**
   * The top level domain name
   */
  readonly rootHostedZoneDNSName: string;
 
  /**
   * A boolean indicating if Domain name has already been registered to a third party or if you want this contruct to create it (the latter is not yet supported)
   */
  readonly thirdPartyProviderDNSUsed?: boolean;
}
 
 
/**
 * A class creating the main hosted zone and a role assumable by stages account to be able to set sub domain delegation
 */
export class RootDns extends cdk.Construct {
  rootHostedZone: route53.IHostedZone;
  dnsAutoUpdateRole: iam.Role;
 
  constructor(scope: cdk.Construct, id: string, props: RootDnsProps) {
    super(scope, id);
    this.dnsAutoUpdateRole = this.createDNSAutoUpdateRole(props);
    this.rootHostedZone = this.createRootHostedZone(props);
 
    Eif ( props.thirdPartyProviderDNSUsed && this.rootHostedZone.hostedZoneNameServers ) {
      new cdk.CfnOutput(this, `NS records`, {value:  cdk.Fn.join(',', this.rootHostedZone.hostedZoneNameServers)});
    } else {
        throw new Error('Creation of DNS domain is not yet supported');
        // TODO: implement call to https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Route53Domains.html#registerDomain-property  
    }
  }
 
  createDNSAutoUpdateRole(props: RootDnsProps) {
    const authorizedPrincipals = [];
    const stagesDetails = props.stagesDetails;
    for (const stageDetailIndex in stagesDetails) {
      const details = stagesDetails[stageDetailIndex];
      if(details.parentOrganizationalUnitName && details.parentOrganizationalUnitName === 'SDLC') {
        authorizedPrincipals.push(new iam.AccountPrincipal(details.id));
      }
    }
 
    const dnsAutoUpdateRole = new iam.Role(this, "dns-auto-update", {
      assumedBy: new iam.CompositePrincipal(...authorizedPrincipals),
    });
 
    dnsAutoUpdateRole.addToPolicy(
      new iam.PolicyStatement({
        resources: ["*"],
        actions: [
          "route53:GetHostedZone",
          "route53:ListHostedZones",
          "route53:ChangeResourceRecordSets",
          "route53:ListHostedZonesByName",
          "route53:TestDNSAnswer",
        ],
      })
    );
 
    return dnsAutoUpdateRole;
  }
 
  createRootHostedZone(props: RootDnsProps) {
    return new route53.HostedZone(this, "RootHostedZone", {
      zoneName: props.rootHostedZoneDNSName,
    });
  }
}