-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdomain_stack.py
94 lines (86 loc) · 3.89 KB
/
domain_stack.py
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
83
84
85
86
87
88
89
90
91
92
93
94
"""
This configures the Domain Stack for the ContainerManager.
"""
from aws_cdk import (
Stack,
Duration,
RemovalPolicy,
aws_route53 as route53,
aws_iam as iam,
aws_logs as logs,
)
from constructs import Construct
from ContainerManager.base_stack import BaseStack
class DomainStack(Stack):
"""
This stack creates a subdomain for the container, and ties it to the root domain.
"""
def __init__(
self,
scope: Construct,
construct_id: str,
container_id: str,
base_stack: BaseStack,
**kwargs
) -> None:
super().__init__(scope, construct_id, **kwargs)
## The instance isn't up, use the "unknown" ip address:
# https://www.lifewire.com/four-zero-ip-address-818384
self.unavailable_ip = "0.0.0.0"
## Never set TTL to 0, it's not defined in the standard
# (Since the container is constantly changing, update DNS asap)
self.dns_ttl = 1
self.record_type = route53.RecordType.A
self.sub_domain_name = f"{container_id}.{base_stack.root_hosted_zone.zone_name}".lower()
# Spaces on the ends to not match sub-domains like "_tcp.*" that shows up in logs.
# The record_type is because BOTH A and AAAA appear, even if my ISP only supports one.
self.dns_log_query_filter = f" {self.sub_domain_name} {self.record_type.value} "
## Log group for the Route53 DNS logs:
self.route53_query_log_group = logs.LogGroup(
self,
"QueryLogGroup",
log_group_name=f"/aws/route53/{construct_id}-query-logs",
# Only need logs to trigger the lambda, don't need long-term:
retention=logs.RetentionDays.ONE_DAY,
removal_policy=RemovalPolicy.DESTROY,
)
## You can't grant direct access after creating the sub_hosted_zone, since it needs to
# write to the log group on creation. AND you can't do a wildcard arn, since the
# account number isn't in the arn.
self.route53_query_log_group.grant_write(iam.ServicePrincipal("route53.amazonaws.com"))
## The subdomain for the Hosted Zone:
# https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.PublicHostedZone.html
self.sub_hosted_zone = route53.PublicHostedZone(
self,
"SubHostedZone",
zone_name=self.sub_domain_name,
query_logs_log_group_arn=self.route53_query_log_group.log_group_arn,
comment=f"Hosted zone for {construct_id}: {self.sub_domain_name}",
)
self.sub_hosted_zone.apply_removal_policy(RemovalPolicy.DESTROY)
# self.route53_query_log_group.grant_write(iam.ArnPrincipal(self.sub_hosted_zone.hosted_zone_arn))
## Tie the two hosted zones together:
# https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.NsRecord.html
self.ns_record = route53.NsRecord(
self,
"NsRecord",
zone=base_stack.root_hosted_zone,
values=self.sub_hosted_zone.hosted_zone_name_servers,
record_name=self.sub_domain_name,
)
self.ns_record.apply_removal_policy(RemovalPolicy.DESTROY)
## Add a record set that uses the base hosted zone
# https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.RecordSet.html
self.dns_record = route53.RecordSet(
self,
"DnsRecord",
zone=self.sub_hosted_zone,
record_name=self.sub_domain_name,
record_type=self.record_type,
target=route53.RecordTarget.from_values(self.unavailable_ip),
ttl=Duration.seconds(self.dns_ttl),
)
self.dns_record.apply_removal_policy(RemovalPolicy.DESTROY)
# Make sure the record is removed BEFORE you try to remove the zone
# idk why this isn't the default....
self.dns_record.node.add_dependency(self.sub_hosted_zone)