Wild walk with #sam and #aws

Mostly these days, I am working with IaC using aws sam cli which gives me a kind of satisfaction – its cumbersome for me to go into the myriad of web gui and continuously clicking. By creating templates and running them from cli has been my choice for too long.

Getting straight into the job, will summarize the initial requirements and the architecture, then move on to additions.

Required Output

Host a Static Site on S3, deliver it globally through Cloud Front CDN with SSL over HTTPS. Once deployed the Route53 tables should be updated. The deployment should use aws sam cli and IaC.

Though there is not much complication in the architecture, while deploying this during the first pandemic wave, after multiple attempts I found that the cloudfront should be created in specific region such that the SSL certificate can be attached.

Well the ACM console was taken and the SSL certificate for both the domains were already requested a couple of days back and it was ready.

Route53 also had the domain as a hosted zone, since we have to create the hosted zone and then update the NS records with the domain registrar which can take some time. One can see there are only 2 records, which are the NS and SOA which gets created with a hosted zone in Route53.

The SAM Template

Nothing “serverless” here, but hosting a site on S3 and delivering over the CDN without managing our own servers could also be considered as part of “serverless”. But the “sam cli” is used only for running the IaC (template.yaml).

The template header tells “sam” to do some transformations, with conformance to the template version specified.

For the resources we start with the S3 (AWS::S3::Bucket), the only thing I was concerned was to permit only the CloudFront to read from this bucket. Hence the AccessControl is set to AuthenticatedRead. For this to work as required, a CloudFront Origin Access Identity has to be attached with a Bucke Policy to be applied to this S3 Bucket.

Before we can start on the Cloud Front Distribution (AWS::CloudFront::Distribution), there are other things to be done which are required for the Cloud Front Distribution properties.

Now we consider taking up the Cloud Front Distribution with the required properties.

Ok, we are almost there, just need to add some DNS entries, accept that these could be done as a RecordSetGroup (AWS::Route53::RecordSetGroup), but found this worked more easily.

Normally there will be some outputs, yes we need the S3 Bucket Name and the Cloud Front ID to be shouted out such that it can be used some where, eg: in a deploy stage with code pipeline.

Now we run the deploy for the initial time with the -g option such that the deployment will ask some questions and then run the deployment.

The prompt after change set is detected

Deployment completed and took about 7 minutes to complete.

Route53 records after completion of the deploy, see the additional 4 records, one each for IPv4 and IPv6 for both domains (www and apex). Note that these are pointed with ‘A’ and ‘AAAA’ resource and alias record with CloudFront Distribution.

Due course, after running for a couple of days, we had an additional requirement where we required a form to be captured, and sent as email to a preset mail address, a kind of support or contact form. Almost all examples on the internet insist on enabling CORS on the API Gateway. Well I have some prejudice on this where the preflight “OPTIONS” request, though is light, will take up additional overheads. Due to this reason, I always do map a request path to a different origin on the CloudFront and forward to the API Gateway Origin. Thus eliminating the requirement of CORS.

A totally new template and code base using NodeJS lambda was deployed with reference to this AWS Architecture Blog article. The API Gateway published endpoint was used in the Origin Configuration, and further properties extended.

Yes this Cache Policy required very low caching, since the purpose was to post some data.

See that the Origins are modified with additional entry to the list array ‘CustomOriginConfig’ which has only the absolute required properties.

Running a sam deploy did take almost 5 minutes, but this can now be ported to build any deployment of static websites.

PS: I posted this after long time since the project was live till last Month, and now it is scraped and all stacks are deleted.