How to setup maintenance page in AWS without modifying Cloudfront? - amazon-web-services

We will be deploying changes in our production environment and would like to put up a maintenance page during the deployment. No redirection to error page but simply display the maintenance page when they hit our website. Our current production setup is, DNS->cloudfront->S3 object (mydomain.test.com). Our staging is, DNS->R53->Cloudfront->S3 (mydomain.staging.test.com->mydomain.staging.test53.com). I would like to test this first in our Staging env so that if it works, I will have the DNS entry of our prod env modified and pointed to a new R53 I will create.
What I've done so far is, create an S3 bucket that has the maintenance.html object, created a Cloudfront and R53 solely for the maintenance page. Added the S3 object as the default root object in the CF and mydomain.staging.maintenance.test53.com as alias. Also added the CF as the cname in the R53. So when I load the r53 mydomain.staging.maintenance.test53.com I see the maintenance page.
However, for this to work I have to update the CF of our live environment to remove mydomain.staging.test.com and mydomain.staging.test53.com and add mydomain.staging.maintenance.test53.com as alias then update the staging live R53 to point to the maintenace R53. This works but the CF changes takes time to propagate.
Would appreciate any suggestions!

Related

How to migrate from one cloudfront distribution to another

We're using cloudfront to front end a web app (myapp.com with s3, lambda, athena, ... etc)
Before a new release we're creating an entire new distribution (next.myapp.com) with new code and content, testing and then would like to make it the live version of myapp.com. But this doesn't seem possible.
Multiple Cloudfront distributions can't have the same CNAMEs so we can't change the DNS entry for myapp.com to point to the new service.
Changing the distribution means there's a delay as the new config populates around the world.
Is there away of doing this using amazon infrastructure? Or am I doing this completely wrong? Would like to be able to migrate the live service ASAP, but still have the existing version available for manual failback if the release breaks something
This is possible with only a very brief period of downtime, if you follow these steps.
Create the new distribution with the correct certificate but no Alternate Domain Name, and allow it to stabilize.
Change the DNS for the site to point to the new distribution. This does not have the negative impact that you would assume, because the site continues to work on the existing distribution. CloudFront does not differentiate between arrival endpoints -- it's only looking at the SNI and Host header, matching these against the Alternate Domain Name -- so the old distribution will continue to handle the traffic.
Edit the existing distribution to remove the Alternate Domain Name. You do not need to wait for it to return to "Deployed" status.
Edit the new distribution to add the Alternate Domain Name. You may have to attempt this more than once but it will eventually be accepted.
The trick is to use *.myapp.com as CNAME for the new distribution, switch your DNS records to point to the new distribution and when the switch is effective you clean everything up.
See Moving an Alternate Domain Name to a Different CloudFront Distribution.
It's not possible to do this for a second-level domain (myapp.com) without contacting AWS. The solution is to use www.myapp.com for the live version and have another distribution only for the HTTPS redirection from myapp.com to www.myapp.com (or a redirection with S3 but HTTP only then). The CNAME for this distribution would never need to be updated.

Access to soon to be new environment on Blue/Green deployments on AWS CodeDeploy

Recently I've been testing AWS CodeDeploy to validate that it will be useful, and so far so good. But after seeing its workflow I started to wonder: "How can someone validate that the new environment is good, in a human way?"
Explaining in more detail:
On my "Deployment Group > Deployment Settings" using the Traffic Rerouting policy of "I will choose whether to reroute traffic", when the new environment boots up, the deployment pauses waiting for me to verify that everything is fine in this new environment. Then, after validation, I can push the "reroute traffic" button and it will proceed as expected.
To validate that the new environment is good I, as someone who has access to the machines, can SSH into one of them and do some tests. Or I can grab the Public DNS of one new machine and access it through the browser and verify that it is OK.
But is there a simpler way of validating the application on these new machines? Like having a Load Balancer that always points to the soon to be new environment that I can send to QA people. Or will I have to, for each and every deploy, manually grab information about the new environment and then send to the QA people?
In order to validate the new environment, you can add scripts as validation hooks in the Appspec that would be run after installing the new revision in the new hosts. Also, the new environment will be registered behind any load balancer you specify in the deployment configuration.

Using comparative logic in AWS DNS/Route 53 records

We have a site setup in AWS. When we bring up a stack for a new release we make it available at a versioned URL. i.e.
V1 available at v1.mysite.com
V2 available at v2.mysite.com
etc
Is it possible to make a single DNS entry that will point to the latest deployed version of my site automatically? So, after I deploy V1, I would have two DNS entries:
v1.mysite.com which goes to the IP of it's stack
mysite.com which redirect to v1.mysite.com
Then when I deploy V2, mysite.com now redirects to v2.mysite.com without me manually having to edit the DNS entry.
In general, can I automatically make DNS entries or make some kind of wildcarded DNS entry that will always point to the highest numbered version of my site currently available in AWS? It should look at the digits after the V for all currently available DNS entries/stacks and make mysite.com point to the numerically highest one.
We are using CloudFormation to create our stacks and our DNS (Route 53) entries, so putting any logic in those scripts would work as well.
This isn't part of DNS itself, so it's unlikely to be supported by anything on Route53. Your best bet is a script that runs when your new instance starts or is promoted to be the production instance. It's pretty simple using boto:
Create a new boto.route53.record.Record
Create a new boto.route53.record.ResourceRecordSets
Add a change record with the action UPSERT and your record
Commit the ResourceRecordSets (with a simple retry in case it fails)
get_change() until Route53 replies INSYNC
Depending on your application you may also want to wait for all the authoritative DNS servers (dns.resolver.query('your-domain', 'NS')) at Amazon to know about your change.
We ended up must making this a manual step before deploying a new stack. If the new stack needed to be resovled at mysite.com, the deployer has to manually remove the existing mapping. Then the cloud formation scripts will create the new DNS mapping.
Not ideal but better than a ton of messy logic in cloud formation scripts I suppose.

AWS Elastic Beanstalk Backup & Recovery

I am new to AWS EB and I am trying to figure out how to backup and restore an entire EB environment. I created an AMI based on the EC2 instance generated by EB, and took a snapshot of RDS, also created by EB.
The problem I have is, how do I restore it, assuming that this is the correct approach of backup. Also, I am doing it manually, shouldn't there be an automated way of doing this within EB? By the way, when I created the AMI, it destroyed the source and the EB just created a new EC2 instance without all my changes.
How do I save & restore configuration changes to my application that impact both filesystem and database?
Unfortunately, Amazon AWS Elastic Beanstalk (EB) does not support restoring databases that contain live data, if those databases were created with EB. If you reload (AKA AWS "deploy") the EB saved configuration, you get a blank database!
I called them and they told me to create the RDS DB separately and update the application code to connect to the DB once you know it's name. If you restore the RDS DB it will have a new name too! So you have to update your code again to connect to it.
Also, if you code and environment is fine, but you want to restore your database, again it will have a new name and you will need to change your code.
How to change your code easily and automatically deploy it is a whole other question for which I don't have an answer yet.
So basically the RDS DB provisioning within Elastic Beanstalk has very limited uses, maybe coding and debugging and testing, but not live production use. :(
This is as of Jan 2015.
First go into your EB environment and save the current config. You should go to a running EC2 instance created by EB and make an Image. Then use that new AMI ID by going to the EB configuration and setting it. It will rebuild the environment tearing down all running instances and creating new ones.
For your RDS instance you should make a backup and restore with a new instance name as the docs say you will lose it if the environment is destroyed. You should probably just manually set the environment variables like RDS does and setup the proper security groups between RDS and EC2.
One option I think could work is just renaming the RDS instance name as the environment seems to break and then destroy the environment and create a new one with an attached RDS instance and then destroy that one and rename the old one to the new one's name which may work.
As always make proper backups before proceeding with any of these ideas.

How to Publish Docpad Website to AWS S3

I've seen the documentation on how to deploy to AWS S3 but am at a bit of a loss still (I also used this unfinished tutorial.
Do I need to setup an EC2 account? Where do I put the package.json file? Do only the out files (and package.json) need to be uploaded to Amazon? Does all of this go into the bucket MyWebsite.com?
Note - I'm new to web programming.
As you pointed out my tutorial is unfinished, but I hope it helped a little. Hopefully I can clarify a few things:
You're spot on with --env static. You need to add that to everything you do with DocPad so that what you see locally is the same as what you plan to deploy. I.e. you need to use DocPad run --env static too.
My 'tutorial' was on how to point AWS CloudFront at a root domain. This can be a frustrating experience particularly if you're just starting out with static sites. If you're using CloudFront, consider switching to just use S3. You can do this easily by changing the configuration in Route 53.
My tutorial misses an important step; You need to create another bucket with the name of your domain with www. in front of it if you would like to use www as well as your root domain. You then configure that bucket as a website and redirect it to the bucket with your website. This is all configuration.
You only need to upload everything in the out folder. package.json is not needed once the site has been generated.
Check out the source to my site and copy what you need. My whole deployment to S3 is automated through Grunt.
Have fun!
I finally found the answer to my question.
Basically what I needed to do was install the Docpad plugin cleanurls. I then needed to use the command line:
docpad generate --env static
And then upload to the AWS S3 bucket.
Here's the stack overflow answer where I gathered this information from.