Zappa
Zappa copied to clipboard
Got `example.com` certified and working. Now how to make `www.example.com` work as well?
Problem
As of title, I have no problem with my website running on my naked domain example.com
.
But now need to get www.example.com
working: i.e. redirecting to the naked domain.
Resolution Attempts
At this stage I'm using Route 53 and trying to add www
as a CNAME, my alias list is empty.
I also tried adding www.example.com
-> example.com
as a non-alias CNAME, but it does not work.
Howdy. There's not a way to do this natively with Zappa. There's a couple of different things you could do:
1.) Use a standard CNAME (not an ALIAS record) to point to example.com for the www.example.com entry.
2.) Create a bucket in S3 that's named www.example.com and use the static website hosting section of the properties to redirect all traffic to example.com. Then in Route 53, create an ALIAS record for www.example.com pointing to the S3 bucket.
Hope this helps.
how would that work? Shouldn't I need a certificate also for www.example.com?
Here's where it can get tricky. Let me outline the different scenarios.
1.) You do option 1 (CNAME to example.com). This will just point to your API Gateway endpoint and try to render the page as www.example.com which is not a valid endpoint yet. To remedy this, you can add an additional profile to your zappa_settings.json, deploy, and certify it separately. This becomes a pain because now you're managing two deployments for the same thing. If you application is not big, you automate your deployments, and/or you have an application level redirect to the preferred URL, this is not a big deal.
2.) You do option 2 (S3 bucket redirect). This will force all traffic going to www.example.com to go to example.com instead where you have a valid endpoint. Here are the cases where it works as you would expect and doesn't work as expected:
Scenario 1 - http://www.example.com -> https://example.com: OK! Scenario 2 - https://www.example.com -> https://example.com: FAILS!
S3 doesn't do direct HTTPS forwarding which is a common complaint, but there's architectural reasons for that. The only way to get seamless coverage for both scenarios is to do Option 1 with an application redirect to the URL you want to be standard or set up your own reverse proxy and own SSL certificates to do the redirection correctly.
If someone else has some thoughts, I'd appreciate them since this is an issue I deal with regularly (we opt for option 2 since manually typing https://example.com is so exceedingly rare that we can live with the consequences).
This is something I'd certainly like to address as well!
I am of the opinion that a domain should exist at either the apex or the www.
, preferring the Apex, and that one should resolve to the other. If there are both, then they should be separate Lambda functions.
HTTPS S3 forwarding not working sucks! A hack there could be to use an HTML page to perform the redirect but I don't know how spiderbots will like that.
Can we have Zappa adding two entries (and two certificates) into the "custom domain name" feature of API gateway? This way the redirect would be optional, and managed at the application level.
Yeah, I think that should be doable. It seems like you can point to the same function twice now.
@Miserlou amazing 👍 Where about in the roadmap would you put this?
Whenever you submit the PR :)
@Miserlou, I'd love to. But I'm not great at python or have time to become better, so I attempted creating a separate Zappa project for the www (containing a simple redirect to the non-www).
Epic fail:
Calling certify for environment dev..
Certifying domain www.readonlyrest.com..
Setting DNS challenge..
Waiting for DNS to propagate..
Deleting DNS challenge..
An error occurred (InvalidChangeBatch) when calling the ChangeResourceRecordSets operation: RRSet of type CNAME with DNS name www.readonlyrest.com. is not permitted as it conflicts with other records with the same DNS name in zone readonlyrest.com.
Failed to generate or install certificate! :(
The issue is that - of course - I have already the zone "readonlyrest.com".
So I think this is a broader issue: it's apparently impossible to have two websites under the same domain and the same AWS account, say: this.domain.com and that.domain.com.
How to handle this? New issue?
I think it should be fairly easy to support multiple domains. I do this in production for my sites. I just have multiple domains setup to point to the same API Gateway at the same path/stage. This allows me to run www.example.com and example.com at the same time. Each domain uses their own certificate_arn (though i suppose one could use a single wildcard cert as well).
I would imagine the settings file could reflect this, something like this:
domains:
- name: example.com
certificate_arn: us-east-1-arn
- name: www.example.com
certificate: ...
certificate_key: ...
certificate_chain: ...
# Example for lets encrypt
- name: example.com
lets_encrypt_key: womp
Would be happy to take a stab at it.
Yep, that's the solution I'd imagine as well. Want to submit a PR, BMX? :D :D :D #
Alas, this should be easy. However AWS's API Gateway API limits itself to 2 Create Domain API requests per min. :(
It can still be done, if a user tries to add too many domains, the cli will create what it can and then fail. The user can than run certify a second time (after a few minutes) to cert the next domain.
Maybe another option would be to instead ask the user to use the domain name they want to certify in the command line, like: zappa certify dev example.com
. This would allow the user to choose which domain in the list to certify, and the user will just have run the command multiple times (once for each domain) with a few minutes in-between, so that the API limit isn't an issue.
Thoughts?
It might look something like this:
> zappa certify dev
Due to AWS APIGateway limitations, please run certify for each domain.
> zappa certify dev example.com
> sleep 60
> zappa certify dev www.example.com
Making some decent progress on this. I have manually tested my change with the cert_arn and Lets Encrpyt.
Todo:
- Manual test manual cert files
- Cleanup
- Update tests
I also discovered that we are not updating Route53 DNS routes in the Let's Encrypt stuff. I fixed it in my branch.
My branch should fix #762 ,#934, #1141, which are all duplicates.
Is there a way to get zappa to set up a LE certificate for a static files domain connected to an S3 bucket too?
@jgroszko I don't believe, so, LE functionality right now is tied to the API Gateway's custom domain. The functionality just uses LE and generate a certificate body and key, and then uploads it to Lambda, true it could be extended to support s3 resources, but I think that might go out of the scope of lambda. AWS Resource management might be better served by something like Terraform.
Hi, I have a WWW redirect working using a combination of CloudFront and S3. This successfully does a www.domain.com -> domain.com redirect as well as HTTP -> HTTPS. So http://www.domain.com becomes https://domain.com.
Route 53 (WWW entry) points to a dedicated CloudFront distribution with an S3 WWW redirect bucket (of the type mentioned above), and the CloudFront distribution settings have a "Redirect HTTP to HTTPS" viewer protocol policy.
I'll try and write up a blog post with every detail in the future.
Hi there, you can simply navigate to Amazon API Gateway > Custom Domain Names and click Create Custom Domain Name.
Select HTTP and enter your domain name, www.[domain name]...
Select TLS 1.0 and Edge optimized. Then select the certificate for your exisiting domain and click save.
Click update base path mappings, you will need to enter in the path which is most likely /
, and the destination. If you get an error about your domain name including www
does not exist on the certificate, navigate to Amazon Certificate Manager and create a new certificate for the www domain.
Once your certificate has been issued, go back and repeat the steps. Select this newly created certificate. Your site should be live at https://www.domain....
Hope this helps!
Hi, I have a WWW redirect working using a combination of CloudFront and S3. This successfully does a www.domain.com -> domain.com redirect as well as HTTP -> HTTPS. So http://www.domain.com becomes https://domain.com.
Route 53 (WWW entry) points to a dedicated CloudFront distribution with an S3 WWW redirect bucket (of the type mentioned above), and the CloudFront distribution settings have a "Redirect HTTP to HTTPS" viewer protocol policy.
I'll try and write up a blog post with every detail in the future.
Hi sheepzez. Any chance that you already published a blog post on this topic?
not sure if anyone is still looking for solution for this problem, but this is how I solved it:
- request for a domain cert and additional domain name *.domainname.ext
- Zappa certify for domainname.ext
- manually add custom domain on api gateway for the *.domainname.ext and (rest and edge optimized, select new *.domainname.ext cert) map it to the same api gateway and stage
- on route 53 create alias A record and point to cloudfront url from the new api custom domain
that should do it
not sure if anyone is still looking for solution for this problem, but this is how I solved it:
- request for a domain cert and additional domain name *.domainname.ext
- Zappa certify for domainname.ext
- manually add custom domain on api gateway for the *.domainname.ext and (rest and edge optimized, select new *.domainname.ext cert) map it to the same api gateway and stage
- on route 53 create alias A record and point to cloudfront url from the new api custom domain
that should do it
Thank you @nabazm. For anyone who might be interested, this also works fine the other way round (using the www. in Zappa settings and following the above steps for domainname.ext). In my case if someone visits domainname.ext I just redirect them to www.domainname.ext in the code of my app.