2 Answers
- Newest
- Most votes
- Most comments
2
Here is the working solution which actually made things quite simple:
- We are using AWS WAF with one Web ACL.
- Web ACL has one rule set to "Block" action and it has Custom response that includes our maintenance HTML page and 503 HTTP status code.
- If we want to put our site into maintenance mode we just associate the Web ACL with the CloudFront distribution (by AWS CLI update-distribution command), which we are using for our site.
- After the maintenance is finished, we remove the association (same AWS CLI update-distribution command).
Extra bonus is that we can put our ip addresses into the IP sets in AWS WAF and make it an exception, so we can access the site during a maintenance.
2
It would be much better to do this with a single distribution - this is a fairly common requirement from customers and you can implement it using custom error pages in CloudFront, along with AWS WAF.
To implement this:
- Create the maintenance page in an S3 bucket as you originally intended
- Create a new Origin in your CloudFront distribution that points to the S3 Bucket. Use OAI/OAC as required.
- Create a new Behavior in your CloudFront distribution with the S3 Bucket as the origin. Use a path that's not currently part of your application, etc /errors
- Configure Custom Errors for your distribution so that your maintenance page is served in the case of a 403 error. Add other error codes if you wish.
- Configure an AWS WAF WebACL and attach it to your CloudFront distibution. If you already have a WebACL attached, you can simply modify that one.
- Create a new custom rule in AWS WAF and place it at the top of the WebACL. The rule should match all traffic - but you may want to add an exception for your own IP address(es) so that you won't receive the maintenance page. Make sure the rule action is set to COUNT
- When you want to invoke the maintenance page, simply change the rule action to BLOCK - this will cause a 403 error to be returned to all of your viewers. The error will be handled by CloudFront, which will display your maintenance page. When you want to return the application back to service, simply switch the rule action back to COUNT
- If you wish, you could use a Lambda function to toggle the rule action. You can then trigger the Lambda function in a variety of ways to suit your use case.
Relevant content
- asked 2 years ago
- asked 2 years ago
- AWS OFFICIALUpdated a year ago
- AWS OFFICIALUpdated 7 months ago
- AWS OFFICIALUpdated a year ago
- AWS OFFICIALUpdated 2 months ago
- AWS OFFICIALUpdated 17 days ago
Perfect way of doing this Paul L.. Theres no worries with DNS Cache here either..
Paul L, your answer adds a component (WAF) which costs money. The OP's desired solution on the other hand, having a dormant Cloudfront maintenance distribution, and then switching DNS to that from the production distribution, would, if it were possible, carry no additional costs. Do you have a suggestion which does not cost money just to add this maintenance functionality?
Also, from AWS docs: "CloudFront can't distinguish between an HTTP status code 403 that is returned by your origin and one that is returned by AWS WAF". Maintenance pages are usually served with a 503. This solution does not nicely allow separate management of planned maintenance vs a genuine application-level "forbidden".
If you prefer to use 503 status codes for your maintenance page, you can do this with a custom response action in WAF: https://docs.aws.amazon.com/waf/latest/developerguide/customizing-the-response-for-blocked-requests.html
I recommended AWS WAF because it aligns to the Well Architected Framework (Apply security at all layers) and also is a best practice for DDOS mitigation. The intention is that it should be used for security use-cases, alongside this one. However, should you decide not to use AWS WAF, you could implement maintenance page functionality on a single CloudFront distribution by using a CloudFront Function to rewrite the URI of all incoming requests to that of your maintenance page. You would then enable/disable the maintenance page by attaching or removing the CloudFront Function.