{"id":142,"date":"2015-04-17T13:57:45","date_gmt":"2015-04-17T03:57:45","guid":{"rendered":"https:\/\/icicimov.com\/blog\/?p=142"},"modified":"2017-01-02T14:54:48","modified_gmt":"2017-01-02T03:54:48","slug":"setting-up-encompass-maintenance-page-with-elb-s3-route53-and-cloudfront","status":"publish","type":"post","link":"https:\/\/icicimov.com\/blog\/?p=142","title":{"rendered":"Setting up Encompass Maintenance Page with ELB, S3, Route53 and CloudFront"},"content":{"rendered":"<p>This is for the environments we have <code>ELB (Elastic Load Balancer)<\/code> instead of <code>HAProxy<\/code>. The idea is to host the maintenance page as static website in <code>S3<\/code> bucket and then have a <code>Failover<\/code> DNS records in <code>Route53<\/code> for the targeted subdomain. To enable SSL support, the S3 bucket is going to be accessed via <code>CloudFront<\/code> CDN distribution where we upload our SSL certificate. The ELB will be set as <code>Primary<\/code> Record with target health evaluation via Route53 DNS health check and the CDN as <code>Secondary<\/code>. In this way the traffic will always flow through the ELB except when it&#39;s backends become unresponsive in which case the DNS record will switch to the CDN\/S3 bucket and our static Maintenance Page will get served.<\/p>\n<h2 id=\"configuration\">Configuration<\/h2>\n<h3 id=\"s3-bucket\">S3 Bucket<\/h3>\n<ul>\n<li>Create S3 bucket with <strong>EXACTLY<\/strong> the same name as the domain\/subdomain we want to create static page for, ie <code>example.encompasshost.com<\/code><\/li>\n<li>Enable the Static Website Hosting option on the bucket and set the Index Document field to index.html<\/li>\n<li>In the Permissions section, add new bucket permission for <code>Everyone<\/code> and tick the only the <code>View Permissions<\/code> check-box<\/li>\n<li>In the same section, click on <code>Add Policy<\/code> button and create new <code>Bucket Policy<\/code> to make the bucket public by pasting the following content in the policy field\n<pre><code class=\"lang-json\">{\n  Version:2012-10-17,\n  Statement:[\n    {\n      Sid:AddPerm,\n      Effect:Allow,\n      Principal: *,\n      Action:[s3:GetObject],\n      Resource:[arn:aws:s3:::example.encompasshost.com\/*]\n    }\n  ]\n}<\/code><\/pre>\n<p>The Resource should be appropriately set to match our bucket name\n<\/li>\n<li>Enter the bucket and create the folders needed and upload the maintenance page, the fonts and images<\/li>\n<li>Since we are going to use CDN to serve our S3 maintenance page, we include the following caching headers in our <code>index.html<\/code> page\n<pre><code class=\"lang-html\"><meta http-equiv=Cache-Control content=public,max-age=900,must-revalidate \/>\n<meta http-equiv=ETag content=201504211145 \/>\n<meta http-equiv=Vary content=Accept-Encoding,ETag \/>\n<meta http-equiv=Pragma content=public,max-age=604800,must-revalidate \/>\n<\/code><\/pre>\n<p>The <code>ETag<\/code> field is important to refresh the page when we change it&#39;s content or the old cached one will keep being served to the clients from the CDN cache. The format I chose is <code>YYYYMMDDHHmm<\/code> and should be good enough to support even multiple page versions per day (on each change we need to change the Etag timestamp). The page and its assets will be cached for 15 minutes.\n<\/li>\n<li>To index our maintenance page we upload <code>robots.txt<\/code> file to the bucket\n<pre><code>robots.txt\nUser-agent: *\nDisallow: \/font\/\nDisallow: \/img\/\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<h3 id=\"cloudfront\">CloudFront<\/h3>\n<p>To use our Encompasshost certificate in CDN we need to upload it first to our IAM service:<\/p>\n<pre><code>ubuntu@server:~\/ssl_encompasshost$ aws iam upload-server-certificate\n--server-certificate-name EncompasshostWildcardCert --certificate-body file:\/\/encompasshost-crt.pem --private-key file:\/\/encompasshost-key.pem --certificate-chain file:\/\/encompasshost-cachain.pem --path \/cloudfront\/star-encompasshost-com\/\n{\n    \"ServerCertificateMetadata\": {\n        \"Path\": \"\/cloudfront\/star-encompasshost-com\/\",\n        \"Arn\": \"arn:aws:iam::<my -arn>:server-certificate\/cloudfront\/star-encompasshost-com\/EncompasshostWildcardCert\",\n        \"ServerCertificateId\": \"AS...V6\",\n        \"ServerCertificateName\": \"EncompasshostWildcardCert\",\n        \"UploadDate\": \"2015-04-21T06:39:35.414Z\"\n    }\n}<\/my><\/code><\/pre>\n<p>Then we go on to creating a new distribution. When finished and deployed it should have the following parameters:<\/p>\n<pre><code>Distribution ID: E2...1M\nLog Prefix: -\nDelivery Method: Web\nCookie Logging: Off\nDistribution Status: Deployed\nComment: -\nPrice Class: Use All Edge Locations (Best Performance)\nState: Enabled\nAlternate Domain Names (CNAMEs): example.encompasshost.com\nSSL Certificate: EncompasshostWildcardCert\nDomain Name: dy...sl.cloudfront.net\nCustom SSL Client Support: Only Clients that Support Server Name Indication (SNI)\nDefault Root Object: index.html\nLast Modified: 2015-04-21 17:19 UTC+10\nLog Bucket: -<\/code><\/pre>\n<h3 id=\"route-53\">Route 53<\/h3>\n<p>We move now to setting up our DNS fail over strategy. First we create Route53 Health Check pointing to the ELB serving our site. When finished it should have the following parameters:<\/p>\n<pre><code>Name: EXAMPLE\nURL: https:\/\/dualstack.example-elasticl-....eu-west-1.elb.amazonaws.com:443\/resource\/hc\/application\nHost Name: dualstack.example-elasticl-....eu-west-1.elb.amazonaws.com\nIP Address: -\nProtocol: HTTPS\nPort: 443\nRequest Interval: 10 seconds\nFailure Threshold: 2<\/code><\/pre>\n<p>The URL and Host Name should be pointing to our ELB&#39;s CNAME (or A record as named on the ELB&#39;s page). In less then a minute the <code>Healt Check<\/code> should show as Healthy in the heath checks table in Route53. While we are here, we also create an CloudWatch Alarm so we get emails when the site is down and switch over to the Maintenance Page should happen.<\/p>\n<p>Now we need to edit the existing Route53 Record Set for the domain name, in our case <code>example.encompasshost.com<\/code> (or create a new one if it doesn&#39;t exist yet). We need to convert this record into <code>Failover<\/code> type. When finished the record should have the following parameters:<\/p>\n<pre><code>Name: example.encompasshost.com.\nType: A - IPv4 address\nAlias: Yes\nAlias Target: &lt;select our ELB from the drop-down menu&gt;\nAlias Hosted Zone ID: Z3...W2\nRouting Policy: Failover\nFailover Record Type: Primary\nSet ID: example-Primary\nEvaluate Target Health: Yes\nAssociate with Health Check: Yes<\/code><\/pre>\n<p>When choosing Yes for the Associate with Health Check option, a drop-down menu will appear from which we can select our newly created EXAMPLE Health Check.<\/p>\n<p>Next we create another <code>Failover Record<\/code> for the same domain name with the S3 bucket, actually the CDN distribution we use the S3 bucket as source, as target and set it as <code>Secondary<\/code>. The parameters we need to set:<\/p>\n<pre><code>Name: example.encompasshost.com.\nType: A - IPv4 address\nAlias: Yes\nAlias Target: &lt;our CLoudFront distribution will appear in the drop-down menu and we select it&gt;\nRouting Policy: Failover\nFailover Record Type: Secondary\nSet ID: example-Secondary\nEvaluate Target Health: No\nAssociate with Health Check: No<\/code><\/pre>\n<p>This will work for most of the modern browsers with SNI support (IE7+ on Windows Vista or higher, FF2+, Opera8+, Chrome6+, Safari3+). For various browser support refer to the following page: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Server_Name_Indication#Web_browsers.5B6.5D\">Server Name Indication<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is for the environments we have ELB (Elastic Load Balancer) instead of HAProxy. The idea is to host the maintenance page as static website in S3 bucket and then have a Failover DNS records in Route53 for the targeted&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-142","post","type-post","status-publish","format-standard","hentry","category-aws"],"_links":{"self":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/142","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=142"}],"version-history":[{"count":8,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/142\/revisions"}],"predecessor-version":[{"id":150,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/142\/revisions\/150"}],"wp:attachment":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}