<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alexander Gusarov</title>
    <description>The latest articles on DEV Community by Alexander Gusarov (@keegooroomie).</description>
    <link>https://dev.to/keegooroomie</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3837057%2F180200bc-bc34-4c5f-a204-e5d70a20dc20.png</url>
      <title>DEV Community: Alexander Gusarov</title>
      <link>https://dev.to/keegooroomie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/keegooroomie"/>
    <language>en</language>
    <item>
      <title>I Got Rejected for "Not Enough Experience" — So I Built My Resume as Infrastructure</title>
      <dc:creator>Alexander Gusarov</dc:creator>
      <pubDate>Sat, 21 Mar 2026 13:36:11 +0000</pubDate>
      <link>https://dev.to/keegooroomie/i-got-rejected-for-not-enough-experience-so-i-built-my-resume-as-infrastructure-j1i</link>
      <guid>https://dev.to/keegooroomie/i-got-rejected-for-not-enough-experience-so-i-built-my-resume-as-infrastructure-j1i</guid>
      <description>&lt;p&gt;Let me paint you a picture.&lt;/p&gt;

&lt;p&gt;It's 2024. I've been in IT for 14 years — Flash games at 13, mobile GameDev, frontend, fullstack, and for the last few years, DevOps. I've managed 750+ servers with Ansible, cut deploy times from 8 minutes to 2, saved ~$250/month on AWS costs through Terraform optimizations. I've shipped games with 100M+ downloads. I have an Upwork Top Rated Plus badge.&lt;/p&gt;

&lt;p&gt;And HR keeps telling me I don't have enough experience.&lt;/p&gt;

&lt;p&gt;Not because I'm unqualified. Because my resume didn't tell the story right. Because I was sending a Google Doc that tried to be everything to everyone — and ended up being nothing to anyone.&lt;/p&gt;

&lt;p&gt;So I did what any reasonable DevOps engineer would do when faced with a tooling problem.&lt;/p&gt;

&lt;p&gt;I over-engineered a solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Actual Problem
&lt;/h2&gt;

&lt;p&gt;Here's what my resume situation looked like before:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One Russian &lt;code&gt;.docx&lt;/code&gt; for local job applications&lt;/li&gt;
&lt;li&gt;One English &lt;code&gt;.docx&lt;/code&gt; for international / remote&lt;/li&gt;
&lt;li&gt;A "DevOps focused" copy somewhere&lt;/li&gt;
&lt;li&gt;A "GameDev focused" copy somewhere else&lt;/li&gt;
&lt;li&gt;A file literally named &lt;code&gt;CV_Gusarov_FINAL_v3_actually_final.docx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time I updated one, I forgot to update the others. Every time I applied to a GameDev role, I had to manually shuffle sections around. Every time I wanted to send a PDF, I opened LibreOffice, crossed my fingers, and watched the formatting break.&lt;/p&gt;

&lt;p&gt;This is a data consistency problem. And data consistency problems have a solution: &lt;strong&gt;a single source of truth&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;I called the project &lt;strong&gt;CV Hub&lt;/strong&gt;. Here's what I wanted it to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Store all resume data in one place&lt;/li&gt;
&lt;li&gt;Generate a website automatically&lt;/li&gt;
&lt;li&gt;Export to PDF, DOCX, and TXT on every push&lt;/li&gt;
&lt;li&gt;Support multiple languages without duplicating content&lt;/li&gt;
&lt;li&gt;Support multiple role-specific versions from the same data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The stack I landed on: &lt;strong&gt;Astro&lt;/strong&gt; for the site, &lt;strong&gt;YAML&lt;/strong&gt; as the data layer, &lt;strong&gt;GitHub Actions&lt;/strong&gt; for CI/CD, &lt;strong&gt;GitHub Pages&lt;/strong&gt; for hosting. Total infrastructure cost: $0.&lt;/p&gt;

&lt;p&gt;Let me walk through each piece.&lt;/p&gt;




&lt;h2&gt;
  
  
  The YAML Structure
&lt;/h2&gt;

&lt;p&gt;Everything lives in YAML. Not a database, not a CMS, not Notion — plain YAML files that you can read, diff, and version control like any other config.&lt;/p&gt;

&lt;p&gt;There's no bilingual key soup (&lt;code&gt;title.en&lt;/code&gt; / &lt;code&gt;title.ru&lt;/code&gt; inside the same file). Instead, each language is a separate file: &lt;code&gt;en.yaml&lt;/code&gt; and &lt;code&gt;ru.yaml&lt;/code&gt;. Same structure, different content. Clean diffs, no mental overhead when editing.&lt;/p&gt;

&lt;p&gt;A base CV file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alexander&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Gusarov"&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DevOps&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Platform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Engineer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Kubernetes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;·&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Terraform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;·&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;AWS"&lt;/span&gt;
&lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;DevOps engineer with 14+ years in IT. Managed production Kubernetes&lt;/span&gt;
  &lt;span class="s"&gt;clusters, built IaC from scratch with Terraform + Ansible on AWS,&lt;/span&gt;
  &lt;span class="s"&gt;shipped monitoring microservices in Go.&lt;/span&gt;

&lt;span class="na"&gt;contacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GitHub&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/KeeGooRoomiE&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Telegram&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://t.me/spartan121&lt;/span&gt;

&lt;span class="na"&gt;achievements&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Managed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;750+&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Linux&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;servers&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Ansible,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;SLA&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1.5–2&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;min"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reduced&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;AWS&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;costs&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$550&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$300/month&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(−45%)"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cut&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;time&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;8&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;minutes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(−75%)"&lt;/span&gt;

&lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Orchestration&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Kubernetes&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Helm&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Docker&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;IaC &amp;amp; Automation&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Terraform&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Ansible&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cloud&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;AWS — EC2&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;S3&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;RDS&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;VPC&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;IAM&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ALB&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Languages&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Go&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Python&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Bash&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;experience&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;InfoScale"&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DevOps&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Engineer"&lt;/span&gt;
    &lt;span class="na"&gt;period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dec&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2024&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;—&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jan&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2026"&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Administered&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Kubernetes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;clusters&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Yandex&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Cloud"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Built&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;full&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;IaC&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;solution&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Terraform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;+&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Ansible&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;AWS&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(~20&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;services)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reduced&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;MTTR&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;by&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;60%&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;custom&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Grafana/VictoriaMetrics&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;dashboards"&lt;/span&gt;
    &lt;span class="na"&gt;stack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Kubernetes&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Helm&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Terraform&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Ansible&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;AWS&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Go&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Grafana&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: &lt;strong&gt;your resume data and your resume presentation are two different concerns&lt;/strong&gt;. YAML handles the data. Astro handles the presentation. They never mix.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-Role Overlay System
&lt;/h2&gt;

&lt;p&gt;This was the part I was most excited about architecting.&lt;/p&gt;

&lt;p&gt;I have genuinely different professional identities: DevOps engineer, GameDev (shipped titles with 100M+ downloads), Frontend/Fullstack developer. Each of these roles needs a different emphasis — different projects front and center, different skills highlighted, different summary framing.&lt;/p&gt;

&lt;p&gt;The naive solution: maintain separate full YAML files per role. The problem: now you have four sources of truth, and the sync nightmare is back.&lt;/p&gt;

&lt;p&gt;My solution: &lt;strong&gt;per-language base files + minimal delta files per profile&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;src/content/cv/&lt;/span&gt;
  &lt;span class="s"&gt;en.yaml              ← base CV in English&lt;/span&gt;
  &lt;span class="s"&gt;ru.yaml              ← base CV in Russian&lt;/span&gt;
  &lt;span class="s"&gt;en_devops.yaml       ← DevOps delta (only what changes)&lt;/span&gt;
  &lt;span class="s"&gt;ru_devops.yaml       ← DevOps delta in Russian&lt;/span&gt;
  &lt;span class="s"&gt;en_gamedev.yaml      ← GameDev delta&lt;/span&gt;
  &lt;span class="s"&gt;ru_gamedev.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The delta file contains &lt;em&gt;only what changes&lt;/em&gt;. Everything else is inherited from the base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# en_devops.yaml — only overrides&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DevOps&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Platform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Engineer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Kubernetes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;·&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Terraform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;·&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;AWS"&lt;/span&gt;

&lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;DevOps-focused summary with emphasis on infrastructure...&lt;/span&gt;

&lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Orchestration&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Kubernetes&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Helm&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Docker&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;IaC &amp;amp; Automation&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Terraform&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Ansible&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;experience&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;InfoScale&lt;/span&gt;        &lt;span class="c1"&gt;# no fields = take everything from base&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AZNResearch&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Backend&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Engineer"&lt;/span&gt;  &lt;span class="c1"&gt;# override role, rest from base&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Developed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;backend&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;microservices&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.NET&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Core"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Introduced&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Git&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;workflow&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CI&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pipelines"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before the build, a &lt;code&gt;merge.mjs&lt;/code&gt; script runs and produces merged artifacts in &lt;code&gt;public/cv/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/content/cv/en.yaml + en_devops.yaml
        ↓ merge.mjs
public/cv/en_devops.yaml  ← merged, ready to render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Astro pages read from &lt;code&gt;public/cv/&lt;/code&gt; — not from source directly. This keeps the merge logic in one place and out of the component layer.&lt;/p&gt;

&lt;p&gt;The profiles registry ties everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/content/profiles/profiles.yml&lt;/span&gt;
&lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generalist"&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;        &lt;span class="c1"&gt;# URL root /&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;      &lt;span class="c1"&gt;# no delta, use base as-is&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;devops&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DevOps"&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;devops"&lt;/span&gt;  &lt;span class="c1"&gt;# URL: /devops, /devops/ru&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;devops&lt;/span&gt;    &lt;span class="c1"&gt;# reads en_devops.yaml, ru_devops.yaml&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gamedev&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Game&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Developer"&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gamedev"&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gamedev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One update to an experience entry in &lt;code&gt;en.yaml&lt;/code&gt; propagates to all profiles automatically. The delta only needs to exist where something actually differs.&lt;/p&gt;




&lt;h2&gt;
  
  
  i18n Without a Framework
&lt;/h2&gt;

&lt;p&gt;I deliberately avoided i18n libraries. They add complexity, and for a resume site the translation problem is actually simple.&lt;/p&gt;

&lt;p&gt;The content layer uses the "one file per language" approach — &lt;code&gt;en.yaml&lt;/code&gt; and &lt;code&gt;ru.yaml&lt;/code&gt; are independent, same structure, different text. No nested keys, no bilingual soup, clean diffs.&lt;/p&gt;

&lt;p&gt;For UI strings (labels, navigation, button text), there's a separate &lt;code&gt;translations.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# src/content/i18n/translations.yaml&lt;/span&gt;
&lt;span class="na"&gt;nav&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;showcase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Showcase"&lt;/span&gt;
    &lt;span class="na"&gt;ru&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Проекты"&lt;/span&gt;

&lt;span class="na"&gt;cv&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skills"&lt;/span&gt;
    &lt;span class="na"&gt;ru&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Навыки"&lt;/span&gt;
  &lt;span class="na"&gt;experience&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Experience"&lt;/span&gt;
    &lt;span class="na"&gt;ru&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Опыт"&lt;/span&gt;
  &lt;span class="na"&gt;download&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Download"&lt;/span&gt;
    &lt;span class="na"&gt;ru&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Скачать"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small &lt;code&gt;makeT&lt;/code&gt; helper resolves keys with a three-level fallback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nav.showcase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// → "Showcase" or "Проекты"&lt;/span&gt;
&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cv.skills&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;// → "Skills" or "Навыки"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fallback chain: requested lang → &lt;code&gt;en&lt;/code&gt; → the key path itself as a string. So missing translations never crash the build — they just show the key, which is immediately obvious in review.&lt;/p&gt;

&lt;p&gt;Language state lives in the URL: &lt;code&gt;/devops&lt;/code&gt; is English, &lt;code&gt;/devops/ru&lt;/code&gt; is Russian. Every page is independently shareable and indexable. The language switcher preserves the current profile, the profile dropdown preserves the current language. No cookies, no localStorage, no hydration shenanigans.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Export Pipeline
&lt;/h2&gt;

&lt;p&gt;This was honestly the trickiest part to get right.&lt;/p&gt;

&lt;p&gt;I wanted three export formats: &lt;strong&gt;PDF&lt;/strong&gt; (for HR), &lt;strong&gt;DOCX&lt;/strong&gt; (for ATS systems that parse Word files better), and &lt;strong&gt;TXT&lt;/strong&gt; (plain text for copy-paste into application forms).&lt;/p&gt;

&lt;p&gt;The build runs in four steps, in order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run cv:build          &lt;span class="c"&gt;# 1. merge YAMLs → public/cv/&lt;/span&gt;
npm run resume:generate   &lt;span class="c"&gt;# 2. DOCX + TXT for all merged files&lt;/span&gt;
npm run resume:pdf        &lt;span class="c"&gt;# 3. PDF via Playwright headless render&lt;/span&gt;
astro build               &lt;span class="c"&gt;# 4. static site&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 1 (&lt;code&gt;merge.mjs&lt;/code&gt;) produces all the merged artifacts in &lt;code&gt;public/cv/&lt;/code&gt;. Steps 2 and 3 read those artifacts and output files into &lt;code&gt;public/downloads/&lt;/code&gt;. Step 4 builds the Astro site, which already has the downloads sitting in the right place.&lt;/p&gt;

&lt;p&gt;File naming follows a consistent pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resume_en.pdf              ← default profile, English
resume_ru.pdf              ← default profile, Russian
resume_en_devops.pdf       ← DevOps profile, English
resume_ru_devops.pdf       ← DevOps profile, Russian
resume_en_gamedev.pdf      ← GameDev profile, English
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The download URLs are built at page generation time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;specSuffix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profileData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spec&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;profileData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/downloads/resume_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;langId&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;specSuffix&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.pdf`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So &lt;code&gt;/devops&lt;/code&gt; serves &lt;code&gt;resume_en_devops.pdf&lt;/code&gt;, &lt;code&gt;/gamedev/ru&lt;/code&gt; serves &lt;code&gt;resume_ru_gamedev.pdf&lt;/code&gt;. Each page offers the right file for its profile × language combination.&lt;/p&gt;

&lt;p&gt;PDF generation uses Playwright — headless browser renders the built HTML with a proper two-column A4 layout. This took the most time to get right. Print CSS is a dark art: &lt;code&gt;@page&lt;/code&gt; rules, page break behavior, orphan/widow control, font embedding — all of it needs careful attention. Budget more time for this than you think you'll need.&lt;/p&gt;




&lt;h2&gt;
  
  
  Astro as the Rendering Layer
&lt;/h2&gt;

&lt;p&gt;Why Astro specifically?&lt;/p&gt;

&lt;p&gt;I evaluated a few options: plain HTML templates (too manual), Next.js (overkill for a static site), Jekyll (Ruby, no thanks), Hugo (fine, but Go templating is awkward for this use case).&lt;/p&gt;

&lt;p&gt;Astro won because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero JS by default.&lt;/strong&gt; The resume site doesn't need interactivity beyond language switching and role dropdown. Astro ships zero client-side JavaScript unless you explicitly opt in. The result is a site that loads instantly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Component model.&lt;/strong&gt; I could build &lt;code&gt;&amp;lt;ResumeSection&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ProjectCard&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ExperienceEntry&amp;gt;&lt;/code&gt; as proper components with typed props, rather than copypasting HTML fragments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Static generation with dynamic routing.&lt;/strong&gt; The &lt;code&gt;[...slug].astro&lt;/code&gt; pattern lets me define one template and generate pages for every profile at build time. No runtime server needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Content collections.&lt;/strong&gt; Astro has a built-in concept of typed content collections — perfect for YAML-driven data. I get TypeScript types for my resume data for free.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The project structure ended up clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="nx"&gt;ResumeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
    &lt;span class="nx"&gt;ExperienceSection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
    &lt;span class="nx"&gt;ProjectCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
    &lt;span class="nx"&gt;LanguageToggle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
    &lt;span class="nx"&gt;RoleDropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
  &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;          &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="nx"&gt;redirects&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;
    &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;      &lt;span class="err"&gt;←&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;
    &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;astro&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="nx"&gt;profiles&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
      &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
      &lt;span class="nx"&gt;devops&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
      &lt;span class="nx"&gt;gamedev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
      &lt;span class="nx"&gt;frontend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;
  &lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
    &lt;span class="nx"&gt;profileLoader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
    &lt;span class="nx"&gt;exportHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;A few things surprised me during this build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;YAML is surprisingly good for structured content.&lt;/strong&gt; I went in skeptical — it's finicky about indentation, and deep nesting gets messy. But for resume data specifically, the structure maps cleanly to YAML's strengths. Anchors and aliases let me deduplicate repeated values. The files are readable without tooling. Git diffs on YAML are meaningful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static generation is underrated for personal sites.&lt;/strong&gt; The whole site is a folder of HTML files. No server, no database, no runtime. It deploys to GitHub Pages in under 2 minutes and serves from CDN globally. For something that updates maybe once a week, this is exactly the right architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Print CSS is a dark art.&lt;/strong&gt; If you're generating PDFs from HTML, budget more time than you think for &lt;code&gt;@media print&lt;/code&gt; styles. Page break behavior, orphan/widow control, margin boxes — all of it requires careful attention and lots of test prints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building tools for yourself is the best way to understand what you actually need.&lt;/strong&gt; I shipped features I thought I needed (fancy animations, a complex filtering system for projects) and ended up removing them. The things that stayed were the things I actually used every day: clean export, fast language switching, role overlays.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;The live site is at &lt;a href="https://keegooroomie.github.io/cv_hub" rel="noopener noreferrer"&gt;keegooroomie.github.io/cv_hub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Four profiles, two languages, three export formats. Fully automated. Hosted for free. Updated with a &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Does it help with the job search? Honestly, yes. Having a URL to send instead of an attachment changes the conversation a little. Having role-specific versions means I'm not asking a GameDev hiring manager to mentally filter through Kubernetes metrics to find the relevant parts.&lt;/p&gt;

&lt;p&gt;More importantly — I never have to manually sync resume versions again. That alone was worth the weekend.&lt;/p&gt;




&lt;h2&gt;
  
  
  Use It Yourself
&lt;/h2&gt;

&lt;p&gt;The whole thing is open source and built to be forked:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/KeeGooRoomiE/cv_hub" rel="noopener noreferrer"&gt;github.com/KeeGooRoomiE/cv_hub&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fork it, replace my YAML with yours, push to GitHub, enable Pages — you have a working versioned resume site with automated exports. The README has a setup guide.&lt;/p&gt;

&lt;p&gt;If you find it useful, a ⭐ on the repo goes a long way.&lt;/p&gt;

&lt;p&gt;And if you build something on top of it or run into issues — I'm genuinely curious to hear about it. Drop a comment or open an issue.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Alexander Gusarov — DevOps / Platform Engineer. 14+ years in IT, currently open to new opportunities.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;GitHub: &lt;a href="https://github.com/KeeGooRoomiE" rel="noopener noreferrer"&gt;KeeGooRoomiE&lt;/a&gt; · Telegram: &lt;a href="https://t.me/spartan121" rel="noopener noreferrer"&gt;@spartan121&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>astro</category>
      <category>github</category>
      <category>career</category>
    </item>
  </channel>
</rss>
