[{"content":"For years my blog lived on a hosted platform. It looked fine, wrote well, and cost me a monthly subscription just to keep the domain and a few pages alive. This year the renewal bill went up again, and I thought — why am I paying rent every month for a handful of posts?\nSo over one evening, I moved everything to my own domain, my own AWS account, and a static site generator. Total ongoing cost: less than a cup of coffee per month. Here\u0026rsquo;s how it works.\nThe bill of materials # Item Where Cost Domain (yearly) Any registrar one-time-ish per year S3 bucket (a few hundred KB of HTML) AWS ~a rupee a month CloudFront distribution AWS global free tier first year, then a few rupees/month ACM TLS certificate AWS free, auto-renews DNS Registrar\u0026rsquo;s built-in DNS free Static site generator Hugo + a theme free \u0026amp; open source Compared to a monthly SaaS subscription, the difference is night and day. AWS charges by usage — a personal blog barely uses anything.\nThe architecture # Reader\u0026#39;s browser │ ▼ https://www.yourdomain │ ▼ Registrar DNS (CNAME www → CloudFront) │ ▼ Amazon CloudFront (HTTPS, ACM cert, global CDN) │ OAC (Origin Access Control) ▼ Private S3 Bucket (static HTML/CSS/JS built by Hugo) S3 stores the generated site (private — no public bucket). CloudFront sits in front, serves over HTTPS, caches globally. ACM issues the TLS cert for free. Registrar DNS points www.yourdomain at the CloudFront domain, and forwards the apex (yourdomain) to www with a 301. The whole thing is boring, standard, and cheap.\nStep 1 — Build the site locally with Hugo #Hugo is a single binary, ridiculously fast, and blog themes are plentiful.\nbrew install hugo hugo new site my-blog --format yaml cd my-blog git submodule add \u0026lt;theme-repo-url\u0026gt; themes/\u0026lt;theme\u0026gt; Then write posts in Markdown under content/posts/, run hugo server, and preview at http://127.0.0.1:1313/.\nStep 2 — Create the S3 bucket #Bucket names are globally unique across all of AWS. The bucket name doesn\u0026rsquo;t need to match your domain when CloudFront is the origin — pick anything memorable.\naws s3api create-bucket \\ --bucket my-blog-bucket \\ --region \u0026lt;your-region\u0026gt; \\ --create-bucket-configuration LocationConstraint=\u0026lt;your-region\u0026gt; aws s3api put-public-access-block \\ --bucket my-blog-bucket \\ --public-access-block-configuration \\ BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true Block all public access. CloudFront reads via Origin Access Control (OAC) — the modern replacement for OAI. No s3-website hosting, no public buckets, no exposed endpoints.\nStep 3 — Request an ACM certificate #CloudFront only accepts certificates from the us-east-1 region, regardless of where your bucket lives.\naws acm request-certificate \\ --domain-name yourdomain \\ --subject-alternative-names www.yourdomain \\ --validation-method DNS \\ --region us-east-1 ACM returns two CNAME records to prove you own the domain. Copy them into your registrar\u0026rsquo;s DNS.\nCommon gotcha: In many registrar UIs, the \u0026ldquo;Name\u0026rdquo; field is relative to your domain. If ACM tells you the record is _xxx.yourdomain, enter just _xxx — otherwise the record ends up as _xxx.yourdomain.yourdomain and validation fails silently.\nOnce both CNAMEs propagate (usually a few minutes), the cert flips from PENDING_VALIDATION to ISSUED.\nStep 4 — Create the CloudFront distribution #The important bits:\nOrigin = S3 bucket, accessed via OAC (not public URL, not OAI) Aliases = your bare domain + www variant Viewer certificate = the ACM cert from step 3 Default root object = index.html HTTPS redirect, HTTP/2 + /3, IPv6 enabled Cheapest price class if you don\u0026rsquo;t need every edge location Then attach a bucket policy that only lets this specific distribution read files:\n{ \u0026#34;Version\u0026#34;: \u0026#34;2012-10-17\u0026#34;, \u0026#34;Statement\u0026#34;: [{ \u0026#34;Effect\u0026#34;: \u0026#34;Allow\u0026#34;, \u0026#34;Principal\u0026#34;: { \u0026#34;Service\u0026#34;: \u0026#34;cloudfront.amazonaws.com\u0026#34; }, \u0026#34;Action\u0026#34;: \u0026#34;s3:GetObject\u0026#34;, \u0026#34;Resource\u0026#34;: \u0026#34;arn:aws:s3:::my-blog-bucket/*\u0026#34;, \u0026#34;Condition\u0026#34;: { \u0026#34;StringEquals\u0026#34;: { \u0026#34;AWS:SourceArn\u0026#34;: \u0026#34;arn:aws:cloudfront::\u0026lt;account-id\u0026gt;:distribution/\u0026lt;dist-id\u0026gt;\u0026#34; } } }] } Step 5 — The CloudFront Function that saved my life #Out of the box, CloudFront\u0026rsquo;s \u0026ldquo;default root object\u0026rdquo; only applies to /. That means https://www.yourdomain/posts/ asks S3 for a file literally named posts/, gets a 403, and returns 404 to the visitor.\nFix: a tiny CloudFront Function that runs on every viewer request and rewrites clean URLs to their index.html equivalent.\nfunction handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith(\u0026#39;/\u0026#39;)) { request.uri = uri + \u0026#39;index.html\u0026#39;; } else if (!uri.includes(\u0026#39;.\u0026#39;)) { request.uri = uri + \u0026#39;/index.html\u0026#39;; } return request; } Attach to the distribution\u0026rsquo;s viewer-request event. Every Hugo/Jekyll/Astro site on S3 + CloudFront needs this.\nStep 6 — Wire up DNS #Two records at your registrar:\nType Name Value CNAME www d3xxxxxxxxx.cloudfront.net Forward apex yourdomain 301 → https://www.yourdomain (masking OFF) If your registrar can\u0026rsquo;t do ALIAS-style records at the apex (many can\u0026rsquo;t), use their built-in domain forwarding to redirect the naked domain to www. Slightly less elegant than an ALIAS, but free — and hosted DNS elsewhere would add a small monthly fee for a hobby site.\nStep 7 — The one-command deploy #Everything above is a one-time setup. Day to day, publishing a new post is one command:\n#!/usr/bin/env bash set -euo pipefail hugo --minify --gc aws s3 sync public/ s3://my-blog-bucket/ --delete \\ --exclude \u0026#34;*\u0026#34; --include \u0026#34;*.html\u0026#34; --include \u0026#34;*.xml\u0026#34; --include \u0026#34;*.json\u0026#34; \\ --cache-control \u0026#34;public, max-age=300, must-revalidate\u0026#34; aws s3 sync public/ s3://my-blog-bucket/ --delete \\ --exclude \u0026#34;*.html\u0026#34; --exclude \u0026#34;*.xml\u0026#34; --exclude \u0026#34;*.json\u0026#34; \\ --cache-control \u0026#34;public, max-age=31536000, immutable\u0026#34; aws cloudfront create-invalidation \\ --distribution-id \u0026lt;dist-id\u0026gt; --paths \u0026#34;/*\u0026#34; HTML files get a short cache (5 min) so edits appear fast. Fingerprinted assets (CSS/JS/images) get a year-long immutable cache — Hugo hashes filenames on every build, so it\u0026rsquo;s safe. CloudFront invalidation forces edge caches to refresh HTML immediately. Run ./deploy.sh after every edit. Full pipeline runs in about 15 seconds.\nWhat it costs, honestly #For the first year you\u0026rsquo;re inside CloudFront\u0026rsquo;s free tier (1 TB out/month, 10M requests). After that, for a personal blog with a few hundred visits a month, we\u0026rsquo;re talking single-digit rupees per month. The domain is by far the biggest cost — and it\u0026rsquo;s the same whether you host on any SaaS platform, GitHub Pages, or your own AWS account.\nWould I do this again? #Yes, without a second thought. It took an evening to set up. It\u0026rsquo;s mine — I own the domain, I own the content, I can move it to any other host in a day. And I\u0026rsquo;ll never get another \u0026ldquo;your subscription is about to renew\u0026rdquo; email.\nIf you\u0026rsquo;re on a hosted platform and thinking of moving — this is the path. Static site + AWS + your own domain. Boring, cheap, and yours.\n","date":"10 August 2026","permalink":"https://www.swashikan.com/posts/hosting-my-blog-on-aws-for-free/","section":"Posts","summary":"How to move a blog off a paid platform, use your own domain, and host it on AWS for pennies a month.","title":"From a Paid Blog Platform to (Almost) Free: Hosting a Blog on AWS + DNS"},{"content":"","date":null,"permalink":"https://www.swashikan.com/posts/","section":"Posts","summary":"","title":"Posts"},{"content":"","date":null,"permalink":"https://www.swashikan.com/","section":"Swashikan","summary":"","title":"Swashikan"},{"content":"Here, we are going to see how to write Terraform configuration scripts to create a new RDS database instance using the latest snapshot which is created by the system as daily snapshots.\nThe main purpose of this configuration script is to use it in a Disaster Recovery situation, where the main RDS databases are down and we need to create a new RDS database instance using the latest snapshot created by the system — whether daily or weekly.\nProvider block #First we need the mandatory resource block known as the Provider block:\nterraform { required_providers { aws = { source = \u0026#34;hashicorp/aws\u0026#34; version = \u0026#34;3.74.1\u0026#34; } } } provider \u0026#34;aws\u0026#34; { region = \u0026#34;us-east-1\u0026#34; } Here we mention the provider we are using (AWS, GCP, Azure, etc.) and the region we are going to perform the task in.\nData block — fetch the latest snapshot #Once the provider block is complete, we create the data block. It is used to fetch data from the cloud provider so we can use it in our Terraform script. In our task we are going to fetch the latest snapshot of our RDS DB, which is created on a scheduled interval:\n# Get latest snapshot from RDS DB data \u0026#34;aws_db_snapshot\u0026#34; \u0026#34;db_snapshot\u0026#34; { most_recent = true db_instance_identifier = \u0026#34;\u0026lt;DB instance or cluster name\u0026gt;\u0026#34; } aws_db_snapshot — the resource we are fetching data from. db_snapshot — the name of the data block we are creating. most_recent — pull the latest RDS DB snapshot. db_instance_identifier — the RDS snapshot DB instance or cluster name. Resource block — create the new RDS instance #Then we create a DB instance resource using the snapshot id fetched by the data block above:\n# Create RDS instance from snapshot resource \u0026#34;aws_db_instance\u0026#34; \u0026#34;recovered_db\u0026#34; { identifier = \u0026#34;name-of-the-new-RDS\u0026#34; snapshot_identifier = data.aws_db_snapshot.db_snapshot.id skip_final_snapshot = true } aws_db_instance — the resource used to create a new RDS DB instance. recovered_db — the name of the resource block we are creating. identifier — the name of the new RDS DB instance. snapshot_identifier — the snapshot id from the data block above. skip_final_snapshot: If true, when destroying the RDS DB, Terraform will skip taking a final snapshot. If false, Terraform will take a final snapshot on destroy, and you must also specify: final_snapshot_identifier = \u0026#34;snapshot_name\u0026#34; That\u0026rsquo;s it for the resource block for our use case.\nBy planning and applying this Terraform configuration script, we can create a new RDS DB instance using the latest RDS DB snapshot.\nThanks for reading — catch you in the next post.\n","date":"28 August 2023","permalink":"https://www.swashikan.com/posts/creating-rds-db-instance-from-snapshot-using-terraform/","section":"Posts","summary":"Writing Terraform to spin up a new RDS instance from the latest DB snapshot for disaster recovery.","title":"Creating RDS DB Instance from Snapshot using Terraform for DR"},{"content":"I had it for an year, on 2014 we are all very familiar with a Sport Bike Manufacturer Named KTM and their Naked bikes named Duke 200 and Duke 390. It was so impressive in the way it looked and the performance it had. At the time 2014 the most torque producing bike in the mid-market was these.\nAs a Adrenaline Junkie I loved the Performance and Risk Review it got all over the place. It had a Review of most Deaths happend with a bike was these due to the torque it produced. I was Dreaming of buying Duke 200 as it was around Rs 1.65 lakhs and it was most valuable money for my family.\nThen on May 2014 I saw a news about a KTM\u0026rsquo;s that year\u0026rsquo;s launch of a very new model of a bike which is completely based on track usage named RC 200 and RC 390. It was very damned in the way they looked and they actually produced the same amount of performance as Duke\u0026rsquo;s which are speed limited to 179 Kmph (RC 390 and Duke 390 Models). So I made a lot of dramas just to prebook RC 200 so once it got launched at September 2014.\nWe as a family went to Prebook the bike in KTM Showroom, Ashok Nagar, Chennai. Once we arrived at the show room we were able to touch and feel both the bike RC 200 and RC 390. The RC 390 was more bolder and worthier than the 200 and it had a double the Performance of RC 200 with the price difference of 50K Rs. So my Mother without knowing about the Horsepowers helped me to prebook the 390 model rather than 200. It had a horsepower of 43Bhp.\nThen It was very silent for next 6 months till March 2015, I used to have a habit of watching the showroom daily and starring like it was from out of this world.\nThen one day we got the call that the bike has Arrived. We\nhave paid 2.46 lakhs for the Beast. I went to the day of delivery it was such a awww moment that made me to keep the bike with me till now even after I bought a car and a Royal Enfield Continental GT 650. That was an another story will be shared soon.\nThank you for Reading this long about the story of my First Bike.\n","date":"5 August 2023","permalink":"https://www.swashikan.com/posts/the-story-of-my-ktm-rc-390/","section":"Posts","summary":"How I fell for the KTM RC 390 in high school and finally rode home on one years later.","title":"The Story of My KTM RC 390"},{"content":"The Knowledge shared on the topic was \u0026ldquo;Adapting Open Source LLMs (Large Language Model) for your use-case\u0026rdquo; by Logesh Kumar Umapathi, who is a Lead ML Research Engineer at Saama Technologies, Inc.\nIt was my First Experience in Participating on Innovative Meetup held at Saama, on the topic of Generative AI.\nEven-though I have learnt some of the theory on AI and ML in my UG Degree, It was quite challenging to keep up with the people present there.\nI understood a lot, but I found there was so much to learn on these technologies.\nThe Agenda was Case for Adapting Open Source LLMs, Ways to Adapt in LLMs and Why Open Source LLMs. Logesh Spoke about a lot on the First agenda like \u0026ldquo;What is a Commercial Api\u0026rdquo;, \u0026ldquo;What are the advantages and Disadvantages of LLMs\u0026rdquo; and \u0026ldquo;Where we can use the Commercial Api\u0026rdquo;.\nThe Second agenda is all about the Ways to adapt Large Language Models. In that we got knowledge on \u0026ldquo;Prompting\u0026rdquo;, \u0026ldquo;Instruction / Task-Specific fine-tuning\u0026rdquo; and the last one is \u0026ldquo;Hybrid - LLM Cascade\u0026rdquo;.\nIn Prompting we have seen demo on StarCoderPlus, SantaCoder Models and some of the Prompt tuning techniques.\nIn Instruction Tuning / Supervised fine-tuning we got to know about multiple patterns like Simple Tuning and Multi Task models.\nIn Hybrid - LLM Cascade, which is a combination of both Open Source and Commercial LLMs. It works as Hoping onto multiple GPT for accurate score until it gets a most preferred match.\nMy Conclusion about the Meetup held was Very Useful with the latest technique in Open Source LLMs and with some great Questions and Answers asked.\nFrugalGPT: How to Use Large Language Models While Reducing Cost and Improving Performance. (https://arxiv.org/pdf/2305.05176.pdf)\nThe Power of Scale for Parameter-Efficient Prompt Tuning. (https://aclanthology.org/2021.emnlp-main.243.pdf)\nLlama 2: Open Foundation and Fine-Tuned Chat Models (https://arxiv.org/pdf/2307.09288.pdf)\nLORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS (https://openreview.net/pdf?id=nZeVKeeFYf9)\nTraining language models to follow instructions with human feedback (https://proceedings.neurips.cc/paper_files/paper/2022/file/b1efde53be364a73914f58805a001731-Paper-Conference.pdf)\n","date":"31 July 2023","permalink":"https://www.swashikan.com/posts/my-first-meetup-on-generative-ai/","section":"Posts","summary":"Notes from my first Generative AI meetup at Saama — open-source LLMs, prompting, fine-tuning, and hybrid LLM cascades.","title":"My First Meetup on Generative AI"}]