This post is part of a series where I add SSL to this blog. The www
template I created in two previous posts had two outputs defined for
the CloudFront distributions created, so that I could import these
values in my dns
template and avoid hard-coding their domain names.
This post shows the changes required to do just that.
Table of Contents
Updated Outputs
Let's dive right in. According to the Outputs documentation you need
to add the optional Export
object to the output, giving the fully
qualified Name
to be used for the variable. It is heavily implied that
you should try to work the StackName into this names somehow. That's
what we're doing on lines 9 and 16. I've also added a new
variable, StackName
, which I'll get back to in a moment.
1: Outputs: 2: RedirDomain: 3: Description: >- 4: The CloudFront domain name for our Apex domain that we use to 5: redirect to our SiteDomain. We will use this to add a CNAME from 6: our DNS template. 7: Value: !GetAtt ApexCloudFront.DomainName 8: Export: 9: Name: !Sub "${AWS::StackName}-RedirDomain" 10: SiteDomain: 11: Description: >- 12: The CloudFront domain name for our site. We will use this to add 13: a CNAME from our DNS template. 14: Value: !GetAtt SiteCloudFront.DomainName 15: Export: 16: Name: !Sub "${AWS::StackName}-SiteDomain" 17: StackName: 18: Description: >- 19: The stack name to use for templates that depend on this one. 20: Value: !Ref 'AWS::StackName'
Now, the required changes to the DNS template from a previous post. We
start by removing the ApexRecords
and WwwRecord
, as we'll get these
from the WWW template. We'll add a new DependentStackName
parameter,
like so:
Parameters: [...] DependentStackName: Type: String Description: >- Name of stack we depend on and will grab exported values from. Computed by Sceptre.
Config file update
As you can infer from the comment in the previous section, Sceptre
provides a bit of magic to obtain the stack name from the WWW template
as an input to the DNS one. To make use of that I added the below
!stack_output
Sceptre fragment to config/superloopy/dns.yaml
. This
file is so short that I'm just showing it in its entirety here:
template_path: templates/dns.yaml parameters: DomainName: superloopy.io DependentStackName: !stack_output www::StackName
RecordSet updates
Let's start with the WwwRecordSet
since that's the simplest change.
The only thing we need to change here is the ResourceRecord
list.
Instead of !Ref WwwRecord
we'll replace it with our imported value
from our dependent stack. (While researching how to do this I found
examples of using the !Sub
function which resulted in a much nicer way
to produce the fqdn from the apex domain; see 4.) The
WwwRecordSet
now looks like this:
1: WwwRecordSet: 2: Type: 'AWS::Route53::RecordSet' 3: Properties: 4: Name: !Sub "www.${DomainName}" 5: HostedZoneId: !Ref Zone 6: Type: CNAME 7: TTL: !Ref TTL 8: ResourceRecords: 9: - Fn::ImportValue: !Sub "${DependentStackName}-SiteDomain"
The ApexRecordSet
requires a different change. You can't CNAME the
Apex domain, but AWS Route 53 supports an AliasTarget
extension that
we can use instead. This is handy since we don't want to hard-code all
of CloudFront's IP addresses like we did previously with GitHub. The
new resource is in the next snippet. Note that I found the "magic"
HostedZoneId
on line 10 in the AliasTarget documentation1.
1: ApexRecordSet: 2: Type: 'AWS::Route53::RecordSet' 3: Properties: 4: Name: !Ref DomainName 5: HostedZoneId: !Ref Zone 6: Type: A 7: AliasTarget: 8: DNSName: 9: Fn::ImportValue: !Sub "${DependentStackName}-RedirDomain" 10: HostedZoneId: Z2FDTNDATAQYW2
Conclusion
This change concludes the work to add SSL to my blog. The only bit I haven't shown is how to tell Gandi to use the name servers I've configured on AWS Route 53 rather than the default ones, but I feel that is outside the scope of this blog series. It's now done, however, and if you're reading this you're getting2 the full experience of my HTTPS-enabled blog :-)
I
didn't see much reason to make it a template property as it is used
everywhere you create an AliasTarget
for a CloudFront domain.
Or, as it happens, maybe not yet. Because it turns out lots of home routers (including my own) ignore TTLs and cache DNS servers for a long time. So for a week or so I'll leave the generated files in GitHub, and also post new content to the AWS S3 bucket.