<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Infrastructure on Alexander's Blog</title><link>https://alexanderbakin.com/categories/infrastructure/</link><description>Recent content in Infrastructure on Alexander's Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 20 Aug 2026 12:02:45 +0400</lastBuildDate><atom:link href="https://alexanderbakin.com/categories/infrastructure/index.xml" rel="self" type="application/rss+xml"/><item><title>Building a Production-Grade Personal Blog with AWS, Terraform, and Hugo</title><link>https://alexanderbakin.com/meta/</link><pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate><guid>https://alexanderbakin.com/meta/</guid><description>&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;As a DevOps engineer, your personal website is your portfolio. It should demonstrate not just what you &lt;em&gt;know&lt;/em&gt; but what you &lt;em&gt;build&lt;/em&gt;. This blog is itself an example of a production-grade cloud architecture - every decision documented, every tradeoff explained.&lt;/p&gt;
&lt;h2 id="architecture-overview"&gt;Architecture Overview&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Architecture diagram: Route53 to CloudFront to S3, with GitHub Actions driving Terraform and content deploys via OIDC" loading="lazy" src="https://alexanderbakin.com/images/architecture-diagram.svg"&gt;&lt;/p&gt;
&lt;p&gt;The stack:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Markdown → Hugo static site&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI/CD (Infra)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub Actions - PR plan, merge apply&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI/CD (Content)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub Actions - build, sync, invalidate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State Mgmt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;S3 backend, concurrency-gated at pipeline level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Origin&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;S3 (private, versioned, encrypted, CloudFront OAC only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CDN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CloudFront with HTTPS, Brotli/Gzip, security headers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DNS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Route 53 alias records (A / AAAA, root + www)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TLS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ACM certificate (auto-renewal, TLSv1.2_2021)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OIDC - no AWS access keys stored anywhere&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CloudWatch dashboard + error rate alarm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost Control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AWS Budgets alert (direct email)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-design-decisions"&gt;Key Design Decisions&lt;/h2&gt;
&lt;h3 id="1-two-separate-pipelines"&gt;1. Two Separate Pipelines&lt;/h3&gt;
&lt;p&gt;Infrastructure changes and content changes have different risk profiles and review requirements. They&amp;rsquo;re handled by separate workflows:&lt;/p&gt;</description></item></channel></rss>