<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Cloud Native Engineer]]></title><description><![CDATA[Master cloud-native engineering with practical insights into Kubernetes, Python, DevOps, and system design. Real solutions from hands-on experience to elevate your technical skills.]]></description><link>https://cloudnativeengineer.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!aG9u!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa06b3aab-f22f-478d-9d0d-550d9a8d6fa5_1280x1280.png</url><title>Cloud Native Engineer</title><link>https://cloudnativeengineer.substack.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 12 May 2026 18:11:04 GMT</lastBuildDate><atom:link href="https://cloudnativeengineer.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Giuseppe Santoro 🚢]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[cloudnativeengineer@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[cloudnativeengineer@substack.com]]></itunes:email><itunes:name><![CDATA[Giuseppe Santoro 🚢]]></itunes:name></itunes:owner><itunes:author><![CDATA[Giuseppe Santoro 🚢]]></itunes:author><googleplay:owner><![CDATA[cloudnativeengineer@substack.com]]></googleplay:owner><googleplay:email><![CDATA[cloudnativeengineer@substack.com]]></googleplay:email><googleplay:author><![CDATA[Giuseppe Santoro 🚢]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Pay your taxes with Claude Code]]></title><description><![CDATA[Episode #47: How connecting Claude Code to Playwright MCP automated my tax return and revealed a bigger pattern]]></description><link>https://cloudnativeengineer.substack.com/p/pay-your-taxes-with-claude-code</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/pay-your-taxes-with-claude-code</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sun, 01 Feb 2026 17:25:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!X1NV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X1NV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X1NV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!X1NV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!X1NV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!X1NV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X1NV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7156225,&quot;alt&quot;:&quot;A steampunk brass-and-copper machine with spinning gears, pipes, and billowing steam. A mechanical arm with a fountain pen writes onto paper rolling out. Tax forms and bank statements feed into a funnel at the top. An engineer in a NASA cap and rust-brown hoodie stands to the side, arms folded, observing the machine work. Illustrated as hand-drawn watercolor with sketch elements and architectural drawing style, isometric perspective, warm rust and copper tones.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/186519162?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A steampunk brass-and-copper machine with spinning gears, pipes, and billowing steam. A mechanical arm with a fountain pen writes onto paper rolling out. Tax forms and bank statements feed into a funnel at the top. An engineer in a NASA cap and rust-brown hoodie stands to the side, arms folded, observing the machine work. Illustrated as hand-drawn watercolor with sketch elements and architectural drawing style, isometric perspective, warm rust and copper tones." title="A steampunk brass-and-copper machine with spinning gears, pipes, and billowing steam. A mechanical arm with a fountain pen writes onto paper rolling out. Tax forms and bank statements feed into a funnel at the top. An engineer in a NASA cap and rust-brown hoodie stands to the side, arms folded, observing the machine work. Illustrated as hand-drawn watercolor with sketch elements and architectural drawing style, isometric perspective, warm rust and copper tones." srcset="https://substackcdn.com/image/fetch/$s_!X1NV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!X1NV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!X1NV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!X1NV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e4fa7e9-97a2-4bf6-a1b1-d58425fb073f_2400x1792.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Claude Code and Playwright MCP working together to automate complex form-filling&#8212;turning weeks of manual work into hours of AI-assisted automation</figcaption></figure></div><p>This year, I used Claude Code to fill my tax return.</p><p>I know. Taxes. How is that relevant to Software engineering. Bear with me.</p><p>This article isn&#8217;t really about taxes. Taxes are just the problem that pushed me to discover something much bigger.</p><p>The real story is about connecting tools in ways you didn&#8217;t expect. About turning a painful, weeks-long process into a few hours of work.</p><p>If you&#8217;re a software engineer, this matters to you. Not because of taxes. Because this pattern works for anything that happens in a browser. Batch-fill job applications. Automate web scraping. Test web applications. Scrape data at scale. Whatever repetitive browser work is eating your time, this unlocks it.</p><p>No AI browser was harmed in this process. Instead, I used <a href="https://github.com/microsoft/playwright-mcp">Playwright MCP</a> to give Claude Code direct control over my browser.</p><p>The tax return was just the catalyst. The real pattern is much bigger.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>The Problem: Why Tax Returns Feel Impossible</strong></h2><p>Every January, I spend weeks filling out HMRC forms. Hundreds of questions. Complex income streams from stocks, side projects, and savings. The math is easy. The form is not.</p><p>I looked up accountants. Some were expensive, some might have actually helped, but it felt like overkill for someone who could probably figure this out themselves.</p><p>I tried tax software next.</p><p>But here&#8217;s the thing: most UK people don&#8217;t need to fill tax returns at all. If you work for a single employer, the system handles it for you.</p><p>Tax software is designed for the majority, not for someone like me with multiple income streams. I had stocks from my previous company, side income from mentoring, Substack revenue, sand avings interest.</p><p>My situation was slightly more complicated than most, but it didn&#8217;t fit the simple templates tax software was built for.</p><p>Last year, I got <a href="https://claude.com/claude-code">Claude Code</a> to write Python code to calculate my total income, handle capital gains, all of it. That worked great.</p><p>But here&#8217;s the thing. The math was only 5% of the problem.</p><p>The other 95% was filling out the actual form. Understanding what each question meant. Figuring out which questions applied to my situation. Typing the right answers in the right boxes. That&#8217;s where I was losing weeks every year.</p><h2><strong>The Solution: Playwright MCP</strong></h2><h3><strong>Why AI Browsers Failed</strong></h3><p>I wanted Claude to actually read the form. See the questions in context, understand what each box was asking for. I tried Claude&#8217;s Chrome extension. Seemed perfect at first. Claude looking at my browser, helping me fill forms.</p><p>One problem. It only supported the older Haiku model. I&#8217;ve been using Opus, which is way smarter.</p><p>I looked at other AI browsers like <a href="https://www.perplexity.ai/comet">Comet by Perplexity</a> and others. Same issue. They locked me into weaker models. No Opus. No choice.</p><p>But there was a bigger problem I didn&#8217;t see at first.</p><p>These AI browsers had no access to my local data. My income calculations. My savings files. My bank statements. They could only see the form itself. That meant I had to manually copy-paste my data, which defeated the whole purpose of automation.</p><h3><strong>How Playwright MCP Works</strong></h3><p>Then I realised the approach was backwards.</p><p>Instead of bringing Claude Code into the browser, I needed to bring the browser to Claude Code. That meant finding a way for Claude to control my browser through proper automation, not through a limited Chrome extension.</p><p>I looked it up and found it. <a href="https://github.com/microsoft/playwright-mcp">Playwright MCP</a>. MCP stands for <a href="https://modelcontextprotocol.io/">Model Context Protocol</a>, Anthropic&#8217;s way of letting Claude access external tools. There&#8217;s a Playwright MCP that bridges Claude and Playwright together.</p><p>The setup is straightforward. Install the tool, add configuration to your <a href="https://claude.com/claude-code">Claude Code</a> config file, tell it where Playwright is, and you&#8217;re done.</p><p>Suddenly Claude could see your browser, read the content, fill form fields, navigate pages, take screenshots. No copy-pasting. Claude actually looks at the form and fills it.</p><p>But the real magic? You keep access to everything on your machine. Your local files. Your income data. Your calculations. And you&#8217;re not locked into a weaker model. You can use Opus for complex reasoning. Switch to Haiku for fast form filling. You&#8217;ve got options.</p><p>That&#8217;s the difference. AI browsers give you sight into the form. Playwright MCP gives you full context plus full control.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/pay-your-taxes-with-claude-code?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/pay-your-taxes-with-claude-code?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/pay-your-taxes-with-claude-code?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h3><strong>In Practice: My Tax Return</strong></h3><p>This year I tested it on my tax return and the difference was night and day.</p><p>I went from spending weeks wrestling with forms to just a few hours, spread over a couple of days.</p><p>Here&#8217;s what actually happened. I asked Claude to navigate to the HMRC form, read each question, and fill in my answers based on my income data. Claude could see the form. It could read what each field was asking for. And because I had all my calculations locally, Claude had full context.</p><p>The best part wasn&#8217;t even the automation.</p><p>It was the conversations. Because Claude had access to every question on the form, I could ask it to explain things. Why does this field matter? Does this apply to my situation? It was like having a private accountant sitting next to me. One that costs nothing beyond a Claude Pro subscription. Not even Max. Just Pro.</p><h2><strong>Voice + Browser Automation: Combining Tools for Power</strong></h2><p>Do you want to know the best part of this experience?</p><p>Actually, while I was filling my taxes this way, I was also using my voice to ask Claude questions.</p><p>No typing. Just speaking. &#8220;Claude, why does this field matter? What does this mean?&#8221; All while Playwright was filling forms in the background. That&#8217;s when I realized how powerful combining these tools really is.</p><p>If you&#8217;re interested in learning how I stopped typing most of my AI prompts, check out my article at <a href="https://cloudnativeengineer.substack.com/p/ultimate-vibe-coding">Talk to your AI agent: the ultimate vibe coding</a>.</p><h2><strong>What You Can Do With This Pattern</strong></h2><p>I built my tax filling learnings into a reusable Claude Code skill I can trigger next financial year.</p><p>If you want to learn more about why Claude Code skills are a game changer, check out my article on <a href="https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats">Claude Agent Skills: Teaching Your AI Agent to Wear Multiple Hats</a>.</p><p>But taxes were just the starting point. Think about what&#8217;s happening in your business. Where do people spend weeks filling out forms? Job applications. Expense reports. Data migration. Customer onboarding. Any repetitive web task that requires human judgment.</p><p>Now you have a tool for it. Claude Code plus Playwright MCP. Web scraping. Batch form filling. Testing. Data automation. Anything that happens in a browser.</p><p>You get full automation with human reasoning. Full access to your local context and data. And you&#8217;re not locked into a weaker model. You can use whatever Claude model makes sense for the task.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Conclusion</strong></h2><p>That&#8217;s the pattern. Voice. Browser automation. Local files. Three tools that weren&#8217;t designed to work together, now solving problems that seemed impossible.</p><p>Innovation isn&#8217;t about writing code anymore. It&#8217;s about connecting existing tools creatively. Playwright MCP proved that to me. A library I&#8217;ve used for years, suddenly powerful when connected to Claude Code.</p><p>The tax return was just the catalyst. This pattern works for anything that happens in a browser. Web scraping. Form filling. Job applications. Data automation.</p><p>What creative tool combinations have you found? What problem have you solved by wiring two things together that weren&#8217;t meant to work?</p><p>Drop a comment or reach out on LinkedIn. I&#8217;d love to hear what you&#8217;re building.</p><div><hr></div><h2><strong>References</strong></h2><ul><li><p><a href="https://claude.com/claude-code">Claude Code</a> - Anthropic&#8217;s official CLI for Claude with integrated tool access</p></li><li><p><a href="https://github.com/microsoft/playwright-mcp">Playwright MCP</a> - Model Context Protocol server that bridges Claude Code to Playwright browser automation</p></li><li><p><a href="https://modelcontextprotocol.io/">Model Context Protocol (MCP)</a> - Open protocol for connecting Claude to external tools and data sources</p></li><li><p><a href="https://playwright.dev/">Playwright</a> - Cross-browser automation library for web testing and form automation</p></li><li><p><a href="https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats">Claude Agent Skills: Teaching Your AI Agent to Wear Multiple Hats</a> - How to build reusable Claude Code skills and why they&#8217;re transformative for automation</p></li><li><p><a href="https://cloudnativeengineer.substack.com/p/ultimate-vibe-coding">Talk to your AI agent: the ultimate vibe coding</a> - How voice-to-text unlocks a faster, smarter way to work with AI through natural conversation</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Talk to your AI agent: the ultimate vibe coding]]></title><description><![CDATA[Episode #46: How voice-to-text unlocks a faster, smarter way to work with AI]]></description><link>https://cloudnativeengineer.substack.com/p/ultimate-vibe-coding</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/ultimate-vibe-coding</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Mon, 15 Dec 2025 09:03:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qCWD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qCWD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qCWD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qCWD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qCWD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qCWD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qCWD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7165110,&quot;alt&quot;:&quot;A software engineer in a NASA cap and rust-brown hoodie leaning intimately close to a small desk microphone, whispering with hands raised in the air. The laptop screen displays text and solutions being generated in real-time from his whispered voice&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/181628067?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A software engineer in a NASA cap and rust-brown hoodie leaning intimately close to a small desk microphone, whispering with hands raised in the air. The laptop screen displays text and solutions being generated in real-time from his whispered voice" title="A software engineer in a NASA cap and rust-brown hoodie leaning intimately close to a small desk microphone, whispering with hands raised in the air. The laptop screen displays text and solutions being generated in real-time from his whispered voice" srcset="https://substackcdn.com/image/fetch/$s_!qCWD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qCWD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qCWD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qCWD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4182d0f7-5130-4b58-881f-33535237cc5a_2400x1792.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Engineer collaborating hands-free with AI by whispering prompts&#8212;watching solutions materialize in real-time without touching the keyboard.</figcaption></figure></div><p>When you are too lazy to type your prompts, use your voice instead.</p><p>Jokes aside, you don&#8217;t have to be lazy to benefit from this article. You just need to be smart enough to recognise that even seemingly silly suggestions, like using your voice instead of typing, can make a massive difference in your career over time. These things compound.</p><p>Once you realise you can speak to your agent instead of typing, regular typing feels like you&#8217;ve been using only 10% of your brain.</p><p>Why does voice work so well for vibe coding?</p><p>Because you&#8217;re not dictating code. Typing code requires precision&#8212;brackets, punctuation, indentation, whitespace&#8212;all the things your voice struggles to convey.</p><p>But speaking conversational prompts to an AI agent that&#8217;s designed to handle imperfect input? That&#8217;s a completely different game. The agent filters out your &#8220;umms&#8221; and pauses. It corrects your spelling. It catches the meaning of what you&#8217;re saying even when you&#8217;re rambling or going into too much detail.</p><p>In this article, I&#8217;ll share a personal story that connects you to my grandfather 30 years ago. I&#8217;ll show you why small daily improvements compound into real career gains. And I&#8217;ll give you the exact setup that works, even in a noisy office.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Beyond AI interaction</strong></h2><p>Voice-to-text isn&#8217;t just for vibe coding either.</p><p>I voice-typed notes for this article in about half an hour. Normally, writing those notes down by typing would&#8217;ve easily taken me a couple of hours. That&#8217;s not a small difference.</p><p>The reason? When you use your voice, your thoughts flow naturally. You&#8217;re not slowed down by your fingers trying to keep up with your brain. And that matters more than you&#8217;d think. Because the moment you slow down, you lose momentum. You lose your train of thought. You start second-guessing yourself instead of just getting the ideas out.</p><p>With voice, you just... talk. The ideas stay fresh. The momentum keeps going.</p><p>And here&#8217;s the real magic: you&#8217;re not staring at a blank page anymore. You&#8217;ve got rough notes to work with. Something tangible to mould into a full article.</p><p>It takes some practice, but once you&#8217;ve done it for a while, it feels like talking to a colleague.</p><p>You&#8217;d be surprised how much you can accomplish just by whispering to your AI agent.</p><div><hr></div><h2><strong>Personal story: Full circle after 30 years</strong></h2><p>I remember my grandad in 1997 (when I was 13 and he was 69). He was looking up articles on <a href="https://en.wikipedia.org/wiki/Encarta">Encarta Enciclopedia</a>, burning CDs with <a href="https://en.wikipedia.org/wiki/Nero_Burning_ROM">Nero Burning ROM</a>, and reading passages aloud from Pinocchio to train <a href="https://en.wikipedia.org/wiki/Dragon_NaturallySpeaking">Dragon NaturallySpeaking</a> to understand his voice so he could dictate text to his computer.</p><p>I&#8217;m sharing this because I'm using AI to convert my speech to text. Just like my grandfather did more than 30 years ago.</p><p>No time seems to have passed, except that now I use my voice to interact with an AI that actually understands me.</p><div><hr></div><h2><strong>Small improvements compound: Typing with 10 fingers</strong></h2><p>I learned to touch-type more than 15 years ago.</p><p>When someone at the university suggested that using all ten fingers was a must.</p><p>How would that actually make me a better engineer?</p><p>I thought about it, decided it was worth a shot, and started training. Honestly, it took me probably a couple of months to get it right. It was <em>boring</em>. There was a program that asked me to type the same letter combinations repeatedly. It seemed pointless.</p><p>But you know what? It paid massive dividends over time.</p><div><hr></div><h2><strong>The same lesson: Typing with no fingers</strong></h2><p>A month ago, a colleague suggested I use my voice to type text into my laptop. My first thought?</p><blockquote><p>That&#8217;s silly. It&#8217;ll be slow. It&#8217;ll be uncomfortable. I&#8217;ll feel awkward talking to my laptop at work.</p></blockquote><p>Plus, I was already quite fast at typing. Why would I need this?</p><p>Then I saw the same colleague using voice-to-text at his desk.</p><p>Something clicked.</p><p>It was the same feeling I had when someone first suggested touch-typing. I realized it was worth the time investment to give it a genuine try.</p><div><hr></div><h2><strong>The 1% better every day principle</strong></h2><p>Both touch-typing and voice-to-text are perfect examples of how getting 1% better every day compounds into real change.</p><p>This reminds me of the book <a href="https://jamesclear.com/atomic-habits">Atomic Habits by James Clear</a>.</p><p>I have a terrible memory, so I rarely remember passages from books, but one specific story from it stuck with me: the UK cycling team.</p><p>They were really struggling until they changed coaches. The new coach implemented a radical strategy: improve everything by 1% every single day. They didn&#8217;t focus on massive changes. Instead, they worked on tiny things. Better tyre grips. Washing hands to avoid the flu. Hundreds of small improvements that individually seemed pointless.</p><p>Together? They compounded into something massive. That cycling team went from underperforming to consistently winning gold medals at the Olympics.</p><p>If you want to dive deeper into this concept, James Clear (author of Atomic Habits) has a great breakdown on <a href="https://jamesclear.com/marginal-gains">marginal gains</a>.</p><p>I think about this principle all the time.</p><p>Using voice-to-text or mastering touch-typing, these are the kinds of silly things you can do that have massive effects over 5, 10, or 15 years.</p><p>Every mentorship session I have now, I tell people: find that 1%.</p><p>What makes you 1% better every day?</p><p>It could be voice-to-text, touch-typing, or something completely different. But get better every day.</p><div><hr></div><h2><strong>My voice-to-text setup</strong></h2><p>I was sceptical about using a microphone at work. Our office is shared with hundreds of others and has background noise from the heating units. But honestly? It works really well.</p><p>I can whisper into my microphone (positioned right in front of me), and it captures everything. I don&#8217;t have to shout or bother my colleagues. I just whisper, and it works.</p><p>I&#8217;m using an app called <a href="https://goodsnooze.gumroad.com/l/macwhisper">MacWhisper</a> (available on Gumroad). Here&#8217;s how it works:</p><p>The app runs in the background. When you press a specific key combination, it captures your speech and converts it to text using a speech-to-text model running locally on your machine. You can choose from different models depending on your needs and hardware. I&#8217;m using &#8220;Large Turbo v3&#8221; on my M1 MacBook, but you have a range of model options.</p><p>After the initial transcription, there&#8217;s an optional second step where you can customise the text cleanup. You can use another model (either running locally in <a href="https://ollama.ai/">Ollama</a> or through an online AI service) to refine your dictation. You can customise the prompt to handle tasks such as removing pauses, correcting spelling, or restructuring your text.</p><p>MacWhisper already provides some cleanup prompts, but you can customise them. If you always mispronounce a word, add it to the prompt. If you need specific spelling corrections, add instructions. I honestly haven&#8217;t explored 10% of this app&#8217;s features yet, but what I&#8217;ve seen convinced me to upgrade from the free version to the paid version for access to additional features.</p><p>MacWhisper isn&#8217;t the only option. <a href="https://wisprflow.ai/">Flow</a> is more famous, but it&#8217;s subscription-based. Since I&#8217;m already overwhelmed with subscriptions, I prefer MacWhisper&#8217;s one-time purchase model with a lifetime license.</p><h2><strong>Why this matters: It started with my manager</strong></h2><p>I need to credit my manager at Loveholidays for introducing me to MacWhisper. He was using it at his desk, which inspired me to try it. Since then, I&#8217;ve invested in a professional podcaster microphone for home and set up the same system at work.</p><p>Now we both sit at our desks facing each other, both whispering into our laptops. A couple of colleagues have asked about my setup and how I&#8217;m using voice to interact with AI. That&#8217;s the main reason I&#8217;m writing this article. I wanted to share what I&#8217;ve learned.</p><p>Thank you to my manager for introducing me to voice-to-text, and to my curious colleagues for pushing me to document this.</p><div><hr></div><h2><strong>Conclusion</strong></h2><p>This article is about recognising that small improvements compound. Find your 1%. It could be voice-to-text, touch-typing, or something completely different. But once you commit to getting 1% better every day, you&#8217;re in the same league as that UK cycling team that went from struggling to winning gold medals.</p><p>The best part? Once you&#8217;ve done it for a while, it feels as natural as talking to a colleague. You&#8217;ll wonder how you ever lived without it.</p><p>If you&#8217;re interested in trying this, start small. Whisper one prompt to your AI agent today. Better yet, tell someone about what you&#8217;re learning. My boss showed me. My colleagues asked me questions. That&#8217;s how these things spread.</p><p>What&#8217;s your 1%? What small thing could you do every day that would compound into something massive over 5, 10, or 15 years?</p><p>Drop a comment or reach out on LinkedIn.</p><p>I&#8217;m genuinely curious what you&#8217;re working on.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>References</strong></h2><ul><li><p><a href="https://jamesclear.com/atomic-habits">Atomic Habits: Tiny Changes, Remarkable Results by James Clear</a> - The foundational book on how small daily improvements compound into remarkable results</p></li><li><p><a href="https://jamesclear.com/marginal-gains">Marginal Gains: The Coach Who Improved Every Tiny Thing by 1 Percent</a> - James Clear&#8217;s article on the UK cycling team&#8217;s success through incremental improvements</p></li><li><p><a href="https://goodsnooze.gumroad.com/l/macwhisper">Mac Whisper</a> - Speech-to-text application for macOS with local Whisper V3 Turbo model and customizable post-processing</p></li><li><p><a href="https://wisprflow.ai/">Flow by Wispr</a> - Alternative voice-to-text application with subscription-based pricing</p></li><li><p><a href="https://ollama.ai/">Ollama</a> - Run large language models locally for text cleanup and post-processing</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Claude Agent Skills: Teaching Your AI Agent to Wear Multiple Hats]]></title><description><![CDATA[Episode #45: How to teach Claude specialized capabilities without bloating your prompts]]></description><link>https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 29 Nov 2025 20:24:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!o0ab!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!o0ab!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o0ab!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!o0ab!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!o0ab!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!o0ab!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!o0ab!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6388737,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/180267629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!o0ab!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!o0ab!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!o0ab!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!o0ab!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51787850-f564-4310-8910-86635b3ec5c8_2400x1792.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Skills are like professional hats. Each one gives your agent a specialised capability to wear when needed, without loading everything at once.</figcaption></figure></div><p>Here&#8217;s a situation you might recognise: You want an AI agent that can help you with both Kubernetes troubleshooting AND Python development. So you load it with docs for both. Add some guidelines for how to approach each. Throw in examples, templates, edge cases. Before you know it, your system prompt is thousands of tokens. It becomes a bloated mess that confuses more than it clarifies.</p><p>This is the fundamental problem with how we traditionally extend AI agents: <strong>prompt stuffing</strong>. We take everything the agent might ever need and cram it into system prompts or CLAUDE.md files. The result? Higher costs, slower inference, maintenance headaches, and an agent that struggles to apply the proper context at the right time.</p><p>Claude Agent Skills solves this by flipping the approach entirely. Instead of loading everything upfront, skills use <strong>progressive context loading</strong>: the agent gets just enough information to decide <em>if</em> it needs a skill, then loads only what&#8217;s relevant <em>when</em> it&#8217;s needed.</p><p>This article introduces Claude Agent Skills: what they are, how they work, and why they&#8217;re a game changer for anyone building with AI.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>How to Interact with Claude</strong></h2><p>Before diving into skills, let&#8217;s quickly map the landscape of ways to extend Claude:</p><p><strong>Slash Commands</strong> (<code>/commands</code>) are saved user prompts. They provide quick automation for tasks you run manually and are great for repetitive workflows you already know you need.</p><p><strong>Output Styles</strong> are saved system prompts that change how Claude formats responses and behaves.</p><p><strong>MCPs (Model Context Protocol)</strong> have been getting a lot of hype lately. Every company rushed to write them. But here&#8217;s the reality: MCPs are powerful but complex. Learn more at <a href="https://modelcontextprotocol.io/">modelcontextprotocol.io</a>.</p><p><strong>Claude Agent Skills</strong> are the focus of this article. They combine Markdown-based instructions with optional Python code, designed for complex workflows and automatic invocation.</p><div><hr></div><h2><strong>Claude Agent Skills: Wearing Different Hats</strong></h2><p>Imagine an agent as a person with multiple jobs. One day, they&#8217;re a system designer. Next, they&#8217;re a code reviewer. Then they&#8217;re a documentation specialist. A single Claude instance can do all of this. You need to teach it how, one skill at a time.</p><p>That&#8217;s what Claude Agent Skills do. They let you extend Claude with specialised capabilities without rebuilding the entire agent. To understand the deeper architecture and design patterns, read Anthropic&#8217;s <a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">Equipping Agents for the Real World with Agent Skills</a> article. It explains the reasoning behind how skills are structured.</p><h3><strong>The Structure of a Skill</strong></h3><p>A skill is surprisingly simple. It&#8217;s just a folder under <code>.claude/skills/</code> that contains:</p><ul><li><p>A <strong>SKILL.md</strong> file: Markdown-based instructions (required)</p></li><li><p>Optional <strong>reference files</strong>: Detailed guides, templates, examples</p></li><li><p>Optional <strong>Python code</strong>: Logic that executes when needed</p></li></ul><p>The reference files, docs, and code can be organised however you want, as long as they&#8217;re referenced in the SKILL.md. Claude will find them. For a deeper dive into the technical setup and how to manage skills in Claude Code, see the <a href="https://claude.com/claude-code">Claude Code Documentation</a>. That&#8217;s it.</p><p>A skill is just a folder with some Markdown and some optional Python code. You can copy the skill from one laptop to another, and it works. Move it from one project to another, and it works. No special installation, no dependencies to configure, no marketplace publishing required (though you can do that later).</p><p>Just a portable folder of instructions and code.</p><h3><strong>How Progressive Context Loading Works</strong></h3><p>This is where skills get powerful. Context loads in stages:</p><p><strong>Level 1 - Front Matter (Always Loaded)</strong><br>The description at the top of SKILL.md is always present in context. It&#8217;s short (usually one or two sentences) and answers the question: &#8220;Should I use this skill?&#8221; Claude reads this and decides if the task matches.</p><p><strong>Level 2 - SKILL.md Content (On-Demand)</strong><br>The full skill instructions load only when Claude decides they&#8217;re needed. The agent asks to confirm loading the skill before proceeding. If the task doesn&#8217;t match, the skill never loads.</p><p><strong>Level 3 - Reference Files (Selectively Loaded)</strong><br>Detailed guides, templates, and reference docs stay in separate files. They are referenced in SKILL.md and loaded only when required. Unless you explicitly need them, they don&#8217;t consume context.</p><p><strong>Level 4 - Source Code (Execute, Don&#8217;t Load)</strong><br>Python code executes in the background but isn&#8217;t loaded into the context. Claude sees only the input and output. Complex logic stays external, keeping your context clean.</p><p>The beauty of this design: the agent only carries the context it actually needs, when it needs it. No bloat. No distraction.</p><h3><strong>Why This Matters</strong></h3><p><strong>Code Execution</strong>: Unlike slash commands or output styles, skills can run Python code. This means complex workflows, calculations, and integrations happen outside the context window.</p><p><strong>Rich Documentation</strong>: Unlike basic prompts, skills can include detailed reference materials that load on demand.</p><div><hr></div><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/ai-agent-wear-multiple-hats?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Problems Addressed by Skills</strong></h2><p>Skills aren&#8217;t just technically clever. They solve real problems. Here&#8217;s what they fix:</p><p><strong>Problem A: Slash Command Fatigue</strong><br>With slash commands, you have to remember what <code>/analyse-code</code> does and when to use it. You&#8217;re responsible for invoking the correct command at the right time. Scale this to 10 commands, 20 commands, and you&#8217;re perpetually context-switching.</p><p>Skills flip this: Claude automatically invokes them when it recognises a matching task. You don&#8217;t need to remember anything.</p><div><hr></div><p><strong>Problem B: MCP Tool Memory Bloat</strong><br>MCPs are powerful, but they have a hidden cost. Every tool description from every installed MCP loads into context <em>all the time</em>. If you have 5 MCPs with 10 tools each, that&#8217;s 50 tool descriptions constantly taking up tokens, whether you need them or not. This bloats your context window and drives up costs.</p><p>Skills solve this through progressive loading. Only the brief front matter description loads initially. The full skill content loads on demand.</p><div><hr></div><p><strong>Problem C: CLAUDE.md Context Overload</strong><br>CLAUDE.md is great for repo-wide rules, but it breaks down at scale. You might have instructions for &#8220;How to bootstrap a Python project&#8221; that load every single time you interact with Claude, even when you&#8217;re writing Golang. In monorepos, different areas need different rules, but CLAUDE.md can&#8217;t distinguish between them. It gets bloated quickly.</p><p>Skills let you apply focused rules to specific tasks. Context appears only when necessary.</p><div><hr></div><p><strong>Problem D: Prompt Distribution Challenge</strong><br>How do you share a working prompt, workflow, or skill with your team? There&#8217;s no standard way. CLAUDE.md is repo-specific. Slash commands are personal. MCPs require publishing infrastructure.</p><p>Skills solve this through Claude Plugins, a Git-based marketplace. Build once, share everywhere.</p><h3><strong>Quick Comparison: When to Use What</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dQHX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dQHX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 424w, https://substackcdn.com/image/fetch/$s_!dQHX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 848w, https://substackcdn.com/image/fetch/$s_!dQHX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 1272w, https://substackcdn.com/image/fetch/$s_!dQHX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dQHX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png" width="1456" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:115983,&quot;alt&quot;:&quot;Feature comparison table showing capabilities of different Claude extension methods: Auto-invocation, Code execution, Rich documentation, Context bloat, Easy to share, and Multi-step workflows. Skills excel in auto-invocation, code execution, and context efficiency while remaining easy to share.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/180267629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Feature comparison table showing capabilities of different Claude extension methods: Auto-invocation, Code execution, Rich documentation, Context bloat, Easy to share, and Multi-step workflows. Skills excel in auto-invocation, code execution, and context efficiency while remaining easy to share." title="Feature comparison table showing capabilities of different Claude extension methods: Auto-invocation, Code execution, Rich documentation, Context bloat, Easy to share, and Multi-step workflows. Skills excel in auto-invocation, code execution, and context efficiency while remaining easy to share." srcset="https://substackcdn.com/image/fetch/$s_!dQHX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 424w, https://substackcdn.com/image/fetch/$s_!dQHX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 848w, https://substackcdn.com/image/fetch/$s_!dQHX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 1272w, https://substackcdn.com/image/fetch/$s_!dQHX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1e1fbb7-674d-4baa-a08b-984162a7d5c3_1748x576.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Comparison of Slash Commands, Output Styles, MCPs, CLAUDE.md, and Skills across key dimensions.</figcaption></figure></div><p><strong>In practice</strong>: I use slash commands for very short prompts I remember. Agent Skills are for complex workflows where I can also benefit from code execution and better context management.</p><div><hr></div><h2><strong>Learning to Build Skills</strong></h2><p>You don&#8217;t need to start from scratch. Anthropic built tools to help:</p><p><strong>The Skills Creator Skill</strong>: Anthropic&#8217;s own interactive skill-building tool. Find it at <a href="https://github.com/anthropics/skills">github.com/anthropics/skills</a>. That repo contains instructions for adding the Anthropic marketplace to your Claude Code instance. Once the marketplace is added, install the required plugins, then ask Claude to use the <code>skill-creator</code> skill to create a new skill. Claude will ask for confirmation to load that skill and then guide you through building your first skill interactively.</p><p><strong>Deep Dives</strong> (I won&#8217;t repeat what&#8217;s already well-documented):</p><ul><li><p><a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">Anthropic Engineering Blog: Equipping Agents for the Real World with Agent Skills</a> - The canonical explanation of what skills are and how to design them</p></li><li><p><a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices">Agent Skills Best Practices</a> - Comprehensive guide to building production-quality skills</p></li></ul><p>Read those for the deep technical guidance. This article introduces the concept.</p><div><hr></div><h2><strong>(Bonus point) Sharing Skills: Marketplaces and Plugins</strong></h2><p>Once you&#8217;ve built a skill, you can share it with the world through Claude Plugins. However, it&#8217;s entirely optional.</p><p>Remember: as explained earlier, a skill is just a folder. You can copy it from one project to another, from one laptop to another, and it works immediately. No special setup required. If that&#8217;s all you need, you&#8217;re done. Sharing is as simple as putting your skills folder in a Git repo and sending the link to your team.</p><p><strong>If you want broader distribution</strong>, Marketplaces and Plugins provide a discoverable way to share:</p><p>A <strong>Marketplace</strong> is just a public GitHub repository with a <code>.claude-plugin</code> folder containing a <code>marketplace.json</code> file. That&#8217;s it.</p><p>See an example here: <a href="https://github.com/anthropics/skills/blob/main/.claude-plugin/marketplace.json">github.com/anthropics/skills/.claude-plugin/marketplace.json</a></p><p>A <strong>Plugin</strong> is a container for one or more Claude Agent Skills. Group related skills together, publish the whole plugin, and others can discover it and add it to their Claude environment.</p><p>The key requirement: your GitHub repo must be public so others can add your marketplace.</p><p>Again, this is entirely optional. Most of the time, copying the skill folder is enough.</p><div><hr></div><h2><strong>Why This Matters (And Why I&#8217;m Excited)</strong></h2><p>I&#8217;ve been using Claude Agent Skills since they launched in mid-October, and they&#8217;ve been a genuine game changer.</p><p>They&#8217;ve fundamentally changed how I extend Claude&#8217;s capabilities. Instead of fighting with bloated prompts, I build focused skills with progressive context loading. Maintenance is easier. Sharing is easier. The agent is smarter about when to use what.</p><p>This is the first article about skills because I&#8217;ll reference them often in future articles. We&#8217;ll explore real-world use cases, including system design, code review, documentation generators, and more. This foundation matters: understanding <em>why</em> skills exist and <em>how</em> they work differently than everything else.</p><p>If you&#8217;re building AI agents or extending Claude for your team, invest time in learning Claude Agent skills. They&#8217;re worth it.</p><div><hr></div><h2><strong>Get in Touch</strong></h2><p>If you enjoy this content, please repost it, share it online, and give it a like. Substack is a place for everyone to learn from each other, so please let me know about your experience with Claude Skills, or share a link to an article about Claude Skills that you found helpful. I&#8217;ll make sure to read it.</p><p>Since I&#8217;ve already been using extensively Claude Agent Skills both at work and in my personal life, if you need some help with Claude Agent Skills, please feel free to reach out to me both on Substack or on my Mentorcruise profile page at <a href="https://mentors.to/gsantoro">https://mentors.to/gsantoro</a> where I provide paid mentorship to anyone interested in learning about AI, system design, cloud-native concepts, or anything that&#8217;s been discussed in this newsletter.</p><p>Since this is a free newsletter, all the content is accessible to everyone.</p><p>Mentorship is how I keep this newsletter up and running.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>References</strong></h2><ul><li><p><a href="https://github.com/anthropics/skills">Anthropic Skills Marketplace</a> - Open repository with Anthropic&#8217;s official skills and the Skills Creator tool</p></li><li><p><a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">Equipping Agents for the Real World with Agent Skills</a> - Anthropic Engineering blog explaining skill architecture and design patterns</p></li><li><p><a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices">Agent Skills Best Practices</a> - Official documentation on building production-quality skills</p></li><li><p><a href="https://claude.com/claude-code">Claude Code Documentation</a> - Claude&#8217;s official CLI tool for working with skills and agents</p></li><li><p><a href="https://modelcontextprotocol.io/">Model Context Protocol (MCP)</a> - Alternative approach to extending AI capabilities with tools</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Pinning GitHub Actions for Reproducibility and Security]]></title><description><![CDATA[Episode #44: Stop relying on mutable version tags. Lock your workflows to immutable commit SHAs for production-grade stability and security.]]></description><link>https://cloudnativeengineer.substack.com/p/github-actions-reproducibility-security</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/github-actions-reproducibility-security</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 22 Nov 2025 11:21:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!z23D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!z23D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!z23D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!z23D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!z23D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!z23D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!z23D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6848507,&quot;alt&quot;:&quot;An isometric illustration of a large pushpin piercing through a stack of colourful paper cards on a board, rendered in flat colours with a minimalist aesthetic. The visual metaphor represents how commit SHA pinning permanently locks GitHub Actions to specific, immutable code versions.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/179636432?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="An isometric illustration of a large pushpin piercing through a stack of colourful paper cards on a board, rendered in flat colours with a minimalist aesthetic. The visual metaphor represents how commit SHA pinning permanently locks GitHub Actions to specific, immutable code versions." title="An isometric illustration of a large pushpin piercing through a stack of colourful paper cards on a board, rendered in flat colours with a minimalist aesthetic. The visual metaphor represents how commit SHA pinning permanently locks GitHub Actions to specific, immutable code versions." srcset="https://substackcdn.com/image/fetch/$s_!z23D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!z23D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!z23D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!z23D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a55ee32-9a60-4d11-8ea7-3ca5494a9c9e_2400x1792.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Just a pushpin locks cards in place, commit SHAs lock your workflows to immutable versions that can never change</figcaption></figure></div><p><a href="https://docs.github.com/en/actions">GitHub Actions</a> are typically referenced by version tags (e.g., <code>actions/checkout@v5</code>), but version tags can be moved, force-pushed, or accidentally updated. For better reproducibility and security, you can pin actions to specific version SHAs (immutable references that never change).</p><p>This is the approach that tools like <a href="https://www.mend.io/renovate/">Renovate</a> (and <a href="https://docs.github.com/en/code-security/dependabot">Dependabot</a>) use behind the scenes to keep your dependencies secure and consistent. If you&#8217;re managing GitHub Actions dependencies at scale, Renovate remains the preferred way to automate version updates and SHA pinning. But understanding where these version SHAs come from and how they work is valuable in several ways:</p><ul><li><p><strong>Debug Renovate behaviour</strong>: If you&#8217;re wondering why Renovate is pinning to a specific SHA, or if it&#8217;s not updating when you expect, understanding the mechanics helps you troubleshoot.</p></li><li><p><strong>Implement the logic yourself</strong>: Sometimes you need custom logic for dependency management. Knowing how SHAs relate to version tags lets you build your own tooling.</p></li><li><p><strong>Understand the fundamentals</strong>: Version pinning is a core security and reproducibility practice. Understanding the why behind it makes you a more thoughtful infrastructure engineer.</p></li></ul><p><strong>Note</strong>: SHA pinning isn&#8217;t unique to GitHub Actions. The same principle appears everywhere in the infrastructure and dependency management world. Most programming languages use SHA hashes in <a href="https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json">lock files</a> (npm, pip, cargo, etc.) to pin transitive dependencies. Docker images are pinned to SHAs for the same reasons (security and reproducibility). Understanding this pattern at the GitHub Actions level helps you recognise and apply it across your entire stack.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>In the Quiet: Where I&#8217;ve Been</strong></h2><p>If you&#8217;ve been wondering why I went quiet back in February, I owe you an explanation.</p><p>Earlier this year, I left <a href="https://www.elastic.co/">Elastic</a> after three great years. I needed time to step back and recharge. I spent five months travelling, reconnecting with family in Italy, and just absorbing things at a slower pace. It gave me space to think clearly about what came next.</p><p>In July, I joined <a href="https://www.loveholidays.com/">Loveholidays</a> as a Senior Platform Engineer. Loveholidays is a UK-based travel booking platform that helps customers find and book holidays across Europe. The role was a significant shift: much heavier on the DevOps and infrastructure side. I had to quickly absorb Terraform, Grafana, Google Cloud, and a whole ecosystem of tools I&#8217;d never worked with deeply before. Those first months weren&#8217;t about writing; they were about listening, learning, and taking in everything I could. I was quietly observing patterns, asking questions, and building foundational knowledge.</p><p>There&#8217;s also the reality of life outside of work: I&#8217;m raising a two-year-old who&#8217;s in full toddler mode. Most weekends are spoken for, and writing demands the kind of mental space that wasn&#8217;t available.</p><p>But here we are at four months in, and something&#8217;s shifted. The fog is lifting. I&#8217;ve absorbed enough to start seeing clearly, and more importantly, I&#8217;ve been quietly accumulating ideas: real, concrete things I&#8217;ve learned about infrastructure, platform engineering, and cloud-native practices that I genuinely want to share.</p><p>So here I am, breaking the quiet. I&#8217;m back, and I have things to say.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/github-actions-reproducibility-security?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/github-actions-reproducibility-security?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/github-actions-reproducibility-security?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Why Pin to SHAs?</strong></h2><p>Version tags are convenient, but they&#8217;re mutable. A maintainer can re-release a tag, move it to a different commit, or even force-push to it. This means your workflow could run different code tomorrow than it did today without you changing anything.</p><p>Here&#8217;s the key insight: a version tag like <code>v5.0.1</code> is just a pointer to a specific commit. When you pin to the commit SHA that tag <em>currently</em> points to, you&#8217;re locking in that exact version. If the tag ever gets moved or re-released to point to a different commit, your workflow stays pinned to the original commit. You&#8217;re insulated from any future changes to that tag.</p><p>Commit SHAs are different. A 40-character SHA like <code>93cb6efe18208431cddfb8368fd83d5badbf9bfd</code> points to one specific commit, forever. It can never change, never be re-released, never be overwritten.</p><p>For production workflows and security-sensitive operations, this immutability is invaluable.</p><h2><strong>How to Find the SHA</strong></h2><h3><strong>Prerequisites</strong></h3><p>You&#8217;ll need:</p><ul><li><p><strong>GitHub CLI installed</strong>: </p></li></ul><p>https://cli.github.com/</p><ul><li><p><strong>Authenticated with GitHub</strong>: Run <code>gh auth login</code></p></li></ul><h3><strong>The Command</strong></h3><p>For any GitHub Action release, use the <a href="https://cli.github.com/">GitHub CLI</a> to get the commit SHA that the version tag currently points to:</p><pre><code><code>gh api repos/actions/checkout/commits/v5.0.1 --jq &#8216;.sha&#8217;
</code></code></pre><p>Replace <code>actions/checkout</code> and <code>v5.0.1</code> with your action and desired version. See the <a href="https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions">GitHub Actions documentation</a> for more details on security best practices.</p><p><strong>Result:</strong> You&#8217;ll get back a 40-character commit SHA like <code>93cb6efe18208431cddfb8368fd83d5badbf9bfd</code>. This is the commit that the <code>v5.0.1</code> tag is currently pointing to: your immutable lock.</p><p>That&#8217;s it. One command, one immutable reference.</p><h2><strong>Using SHAs in Your Workflow</strong></h2><p>Replace the version tag with the full commit SHA:</p><pre><code><code># Before: Version tag (can change)
- uses: actions/checkout@v5

# After: Immutable commit SHA with version comment for readability
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
</code></code></pre><p>It&#8217;s common practice to include a comment with the version tag (e.g., <code># v5.0.1</code>) next to the SHA. This gives human readers a quick reference to which version you&#8217;re pinned to, while the SHA itself provides the immutable guarantee. The comment doesn&#8217;t affect functionality, it&#8217;s purely for documentation and clarity in code review.</p><p>The behaviour is identical to the tag, but now you have a guarantee that the exact same code will run every single time.</p><h2><strong>The Benefits</strong></h2><p><strong>Immutability</strong><br>SHAs never move. Version tags can be re-released, updated, or accidentally modified. A SHA pin locks you to a specific point in git history forever.</p><p><strong>Security</strong><br>You can explicitly control which version of an action runs in your workflow. No surprises, no unexpected updates that could introduce bugs or vulnerabilities.</p><p><strong>Auditability</strong><br>When you audit your workflows, you know exactly which version of code ran. The 40-character SHA serves as an immutable audit trail.</p><p><strong>Reproducibility</strong><br>Your workflow behaves identically across runs and across time. This is critical for debugging, compliance, and understanding system behaviour.</p><h2><strong>When to Use This</strong></h2><p>Use commit SHAs for:</p><ul><li><p><strong>Production workflows</strong> where stability is critical and unexpected updates could break deployments</p></li><li><p><strong>Security-sensitive operations</strong> where you need complete control over dependency versions</p></li><li><p><strong>Compliance requirements</strong> that demand audit trails and version pinning</p></li></ul><p>For development workflows, version tags may be convenient enough. But for production, SHAs provide the security and predictability you need.</p><div><hr></div><p><strong>Ready to pin your actions?</strong> Start with your most critical workflows and expand from there. The small effort of pinning to SHAs pays dividends in reproducibility and peace of mind.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>References</strong></h2><ul><li><p><a href="https://docs.github.com/en/actions">GitHub Actions Documentation</a> - Official guide to GitHub Actions workflows, syntax, and capabilities.</p></li><li><p><a href="https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions">GitHub Actions Security Hardening Guide</a> - Best practices for securing GitHub Actions workflows, including SHA pinning recommendations.</p></li><li><p><a href="https://cli.github.com/">GitHub CLI</a> - Command-line tool for interacting with GitHub repositories and retrieving commit SHAs.</p></li><li><p><a href="https://docs.renovatebot.com/">Renovate Documentation</a> - Comprehensive guide to automating dependency updates and SHA pinning across your repositories.</p></li><li><p><a href="https://docs.github.com/en/code-security/dependabot">GitHub Dependabot Documentation</a> - GitHub&#8217;s native tool for dependency updates and security vulnerability alerts.</p></li><li><p><a href="https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest">Container Image Digests</a> - Guide to pinning Docker images using immutable digest SHAs.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Cloud Native Engineer - Table of contents - (Start here)]]></title><description><![CDATA[Table of contents split by category]]></description><link>https://cloudnativeengineer.substack.com/p/start-here</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/start-here</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Mon, 10 Feb 2025 13:29:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yFMm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yFMm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yFMm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!yFMm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!yFMm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!yFMm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yFMm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6380263,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yFMm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!yFMm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!yFMm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!yFMm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F926325cd-7dee-46e8-bb3f-ee75d7cf015c_2400x1792.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Cloud Native Engineer - Logo</figcaption></figure></div><p><br>Welcome to <strong>Cloud Native Engineer</strong>, where we explore the tools, patterns, and practices that power modern cloud-native systems.</p><h2><strong>Who This Is For</strong></h2><p>This newsletter is for software engineers, platform engineers, and DevOps practitioners who want to:</p><ul><li><p>Master Kubernetes and container orchestration</p></li><li><p>Design scalable systems that can grow with your users</p></li><li><p>Implement observability to understand what&#8217;s happening in production</p></li><li><p>Discover modern tools and DevOps practices that make your life easier</p></li></ul><p>Whether you&#8217;re preparing for the Certified Kubernetes Administrator (CKA) exam, designing your first microservices architecture, or optimizing your deployment pipeline, you&#8217;ll find practical, hands-on content here.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>About Me</strong></h2><p>I&#8217;m Giuseppe Santoro, a Platform Engineer at Loveholidays based in London, with over 12 years of experience in cloud infrastructure and platform engineering. I&#8217;ve worked with companies like Elastic and PlayStation, specializing in high-scale distributed systems, Kubernetes, and cloud-native technologies.</p><p>I hold a Certified Kubernetes Administrator (CKA) credential and focus on system design, DevOps practices, and making complex topics accessible.</p><p>My mission is to guide engineers through modern system design and cloud-native engineering with hands-on technical expertise and real-world industry insights.</p><p>Through this newsletter, I share lessons learned, tools I&#8217;ve discovered, and techniques that have made me more productive as an engineer.</p><h2><strong>Get In Touch</strong></h2><p>I offer one-on-one mentoring on system design, Kubernetes, and cloud-native architecture. Whether you&#8217;re preparing for system design interviews, building your startup&#8217;s infrastructure, or looking to optimize your cloud deployment, I&#8217;m here to help guide you through the challenges.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sIqV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sIqV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 424w, https://substackcdn.com/image/fetch/$s_!sIqV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 848w, https://substackcdn.com/image/fetch/$s_!sIqV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 1272w, https://substackcdn.com/image/fetch/$s_!sIqV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sIqV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png" width="232" height="124.28571428571429" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:840,&quot;resizeWidth&quot;:232,&quot;bytes&quot;:40955,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sIqV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 424w, https://substackcdn.com/image/fetch/$s_!sIqV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 848w, https://substackcdn.com/image/fetch/$s_!sIqV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 1272w, https://substackcdn.com/image/fetch/$s_!sIqV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F724fde50-e47d-4ad5-b93b-245aeb777b7f_840x450.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong><a href="https://mentors.to/gsantoro">Book a mentoring session &#8594;</a></strong></p><div><hr></div><h2><strong>Top Performing Articles (as 2025-11-30)</strong></h2><p>These are the most-read articles across the entire newsletter, handpicked based on views and reader engagement:</p><ol><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/ep-5-taskfile-a-modern-alternative">Taskfile: a modern alternative to Makefile</a></strong> (DevOps &amp; Tooling) - 13,404 views<br>Modern approach to task automation with Taskfile as a user-friendly alternative to Makefile.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/how-to-publish-a-post-with-the-linkedin">How to publish a post with the LinkedIn API</a></strong> (DevOps &amp; Tooling) - 3,407 views<br>Automate posting on LinkedIn by using their API. Learn about OAuth2.0 access tokens and Open Graph meta tags.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/fleet-on-eck">How to deploy Fleet and Elastic Agent on Elastic Cloud Kubernetes</a></strong> (Observability) - 1,505 views<br>Deploy Fleet and Elastic Agent on ECK for centralized management and access to 400+ Elastic integrations.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/ep-11-elasticsearch-development-environment">Dev environment with Elastic Cloud on Kubernetes (ECK)</a></strong> (Observability) - 1,490 views<br>Set up a scalable development environment for Elasticsearch using Elastic Cloud on Kubernetes.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/powerful-load-balancing-strategies-kubernetes">Powerful Load Balancing Strategies: Kubernetes Gateway API</a></strong> (System Design) - 1,293 views<br>From ClusterIP to Ingress and Gateway API. Discover the most common strategies to load balance services in Kubernetes with practical examples using Traefik and K3d.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/hot-reloading-in-kubernetes-with-tilt">Maximise Your Productivity: Harness Hot Reloading in Kubernetes</a></strong> (Kubernetes &amp; Containers) - 1,207 views<br>Accelerating Kubernetes development workflows with Tilt and hot reloading for near-instantaneous feedback loops.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/5-must-have-tools-for-kubernetes">From Zero to K8s Hero: 5 Must-Have Tools for Kubernetes</a></strong> (Kubernetes &amp; Containers) - 1,154 views<br>Essential tools for Kubernetes development and operations, from K9s terminal UI to advanced debugging with node-shell.</p></li><li><p><strong><a href="https://cloudnativeengineer.substack.com/p/enhancing-software-design-with-diagrams">Enhancing Software Design with Diagrams as Code</a></strong> (System Design) - 896 views<br>Create version-controlled, automated architecture diagrams using PlantUML, Mermaid, and Diagrams for AWS, Kubernetes, and system design.</p></li></ol><div><hr></div><h2><strong>Explore by Category</strong></h2><p>Navigate to content organized by topic:</p><h3><strong>Kubernetes &amp; Containers</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OdIu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OdIu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!OdIu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!OdIu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!OdIu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OdIu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8119138,&quot;alt&quot;:&quot;Developer workstation with multiple monitors displaying Kubernetes dashboard with colorful pod nodes, clusters, and resource allocation charts, terminal showing kubectl commands, and Docker containers illustrated as stacked shipping containers being orchestrated&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Developer workstation with multiple monitors displaying Kubernetes dashboard with colorful pod nodes, clusters, and resource allocation charts, terminal showing kubectl commands, and Docker containers illustrated as stacked shipping containers being orchestrated" title="Developer workstation with multiple monitors displaying Kubernetes dashboard with colorful pod nodes, clusters, and resource allocation charts, terminal showing kubectl commands, and Docker containers illustrated as stacked shipping containers being orchestrated" srcset="https://substackcdn.com/image/fetch/$s_!OdIu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!OdIu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!OdIu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!OdIu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c28149-1553-48dc-8c7f-827b73c2fcf8_2400x1792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Kubernetes architecture and container orchestration in action</figcaption></figure></div><p>Master container orchestration with practical guides, exam preparation, and advanced Kubernetes patterns. Learn everything from CKA exam strategies to production-ready deployment techniques.</p><p><strong><a href="https://cloudnativeengineer.substack.com/p/kubernetes-and-containers">Go to Kubernetes &amp; Containers &#8594;</a></strong></p><p></p><div><hr></div><h3><strong>System Design</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cH0L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cH0L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!cH0L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!cH0L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!cH0L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cH0L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6854803,&quot;alt&quot;:&quot;Software engineer standing on tall ladder in front of enormous whiteboard, confidently sketching sprawling system architecture diagram with boxes, arrows, and interconnected components representing databases, load balancers, and microservices, hand-drawn watercolor with isometric 3D perspective&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Software engineer standing on tall ladder in front of enormous whiteboard, confidently sketching sprawling system architecture diagram with boxes, arrows, and interconnected components representing databases, load balancers, and microservices, hand-drawn watercolor with isometric 3D perspective" title="Software engineer standing on tall ladder in front of enormous whiteboard, confidently sketching sprawling system architecture diagram with boxes, arrows, and interconnected components representing databases, load balancers, and microservices, hand-drawn watercolor with isometric 3D perspective" srcset="https://substackcdn.com/image/fetch/$s_!cH0L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!cH0L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!cH0L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!cH0L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4faa234b-e753-431c-8d08-ff98cd57a54b_2400x1792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">System architect confidently sketching complex architecture diagrams</figcaption></figure></div><p>Learn the principles and practices behind scalable, resilient systems. From understanding HTTP fundamentals to designing architectures that serve millions of users, these articles cover the architectural foundations of modern applications.</p><p><strong><a href="https://cloudnativeengineer.substack.com/p/system-design">Go to System Design &#8594;</a></strong></p><p></p><div><hr></div><h3><strong>Observability</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9UqN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9UqN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!9UqN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!9UqN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!9UqN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9UqN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:163410,&quot;alt&quot;:&quot;Worried SRE in gray-blue NASA baseball cap and rust-brown hoodie seated at enormous control console with hundreds of buttons, switches, and gauges, monitoring dashboards with intense focus, with scenic river landscape and log blockage visible through control room window, hand-drawn watercolor with isometric 3D perspective&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Worried SRE in gray-blue NASA baseball cap and rust-brown hoodie seated at enormous control console with hundreds of buttons, switches, and gauges, monitoring dashboards with intense focus, with scenic river landscape and log blockage visible through control room window, hand-drawn watercolor with isometric 3D perspective" title="Worried SRE in gray-blue NASA baseball cap and rust-brown hoodie seated at enormous control console with hundreds of buttons, switches, and gauges, monitoring dashboards with intense focus, with scenic river landscape and log blockage visible through control room window, hand-drawn watercolor with isometric 3D perspective" srcset="https://substackcdn.com/image/fetch/$s_!9UqN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!9UqN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!9UqN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!9UqN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bcd5b80-57e3-4da4-ba4e-88beb7c08f73_1024x1024.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">SRE monitoring critical systems in a nuclear-plant-style control room</figcaption></figure></div><p></p><p>Build systems where you can see what&#8217;s happening. Learn how to implement effective logging, structured logging, and log collection strategies to understand and troubleshoot your applications and infrastructure.</p><p><strong><a href="https://cloudnativeengineer.substack.com/p/observability">Go to Observability &#8594;</a></strong></p><p></p><div><hr></div><h3><strong>DevOps &amp; Tooling</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XuCD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XuCD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 424w, https://substackcdn.com/image/fetch/$s_!XuCD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 848w, https://substackcdn.com/image/fetch/$s_!XuCD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 1272w, https://substackcdn.com/image/fetch/$s_!XuCD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XuCD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png" width="1456" height="1014" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e874967d-7c90-4784-b582-526b4c108620_2241x1560.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1014,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6762904,&quot;alt&quot;:&quot;Engineer in gray-blue NASA baseball cap and rust-brown hoodie seated in front of a towering server rack, carefully sorting through cables with rows of similar racks stretching behind, hand-drawn watercolor with isometric 3D perspective&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Engineer in gray-blue NASA baseball cap and rust-brown hoodie seated in front of a towering server rack, carefully sorting through cables with rows of similar racks stretching behind, hand-drawn watercolor with isometric 3D perspective" title="Engineer in gray-blue NASA baseball cap and rust-brown hoodie seated in front of a towering server rack, carefully sorting through cables with rows of similar racks stretching behind, hand-drawn watercolor with isometric 3D perspective" srcset="https://substackcdn.com/image/fetch/$s_!XuCD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 424w, https://substackcdn.com/image/fetch/$s_!XuCD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 848w, https://substackcdn.com/image/fetch/$s_!XuCD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 1272w, https://substackcdn.com/image/fetch/$s_!XuCD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe874967d-7c90-4784-b582-526b4c108620_2241x1560.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Engineer problem-solving in a data center</figcaption></figure></div><p></p><p>Discover modern tools, automation practices, and development techniques that make your workflows more efficient. From command-line tools to infrastructure automation, learn how to work smarter.</p><p><strong><a href="https://cloudnativeengineer.substack.com/p/devops-tooling">Go to DevOps &amp; Tooling &#8594;</a></strong></p><p></p><div><hr></div><h3><strong>Community &amp; Milestones</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QR8B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QR8B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!QR8B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!QR8B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!QR8B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QR8B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png" width="1456" height="1087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97f76689-784d-4049-8125-795a702d92fd_2400x1792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1087,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5933228,&quot;alt&quot;:&quot;A vibrant scene of a diverse team celebrating together with confetti falling, fist bumps, and smiles around a desk with growth charts and milestone markers visible in the background&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://cloudnativeengineer.substack.com/i/156848456?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A vibrant scene of a diverse team celebrating together with confetti falling, fist bumps, and smiles around a desk with growth charts and milestone markers visible in the background" title="A vibrant scene of a diverse team celebrating together with confetti falling, fist bumps, and smiles around a desk with growth charts and milestone markers visible in the background" srcset="https://substackcdn.com/image/fetch/$s_!QR8B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 424w, https://substackcdn.com/image/fetch/$s_!QR8B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 848w, https://substackcdn.com/image/fetch/$s_!QR8B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 1272w, https://substackcdn.com/image/fetch/$s_!QR8B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97f76689-784d-4049-8125-795a702d92fd_2400x1792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Community celebration and milestone achievements in Cloud Native Engineer</figcaption></figure></div><p>Behind-the-scenes stories, wrap-ups, and milestone celebrations. These articles share the journey of building Cloud Native Engineer, lessons learned, and gratitude to the community.</p><p><strong><a href="https://cloudnativeengineer.substack.com/p/community-and-milestones">Go to Community &amp; Milestones &#8594;</a></strong></p>]]></content:encoded></item><item><title><![CDATA[UV Package Manager: Better Python Dependency Management]]></title><description><![CDATA[Episode #43: Forget about Pipx, virtualenv, Poetry, pyenv (and many more) and embrace UV, the ultimate tool for your Python projects.]]></description><link>https://cloudnativeengineer.substack.com/p/uv-python-package-manager</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/uv-python-package-manager</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sun, 09 Feb 2025 22:00:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!cqsy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cqsy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cqsy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!cqsy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!cqsy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!cqsy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cqsy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:121901,&quot;alt&quot;:&quot;A Python racing on an F1 car&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Python racing on an F1 car" title="A Python racing on an F1 car" srcset="https://substackcdn.com/image/fetch/$s_!cqsy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!cqsy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!cqsy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!cqsy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3067fa7f-2770-429b-b1e6-5fe48bfd9a19_1024x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A Python racing on an F1 car. Image created by Flux.1 Pro</figcaption></figure></div><p>A warm welcome to the 191 new subscribers who joined the Cloud Native Engineer newsletter in the last three weeks.</p><p>It's unbelievable how things can change with a single Substack note.</p><p>If you are new here and you don't know what I am talking about, feel free to read my story at <a href="https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything">A Thank You to my 1K Subscribers (And How Being Seen Changed Everything)</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;f63ec0c1-6cda-495a-b01e-78a9b49a247d&quot;,&quot;caption&quot;:&quot;Happy New Year!!!&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;A Thank You to my 1K Subscribers (And How Being Seen Changed Everything)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Substack, Mentor on Mentorcruise. https://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/566571eb-2189-42aa-be8a-a58ceb206470_1024x1024.webp&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-01-21T22:47:02.760Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:155377258,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:31,&quot;comment_count&quot;:13,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62c4afef-4ee5-4779-a6ad-e524b95acf4f_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><p>Are you a Python developer?</p><p>Are you frustrated with your development tools?</p><p>Have you ever wished there was a better way to handle dependencies in Python?</p><p>I have the answer you have been looking for.</p><p>I've been a Python developer for the last 10 years and have never been so excited about programming in Python.</p><p>Years of frustration are finally gone.</p><p>In this article, I will introduce you to <a href="https://docs.astral.sh/uv/">Uv</a>, the latest package manager revolutionising Python tooling.</p><p>This article is not meant to be an alternative to the UV documentation.</p><p>The documentation by Astral (the company behind UV) is excellent, and repeating it here would be a waste of your time and mine.</p><p>I aim to introduce this tool, compare it to the Python ecosystem, and explain how I use it daily.</p><p>The outline of this article is as follows:</p><ul><li><p>The story so far</p></li><li><p>UV adopts the industry's best practices</p></li><li><p>Why is UV better than other solutions?</p></li><li><p>How do I use UV in my development tools?</p></li><li><p>Bonus feature: Inline dependencies</p></li></ul><p>I have published a cheatsheet for UV on Gumroad at <a href="https://cloudnativeeng.gumroad.com/l/uv-package-manager">UV Python Package Manager - The Essential Cheatsheet</a>.</p><p>In a previous article, <a href="https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything">A Thank You to my 1K Subscribers (And How Being Seen Changed Everything)</a>, I have described my decision to remove my paywall from my newsletter and go completely free.</p><p>So, if after reading this article, you have enjoyed my content, please donate by buying a cheatsheet from <a href="https://cloudnativeeng.gumroad.com/">Gumroad</a>, donate via <a href="https://buymeacoffee.com/cloudnative_eng">Buy me a Coffee</a> or simply like and reshare this article so it can reach a broader audience.</p><p>Your donation will help keep this newsletter free for everyone.</p><p>Thank you for being so supportive.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/uv-python-package-manager?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/uv-python-package-manager?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/uv-python-package-manager?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div><hr></div><h2><strong>The story so far</strong></h2><p>I have written in a previous article <a href="https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix">Effortless Python Development with Nix</a> how I have already abandoned pipenv, pyenv and virtualenv in favour of a tool called Poetry.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;eaf567d6-dae9-4460-a564-b78c282d7fd7&quot;,&quot;caption&quot;:&quot;If you ask 100 developers how they set up their Python development environment, getting many different answers is not uncommon.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Effortless Python Development with Nix&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Substack, Mentor on Mentorcruise. https://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/566571eb-2189-42aa-be8a-a58ceb206470_1024x1024.webp&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-02-18T00:28:29.202Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d927bed-c1f3-45f1-9313-694f0383ba5a_990x994.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:141779798,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:3,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62c4afef-4ee5-4779-a6ad-e524b95acf4f_1024x1024.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>If you have never heard of any of those, do not worry. You don't have to learn them or even be aware of what they used to do.</p><p>Poetry was already a huge step forward in the history of Python development tools.</p><p>But there is now a better alternative.</p><p>A while ago, I wrote another article <a href="https://cloudnativeengineer.substack.com/p/goodbye-python-dependency-hell-with-pipx">Goodbye Dependency Headaches: Discover the Power of Pipx for Python Package Management</a> where I introduced pipx, a great tool that allows you to install each Python tool in an isolated virtual environment to avoid dependency conflicts.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;93865a7c-1a4e-4eb5-977c-1c7868849d96&quot;,&quot;caption&quot;:&quot;If you have been a Software Developer as long as I have (more than ten years now), you might have encountered dependency hell at some point in your career.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Goodbye Dependency Headaches: Discover the Power of Pipx for Python Package Management&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Substack, Mentor on Mentorcruise. https://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/566571eb-2189-42aa-be8a-a58ceb206470_1024x1024.webp&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-05-05T22:26:13.472Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/goodbye-python-dependency-hell-with-pipx&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:144344427,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62c4afef-4ee5-4779-a6ad-e524b95acf4f_1024x1024.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>UV combines the best characteristics of Poetry and Pipx in a single tool that is both fast and easy to use.</p><p>Speed and usability are usually at the top of my mind when I choose a tool to use.</p><div><hr></div><h2><strong>UV adopts the industry's best practices</strong></h2><p>From the official Astral website, you can read about <a href="https://docs.astral.sh/uv/">UV</a>:</p><blockquote><p>An extremely fast Python package and project manager written in Rust.</p><p>&#128640; A single tool to replace <code>pip</code>, <code>pip-tools</code>, <code>pipx</code>, <code>poetry</code>, <code>pyenv</code>, <code>twine</code>, <code>virtualenv</code>, and more.<br>&#9889;&#65039; <a href="https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md">10-100x faster</a> than <code>pip</code>.</p></blockquote><p>If you have ever written any Python code, you are already familiar with virtual environments.</p><p>If you haven't, you can learn about it from this great article <a href="https://realpython.com/python-virtual-environments-a-primer/">Python Virtual Environments: A Primer &#8211; Real Python</a>. If you read that article, bear in mind that with UV, you will have a much simpler way to create virtual environments than what is suggested there.</p><p>Each tool I have used in the past (aka pyenv, virtualenv, pipenv) has its own way of creating virtual environments. Some prefer creating them in a global fixed location; others prefer to make them close to your code.</p><p>The approach that UV follows is my favourite one.</p><p>UV creates a hidden directory called <code>.venv</code> in the same root folder where you have your Python code.</p><p>The benefits of this approach are many.</p><p>Keeping code and virtualenv next to each other makes development a lot easier when you have to activate the virtualenv from your shell or if you want to eliminate the entire project and the associated venv.</p><p>You will always know where the venv for your project is stored.</p><p>For managing dependencies, Uv adopts a lock file approach similar to Poetry.</p><p>There is a file called <code>pyproject.toml</code> where you add your dependency rules (greater than this version or lower than that version) and another file, <code>uv.lock</code>, where the dependencies are pinned to fixed versions.</p><p>This approach allows the developer to define their high-level dependencies in a human-friendly file and separate it from the file used by the machine to create reproducible environments.</p><p>Forget about <code>requirements.txt</code>; using a single file for humans and machines was never a great idea.</p><p>Uv is compatible with pip and requirements.txt, but you don't have to use those features. Those are there primarily for backward compatibility.</p><p>Finally, Uv adopts the same approach as Pipx for installing tools in isolated virtual environments.</p><p>Please have a read at <a href="https://cloudnativeengineer.substack.com/p/goodbye-python-dependency-hell-with-pipx">Goodbye Dependency Headaches: Discover the Power of Pipx for Python Package Management</a> for more information about Pipx and installing tools in Python.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Why is UV better than other solutions?</strong></h2><p>By now, you should have a good idea of how Uv adopts best practices from established tools and combines multiple tools into one (namely Pipx and Poetry, for me).</p><p>But what is the fuss about UV? Why is everyone using it?</p><p>UV is extremely fast compared to other solutions.</p><p>While speed is usually not at the top of your mind when you think about Python development tools, speed is very beneficial in many contexts.</p><p>Speed is a great benefit when you have to install dependencies many times a day for all your developers as part of a CI/CD pipeline. You might save lots of money each month in cloud costs by running faster pipelines and countless hours in development time.</p><p>Furthermore, UV uses a global caching mechanism that avoids storing the same dependency multiple times on the same machine. This can also have enormous implications for storage savings in a cloud scenario.</p><p>There are lots more UV features that make it a great solution.</p><p>I have barely scratched the surface of what you can do with UV, but I am already in love.</p><div><hr></div><h2><strong>How do I use UV in my development tools?</strong></h2><p>If you have read my article <a href="https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix">Effortless Python Development with Nix</a>, you might wonder by now how I am combining Nix with UV.</p><p>I discovered UV in the first place because I recently had an issue at work where Python installed by Nix would break when installing a specific dependency while compiling Python from the source code.</p><p>After looking around for a more straightforward setup, I discovered UV can not only be used to install dependencies but also to install Python itself.</p><p>Instead of compiling Python from source, as Nix does, Uv uses binaries from Astral for a quicker setup.</p><p>What if you combine UV with the Nix dependency manager for non-Python tools?</p><p>I have been using UV for anything about Python and Nix for everything else.</p><p>Furthermore, direnv integrates with UV to activate the virtual environment.</p><p>Instead of running the command <code>source .venv/bin/activate</code> every time I want to run a Python project, I now use the following two lines in my <code>.envrc</code>:</p><pre><code><code>layout python-venv
PATH_add .venv/bin</code></code></pre><p>The second command is particularly useful if Python is installed by Uv or other binaries are installed in your virtualenv. All those binaries will be available in your shell with no extra effort.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Bonus feature: Inline dependencies</strong></h2><p>There might be a case where you have a single Python file that you want to distribute as a tool to your colleagues.</p><p>I'm sure you would like to avoid publishing a package on <a href="https://pypi.org/">Pypi</a> or creating a docker image if it's just in the initial development.</p><p>UV provides an easier alternative to the previous two options, avoiding writing long instructions on creating virtualenvs and installing dependencies.</p><p>You can add <a href="https://peps.python.org/pep-0723/">inline dependencies</a> to your Python script like this.</p><pre><code><code>uv init --script example.py
uv add --script example.py 'requests&lt;3' 'rich'</code></code></pre><p>The content of your <code>example.py</code> will look like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vdSx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vdSx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 424w, https://substackcdn.com/image/fetch/$s_!vdSx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 848w, https://substackcdn.com/image/fetch/$s_!vdSx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 1272w, https://substackcdn.com/image/fetch/$s_!vdSx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vdSx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png" width="692" height="743" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:743,&quot;width&quot;:692,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104266,&quot;alt&quot;:&quot;Python script with inline dependencies&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Python script with inline dependencies" title="Python script with inline dependencies" srcset="https://substackcdn.com/image/fetch/$s_!vdSx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 424w, https://substackcdn.com/image/fetch/$s_!vdSx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 848w, https://substackcdn.com/image/fetch/$s_!vdSx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 1272w, https://substackcdn.com/image/fetch/$s_!vdSx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f0b9e8c-709c-4096-b02d-bfec933ef3d5_692x743.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Python script with inline dependencies</figcaption></figure></div><p>Finally, you can run this script using <code>uv run example.py</code>.</p><p>More information on how to use scripts is available at <a href="https://docs.astral.sh/uv/guides/scripts">Running scripts | uv</a>.</p><p>I only discovered this feature with UV, but it is also available in Pipx.</p>]]></content:encoded></item><item><title><![CDATA[A Thank You to my 1K Subscribers (And How Being Seen Changed Everything)]]></title><description><![CDATA[Episode #42: On passing a thousand subscribers and how I "went viral" (at least for my standards).]]></description><link>https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Tue, 21 Jan 2025 22:47:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_fVT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_fVT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_fVT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 424w, https://substackcdn.com/image/fetch/$s_!_fVT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 848w, https://substackcdn.com/image/fetch/$s_!_fVT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!_fVT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_fVT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png" width="1080" height="1080" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1080,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:889071,&quot;alt&quot;:&quot;Celebrating my first 1000 subscribers&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Celebrating my first 1000 subscribers" title="Celebrating my first 1000 subscribers" srcset="https://substackcdn.com/image/fetch/$s_!_fVT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 424w, https://substackcdn.com/image/fetch/$s_!_fVT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 848w, https://substackcdn.com/image/fetch/$s_!_fVT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!_fVT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a60fd67-d0f9-420d-babc-fc296c2ebd5f_1080x1080.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Celebrating my first 1000 subscribers</figcaption></figure></div><p>Happy New Year!!! </p><p>I know it's almost the end of January, and not even my first article of the year.</p><p>But, while I usually keep my article strictly technical, I wanted to try a different format this week.</p><p>First, I want to give a big WELCOME to almost 480 new subscribers who have joined this newsletter since last week.</p><p>I still can't believe that this is really happening.</p><p>It all started when I announced this paid newsletter was going free... but I'm getting ahead of myself. I will elaborate on the decision to remove any paywall for my content later.</p><p>This article will primarily focus on how we got here and what happened last week.</p><p>I'm going to post a follow-up article in a couple of days (or a week), where I'll discuss in more detail what the future of this newsletter looks like.</p><p>The outline of the article is the following:</p><ul><li><p>The Story so far: slow growth and mostly talking into the void</p></li></ul><ul><li><p>Last week's update: going viral with Substack Notes and boost sessions</p></li></ul><ul><li><p>Conclusion: what is the lesson learned</p></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>The story so far: slow growth and mostly talking into the void</strong></h2><p>I never really believed those stories of people reaching thousands of subscribers in a few months. I thought they might have just paid for ads or were just pure lies trying to attract new subscribers.</p><p>It didn't make sense to me.</p><p>My own experience was very different.</p><p>Slow growth and mostly talking into the void.</p><p>In my mind, I have always "blamed" my very narrow niche, but this is what I am interested in, and I won't change it for anything in this world.</p><p>I always thought I could make it a bit broader to attract a bigger audience, but I firmly believe that I would lose part of who I am in the process. So, no, thank you.</p><p>At the same time, when you spend enough time on Substack, you see wild success stories like <a href="https://blog.bytebytego.com/">ByteByteGo Newsletter by Alex Xu</a> and you think, one day that will be me.</p><p>Fair enough, he wrote two books, has a YouTube channel, and has an entire team of writers, marketers, and a considerable budget. You can't really think of competing with him. That still won't stop me from trying to get there either.</p><p>Anyway, I am diverging from my main focus.</p><p>The growth of my newsletter has always been top of my mind, but I have never really done much about it.</p><p>As every other creator here, I have read all the tips about Substack growth:</p><ul><li><p>Writing on Substack Notes daily</p></li><li><p>Writing consistently each week</p></li><li><p>and so on and on</p></li></ul><p>I always thought that my content would speak for me.</p><p>Even if I was never very consistent.</p><p>I was so wrong!!!</p><p>Consistency alone is nothing if nobody sees your content, no matter how good it is.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/how-being-seen-changed-everything?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div><hr></div><h2><strong>Last week's update: going Viral with Substack Notes</strong></h2><p>During Christmas, I had time to think about where I wanted to get my newsletter and what I was doing wrong.</p><p>I wasn't very happy about the current situation, even if I could consider myself lucky with 15 paid subscribers and almost 1000 free subscribers.</p><p>The thing about paid subscribers has always been that I felt the extra pressure of delivering very high quality. That meant taking many hours to write an article. Countless hours of research, coding, and testing were needed to get to the point where I really felt like an expert in the field before I could write about it.</p><p>My articles usually hit the limit of the email size, and I struggled to cut off bits of it.</p><p>Furthermore, while trying different strategies (like only putting a paywall 3 months after an article was published), I always felt that paywalling my content could reduce my engagement and visibility.</p><p>As many people have said before me, I was probably already in the top 20% of newsletter creators, given that most people give up after 6 months.</p><p>If I still had to do something drastic about growth or otherwise, I would have given up writing entirely.</p><p>A drastic change of direction. That's what I needed. I thought I'd do something that not so many people do.</p><p>So on January 15th 2025, I decided that I had enough of slow growth. I decided to remove any paywall from my newsletter and go free.</p><p>What is the worst that can happen, I thought!!! I could lose all my paid subscribers overnight, but at least I'll get that motivational boost to write shorter articles more often.</p><p>I might lose my reader's trust other than just the monthly revenue. But if I don't do something drastic now with 15 paid subscribers, I might never get out of this situation.</p><p>This was when I could average 3-7 daily free subscribers, but I struggled to reach 1000 subscribers.</p><p>My numbers were going up and down every day during the Christmas break.</p><p>So what did I do?</p><p>I created a note describing my decision and shared it in the "Wednesday Boost Session" chat by <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Claudia Faith&quot;,&quot;id&quot;:174269834,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f42775-8321-4161-96d1-ce8b1b2b78d7_400x400.png&quot;,&quot;uuid&quot;:&quot;0c9512a6-7c87-4502-a5c0-166d593c41ff&quot;}" data-component-name="MentionToDOM"></span>.</p><p>Best decision ever!!!</p><p>I think that my message really resonated with lots of readers since that Substack note alone has since then generated (in no particular order):</p><ul><li><p>new free subscribers: 320</p></li><li><p>clicks: 2740</p></li><li><p>new followers: 1</p></li><li><p>Shares: 20</p></li><li><p>likes: 229</p></li><li><p>comments: 29</p></li><li><p>restack: 4</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ys-7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ys-7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 424w, https://substackcdn.com/image/fetch/$s_!ys-7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 848w, https://substackcdn.com/image/fetch/$s_!ys-7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 1272w, https://substackcdn.com/image/fetch/$s_!ys-7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ys-7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png" width="906" height="892" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:892,&quot;width&quot;:906,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:89782,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ys-7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 424w, https://substackcdn.com/image/fetch/$s_!ys-7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 848w, https://substackcdn.com/image/fetch/$s_!ys-7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 1272w, https://substackcdn.com/image/fetch/$s_!ys-7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b7eee71-a5d1-4329-94d5-a6c2d15e0463_906x892.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Substack Notes can really bring you subscribers</figcaption></figure></div><p></p><p>My free subscriber's chart went totally vertical, as you can see below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uTFC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uTFC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 424w, https://substackcdn.com/image/fetch/$s_!uTFC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 848w, https://substackcdn.com/image/fetch/$s_!uTFC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 1272w, https://substackcdn.com/image/fetch/$s_!uTFC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uTFC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png" width="1456" height="682" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:682,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:59307,&quot;alt&quot;:&quot;Going viral on Substack&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Going viral on Substack" title="Going viral on Substack" srcset="https://substackcdn.com/image/fetch/$s_!uTFC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 424w, https://substackcdn.com/image/fetch/$s_!uTFC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 848w, https://substackcdn.com/image/fetch/$s_!uTFC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 1272w, https://substackcdn.com/image/fetch/$s_!uTFC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1d02cc3-3b9b-4990-9138-d64a56261546_1459x683.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Going viral on Substack</figcaption></figure></div><p>My current count of subscribers is:</p><ul><li><p>free subscribers: 1,476</p></li><li><p>paid subscribers: 15 (I haven't lost any yet)</p></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Conclusion</strong></h2><p>Of course, I had no idea that this would happen.</p><p>I had no expectations!!!</p><p>The best part of this newly found engagement is that I spent most of the weekend:</p><ul><li><p>chatting with many fellow creators</p></li><li><p>exchanging ideas about content</p></li><li><p>learning about their experience</p></li><li><p>creating multiple opportunities for further collaboration</p></li><li><p>learning about various different ways to monetise your free content</p></li></ul><p>My main realisation was... "That's why they call it social networks; you are supposed to talk to people, not just talk at them". &#128514;</p><p>So, what is the lesson here.</p><p>I meant to write this article not for bragging but as my personal life lesson that maybe might inspire new content creators to not give up on their journey.</p><p>Quality content is essential, but you will never get a sizeable audience if nobody sees your content.</p><p>In the next article, I'll discuss the future of this newsletter and what I plan to offer my paid subscribers to avoid loosing them.</p>]]></content:encoded></item><item><title><![CDATA[Powerful Load Balancing Strategies: Kubernetes Gateway API]]></title><description><![CDATA[Episode #41: From ClusterIP to Ingress and Gateway API. Discover the most common strategies to load balance services in Kubernetes.]]></description><link>https://cloudnativeengineer.substack.com/p/powerful-load-balancing-strategies-kubernetes</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/powerful-load-balancing-strategies-kubernetes</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Wed, 08 Jan 2025 23:59:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ocLT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ocLT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ocLT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ocLT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ocLT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ocLT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ocLT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:132137,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ocLT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ocLT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ocLT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ocLT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd934f7b0-2487-42ff-bb6c-485d02d542d7_1024x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Balancing two server racks on a huge scale. Image created with Flux.1 Pro</figcaption></figure></div><p>There are many ways to expose HTTP applications running in Kubernetes.</p><p>A typical setup involves creating a deployment and an associated service.</p><p>The type of Service decides the visibility of your application.</p><p>The most common types of <a href="https://kubernetes.io/docs/concepts/services-networking/service/">Kubernetes Services</a> are:</p><ul><li><p><code>ClusterIP</code>: default value (if no type is provided) that only exposes an application internally to other services in the same Kubernetes cluster.</p></li><li><p><code>NodePort</code>: primarily used for testing to expose a service externally at every cluster node at a chosen port.</p></li><li><p><code>LoadBalancer</code>: used for production use cases in the cloud to expose the service outside your cluster.</p></li></ul><p>This is it, right?</p><p>That's what I thought for a while since that is what I learned when I took the Certified Kubernetes Admin (aka CKA) exam more than two years ago.</p><p>In this article, we will briefly introduce CluterIP and LoadBalancer Service types and discuss the alternatives of <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Ingress</a> and <a href="https://kubernetes.io/docs/concepts/services-networking/gateway/">Gateway API</a>.</p><p>We will briefly discuss each option and its pros and cons and provide some code samples to get you started.</p><p>This article has the following sections:</p><ul><li><p>A small caveat</p></li><li><p>ClusterIP: exposing a service internally</p></li><li><p>LoadBalancer: exposing a service in the cloud</p></li><li><p>Ingress: a single gateway for all services</p></li><li><p>Gateway API: the modern alternative to Ingress</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Want to connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p><div><hr></div><h2><strong>A small caveat</strong></h2><p>The code samples in this article are working examples, even if just a toy application.</p><p>They are kept as simple as possible since there is a lot to cover, and we only want to focus on the load-balancing strategies.</p><p>We will use a container image called <a href="https://github.com/traefik/whoami">traefik/whoami</a> that returns the content of an HTTP request with all its headers and parameters as output.</p><p>This container image is used by the Reverse Proxy <a href="https://traefik.io/traefik/">Traefik</a> in their official documentation. Since Traefik is my Reverse Proxy of choice (since it comes as default in <a href="https://k3d.io/">K3d</a>), this is what we are going to use in this article.</p><p>Even if those code samples have been tested with K3d and Traefik, they should be working with any Kubernetes distribution or any Reverse Proxy.</p><p>More info on setting up those code samples is not part of this article. I'll write about it in the future.</p><p>This article doesn't mean to be an exhaustive tutorial to load balancers in Kubernetes. There would be too much to cover.</p><p>I would like to introduce you to the concepts so that you know those things exist in the first place.</p><p>I'll provide some external resources to keep the learning going.</p><div><hr></div><h2><strong>ClusterIP: exposing a service internally</strong></h2><p>The bare minimum to create and expose an HTTP application is to create a Kubernetes Deployment and an associated service.</p><p>Throughout the article, we will use the same Kubernetes Deployment, the code provided in the following image.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0HQ0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0HQ0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 424w, https://substackcdn.com/image/fetch/$s_!0HQ0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 848w, https://substackcdn.com/image/fetch/$s_!0HQ0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 1272w, https://substackcdn.com/image/fetch/$s_!0HQ0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0HQ0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png" width="634" height="944" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08902b49-c877-41ff-8b01-073c24f65665_634x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:944,&quot;width&quot;:634,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:134581,&quot;alt&quot;:&quot;A Kubernetes deployment with 3 replicas for the image `traefik/whoami`&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Kubernetes deployment with 3 replicas for the image `traefik/whoami`" title="A Kubernetes deployment with 3 replicas for the image `traefik/whoami`" srcset="https://substackcdn.com/image/fetch/$s_!0HQ0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 424w, https://substackcdn.com/image/fetch/$s_!0HQ0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 848w, https://substackcdn.com/image/fetch/$s_!0HQ0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 1272w, https://substackcdn.com/image/fetch/$s_!0HQ0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08902b49-c877-41ff-8b01-073c24f65665_634x944.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A Kubernetes deployment with 3 replicas for the image `traefik/whoami`</figcaption></figure></div><p>As discussed above, this is just a toy application that is useful for debugging HTTP network routing.</p><p>We will see what the output of this application looks like later in the section for Ingress.</p><p>Aside from the boilerplate code for a deployment, you should notice:</p><ul><li><p>we are creating three replicas of the same pod. This is so that when running the client, you will be returned a different internal IP for each pod responding.</p></li><li><p>The container port used by the application is configured by the environment variable <code>PORT</code> and then referenced by the <code>containerPort: 80</code></p></li><li><p>We will use the Kubernetes label <code>label: my-app</code> for deployment, service, and pods.</p></li></ul><p>Once you have a deployment, you can create an associated service with no type.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6NoZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6NoZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 424w, https://substackcdn.com/image/fetch/$s_!6NoZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 848w, https://substackcdn.com/image/fetch/$s_!6NoZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 1272w, https://substackcdn.com/image/fetch/$s_!6NoZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6NoZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png" width="457" height="621" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:621,&quot;width&quot;:457,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83330,&quot;alt&quot;:&quot;A Kubernetes service of type ClusterIP&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Kubernetes service of type ClusterIP" title="A Kubernetes service of type ClusterIP" srcset="https://substackcdn.com/image/fetch/$s_!6NoZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 424w, https://substackcdn.com/image/fetch/$s_!6NoZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 848w, https://substackcdn.com/image/fetch/$s_!6NoZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 1272w, https://substackcdn.com/image/fetch/$s_!6NoZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa921c9-4ce3-4b33-82bd-0b0828b58e0c_457x621.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A Kubernetes service of type ClusterIP</figcaption></figure></div><p>By default the type of the Service is <code>ClusterIP</code>, and the Service will only be accessible from other services and pods inside the same Kubernetes cluster.</p><p>There is not much to notice from this Service except that it exposes an HTTP application at port 80.</p><p>As per the above deployment, the Service above will be used (mostly as it is) in the following chapters.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/powerful-load-balancing-strategies-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/powerful-load-balancing-strategies-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/powerful-load-balancing-strategies-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div><hr></div><h2><strong>LoadBalancer: exposing a service in the cloud</strong></h2><p>As discussed at the beginning, if you want to expose a service externally to the internet for a production use case, you need to create a Service of type <code>LoadBalancer</code>.</p><p>The cloud provider where you are running your Kubernetes cluster will provide a Load balancer associated with this Service.</p><p>A different load balancer will be created for each Service you want to expose.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7X_0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7X_0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 424w, https://substackcdn.com/image/fetch/$s_!7X_0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 848w, https://substackcdn.com/image/fetch/$s_!7X_0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 1272w, https://substackcdn.com/image/fetch/$s_!7X_0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7X_0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png" width="449" height="655" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:655,&quot;width&quot;:449,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90813,&quot;alt&quot;:&quot; A Kubernetes service of type LoadBalancer&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt=" A Kubernetes service of type LoadBalancer" title=" A Kubernetes service of type LoadBalancer" srcset="https://substackcdn.com/image/fetch/$s_!7X_0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 424w, https://substackcdn.com/image/fetch/$s_!7X_0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 848w, https://substackcdn.com/image/fetch/$s_!7X_0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 1272w, https://substackcdn.com/image/fetch/$s_!7X_0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8be39df3-283f-4522-a2fd-c3edc2fbf8b2_449x655.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"> A Kubernetes service of type LoadBalancer</figcaption></figure></div><p>As you can notice, the only difference from the Service in the previous section is the type of Service in <code>spec.type = LoadBalancer</code>.</p><h3><strong>Pros and Cons</strong></h3><p>While this solution is straightforward, it starts to be a problem when you have many microservices and don't want to create a single Load balancer for each of those external services.</p><p>While this solution is perfect when running in the cloud, it doesn't work when running your Kubernetes cluster locally on your machine, for example, with K3d.</p><p>Suppose you, like me, firmly believe that a local Kubernetes cluster should be able to allow you to replicate a production use case. In that case, you are out of luck here.</p><p>Alternatively, you could use a Service Mesh provider like <a href="https://istio.io/">Istio</a>. Still, for simple use cases, there is a much simpler alternative.</p><div><hr></div><h2><strong>Ingress: a single gateway for all services</strong></h2><p>A while ago, Kubernetes decided that a good alternative to a single Load Balancer for each Service was to create a resource called <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Ingress</a> that would allow Reverse Proxies like Traefik or Nginx to create complex routing rules.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FXDB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FXDB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 424w, https://substackcdn.com/image/fetch/$s_!FXDB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 848w, https://substackcdn.com/image/fetch/$s_!FXDB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 1272w, https://substackcdn.com/image/fetch/$s_!FXDB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FXDB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png" width="553" height="733" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d13d022d-810c-4c52-9836-b967dc07cf73_553x733.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:733,&quot;width&quot;:553,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:102423,&quot;alt&quot;:&quot;A Kubernetes resource of type Ingress&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Kubernetes resource of type Ingress" title="A Kubernetes resource of type Ingress" srcset="https://substackcdn.com/image/fetch/$s_!FXDB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 424w, https://substackcdn.com/image/fetch/$s_!FXDB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 848w, https://substackcdn.com/image/fetch/$s_!FXDB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 1272w, https://substackcdn.com/image/fetch/$s_!FXDB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd13d022d-810c-4c52-9836-b967dc07cf73_553x733.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A Kubernetes resource of type Ingress</figcaption></figure></div><p>This Ingress resource points to the service definition that we defined in the section <code>ClusterIP: exposing a service internally</code> and the related deployment. For brevity, the code is not duplicated here.</p><p>To reach the Service from your laptop, you will have to run the following curl command:</p><pre><code><code>curl -H "Host: my-app.example" http://localhost:8080
</code></code></pre><p>As you might have noticed, <code>my-app.example</code> is the hostname defined in the Ingress resource at <code>spec.rules.host</code>.</p><p>As a reference, the output of the curl command is the following.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GAD5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GAD5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 424w, https://substackcdn.com/image/fetch/$s_!GAD5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 848w, https://substackcdn.com/image/fetch/$s_!GAD5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 1272w, https://substackcdn.com/image/fetch/$s_!GAD5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GAD5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png" width="676" height="737" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:737,&quot;width&quot;:676,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:132341,&quot;alt&quot;:&quot;Output from the container image `traefik/whoami`&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Output from the container image `traefik/whoami`" title="Output from the container image `traefik/whoami`" srcset="https://substackcdn.com/image/fetch/$s_!GAD5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 424w, https://substackcdn.com/image/fetch/$s_!GAD5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 848w, https://substackcdn.com/image/fetch/$s_!GAD5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 1272w, https://substackcdn.com/image/fetch/$s_!GAD5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3b93428-ccf0-411c-9895-f7c7dfe7d420_676x737.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Output from the container image `traefik/whoami`</figcaption></figure></div><p>The example provided in this section is officially called <code>Host-Based Routing (Virtual Hosting)</code> and it is only one of the many use cases for Ingress:</p><ul><li><p>Path-Based Routing</p></li><li><p>SSL/TLS Termination</p></li><li><p>Load Balancing and Traffic Management</p></li><li><p>Authentication and Access Control</p></li></ul><h3><strong>Pros and cons of using Ingress API</strong></h3><p>Between the pros of using Ingress:</p><ul><li><p>Well-established API supported by all major Reverse Proxies (e.g. Traefik, Nginx)</p></li><li><p>Works on a local Kubernetes cluster with K3d as well as in the cloud</p></li></ul><p>Between the cons:</p><ul><li><p>Only support L7 Load balancing. There is no support for L4 protocols like TCP and UDP</p></li><li><p>From the L7 network stack it only supports HTTP/S. It doesn't support GRPC. This might be inconvenient if you want to support microservices.</p></li><li><p>Ingress is not a standard API between all Reverse Proxies. There might be some differences in the spec and ways to implement some routing strategies.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Gateway API: the modern alternative to Ingress</strong></h2><p>The problem with <code>Ingress</code> is that most Reverse Proxies have their way of implementing those routing rules.</p><p>Each one of the Reverse Proxies would require the user to provide either a custom Kubernetes annotation, a custom middleware extension or some custom Kubernetes Custom Resources (CRDs).</p><p>This was the case until a new Kubernetes API was introduced called <a href="https://kubernetes.io/docs/concepts/services-networking/gateway/">Gateway API</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-6Do!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-6Do!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 424w, https://substackcdn.com/image/fetch/$s_!-6Do!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 848w, https://substackcdn.com/image/fetch/$s_!-6Do!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 1272w, https://substackcdn.com/image/fetch/$s_!-6Do!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-6Do!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png" width="627" height="709" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:709,&quot;width&quot;:627,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:115023,&quot;alt&quot;:&quot;A Kubernetes resource of type HTTPRoute from the Gateway API&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Kubernetes resource of type HTTPRoute from the Gateway API" title="A Kubernetes resource of type HTTPRoute from the Gateway API" srcset="https://substackcdn.com/image/fetch/$s_!-6Do!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 424w, https://substackcdn.com/image/fetch/$s_!-6Do!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 848w, https://substackcdn.com/image/fetch/$s_!-6Do!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 1272w, https://substackcdn.com/image/fetch/$s_!-6Do!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0789b02a-b9e1-417b-ae88-f9d04c9fb3e4_627x709.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A Kubernetes resource of type HTTPRoute from the Gateway API</figcaption></figure></div><p>As you can see from above, instead of an Ingress you can replicate the same outcome with a <code>HTTPRoute</code>.</p><p>In this scenario, you will be able to hit the backend service with a command like:</p><pre><code><code>curl -H "Host: load-balance.example" http://localhost:8080</code></code></pre><h3><strong>Pros and cons of Gateway API</strong></h3><p>Between the pros:</p><ul><li><p>Similar concept to Ingress. A single network endpoint for all services instead of a single load balancer per Service.</p></li><li><p>Support both L4 and L7 network protocols (eg. UDP, TCP, HTTP/S and GRPC).</p></li><li><p>Standard API across multiple Reverse Proxies (eg. Traefik, Nginx, etc).</p></li></ul><p>Between the cons:</p><ul><li><p>it is a much newer API, so not all features are implemented by all Reverse Proxies. As an example, for the complete list of features supported by the latest version of Traefik v3.2.2 visit <a href="https://github.com/kubernetes-sigs/gateway-api/blob/main/conformance/reports/v1.2.1/traefik-traefik/experimental-v3.2.2-default-report.yaml">gateway-api/conformance/reports/v1.2.1/traefik-traefik/experimental-v3.2.2-default-report.yaml at main &#183; kubernetes-sigs/gateway-api</a>.</p></li></ul><div><hr></div><h2><strong>Resources</strong></h2><ul><li><p><a href="https://community.traefik.io/t/getting-started-with-kubernetes-gateway-api-and-traefik/23601">Getting started with Kubernetes Gateway API and Traefik - Blog - Traefik Labs Community Forum</a></p></li><li><p><a href="https://konghq.com/blog/engineering/gateway-api-vs-ingress">Gateway API vs Ingress: The Future of Kubernetes Networking | Kong Inc.</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Steampipe: Query your cloud infrastructure with SQL for faster insights]]></title><description><![CDATA[Episode #40: SQL as a universal gateway to your cloud infrastructure and beyond.]]></description><link>https://cloudnativeengineer.substack.com/p/steampipe-query-your-cloud-infrastructure</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/steampipe-query-your-cloud-infrastructure</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 14 Dec 2024 23:10:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LFGO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LFGO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LFGO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LFGO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LFGO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LFGO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LFGO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:764134,&quot;alt&quot;:&quot;A steam-powered computer&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A steam-powered computer" title="A steam-powered computer" srcset="https://substackcdn.com/image/fetch/$s_!LFGO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LFGO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LFGO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LFGO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56878fd4-7f80-47ea-8c68-77e12f03a674_1024x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A steam-powered computer. Image generated with Flux1 Pro</figcaption></figure></div><p>In computer science, it is common to see programming languages emerge out of the blue every 5-10 years.</p><p>Every new language promises to improve your life for the better.</p><p>Keeping up to date as a software engineer is a challenging life.</p><p>I'm sure that engineers are still making a living by still programming in COBOL. For the rest of us, if you still want to be relevant and change jobs every 4-6 years, you need to learn the latest flavour of programming language.</p><p>However, if there is a single language that has yet to go out of fashion for over 50 years, that is SQL.</p><p>Over the years, many different flavours of databases and various SQL dialects have emerged, but at its core, SQL has stayed the same since it was created.</p><p>So, in my opinion, learning SQL is an excellent long-term investment for your career.</p><p>What if I tell you that you could use SQL to query the status of your cloud infrastructure?</p><p>Today, I would like to introduce you to <a href="https://steampipe.io/">Steampipe</a>, a tool I recently added to my arsenal of DevOps power tools.</p><p>Steampipe lets you query your cloud infrastructure and many other APIs (Twitter, GitHub, Kubernetes, to name a few) via a simple SQL interface.</p><p>This article has the following sections:</p><ul><li><p>What is Steampipe?</p></li><li><p>SQL to query everything: OSQuery and Cloudquery</p></li><li><p>How to query Hackernews via SQL</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Want to connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p><div><hr></div><h2><strong>What is Steampipe?</strong></h2><p>Steampipe is an innovative open-source project that allows users to query cloud services and APIs using SQL.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MFxH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MFxH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 424w, https://substackcdn.com/image/fetch/$s_!MFxH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 848w, https://substackcdn.com/image/fetch/$s_!MFxH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!MFxH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MFxH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png" width="1456" height="1040" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1040,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144381,&quot;alt&quot;:&quot;Star history the Steampipe project&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Star history the Steampipe project" title="Star history the Steampipe project" srcset="https://substackcdn.com/image/fetch/$s_!MFxH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 424w, https://substackcdn.com/image/fetch/$s_!MFxH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 848w, https://substackcdn.com/image/fetch/$s_!MFxH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!MFxH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25307038-e7ad-4770-bc29-49a54e8ceb78_1832x1308.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Star history of the Steampipe project</figcaption></figure></div><p>Between the main features of Steampipe, we can find:</p><ul><li><p>Wide Range of Plugins: Steampipe has an extensive library of plugins that support popular cloud services and data sources. Currently, you can count more than 140 plugins.</p></li><li><p>Zero-ETL Data Access: Steampipe provides Zero-ETL data access, allowing you to fetch data directly from cloud APIs without complex integrations.</p></li><li><p>Open-Source: Steampipe is an open-source tool that ensures data security and integrity and is free for developers.</p></li></ul><p>Notable Steampipe integrations are the following:</p><ul><li><p>all major cloud providers: <a href="https://hub.steampipe.io/plugins/turbot/aws">AWS</a>, <a href="https://hub.steampipe.io/plugins/turbot/gcp">GCP</a>, <a href="https://hub.steampipe.io/plugins/turbot/azure">Azure</a></p></li><li><p><a href="https://hub.steampipe.io/plugins/turbot/kubernetes">Kubernetes</a></p></li><li><p><a href="https://hub.steampipe.io/plugins/turbot/openai">OpenAI</a></p></li><li><p><a href="https://hub.steampipe.io/plugins/turbot/github">GitHub</a></p></li></ul><p>You can use Steampipe in different ways:</p><ul><li><p>Default CLI: a solution with its own PostgreSQL database and plugin management.</p></li><li><p>Postgres FDWs: native Postgres Foreign Data Wrappers that translate APIs to foreign tables.</p></li><li><p>SQLite extensions: virtual tables that translate your queries into API calls.</p></li><li><p>Export CLIs: each exporter is a stand-alone binary that extracts data from Steampipe without a database.</p></li></ul><p>Read more at: <a href="https://steampipe.io">https://steampipe.io</a>.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/steampipe-query-your-cloud-infrastructure?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/steampipe-query-your-cloud-infrastructure?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/steampipe-query-your-cloud-infrastructure?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><div><hr></div><h2><strong>OSQuery: SQL to query your OS</strong></h2><p>Steampipe is not the only project that provides an SQL interface for APIs.</p><p><a href="https://osquery.io/">Osquery</a> provides a SQL interface to query OS resources like processes, open network connections and much more.</p><p>Its website describes the project as:</p><blockquote><p>osquery exposes an operating system as a high-performance relational database. With osquery, SQL tables represent abstract concepts such as running processes, loaded kernel modules, open network connections, browser plugins, hardware events or file hashes.</p></blockquote><p>An example query with Osquery is as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LwbR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LwbR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 424w, https://substackcdn.com/image/fetch/$s_!LwbR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 848w, https://substackcdn.com/image/fetch/$s_!LwbR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 1272w, https://substackcdn.com/image/fetch/$s_!LwbR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LwbR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png" width="756" height="341" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:341,&quot;width&quot;:756,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41701,&quot;alt&quot;:&quot;SQL query to list the ports open on the local machine via Osquery&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="SQL query to list the ports open on the local machine via Osquery" title="SQL query to list the ports open on the local machine via Osquery" srcset="https://substackcdn.com/image/fetch/$s_!LwbR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 424w, https://substackcdn.com/image/fetch/$s_!LwbR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 848w, https://substackcdn.com/image/fetch/$s_!LwbR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 1272w, https://substackcdn.com/image/fetch/$s_!LwbR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95386d70-e190-435d-abfd-9dd0b2a39fa5_756x341.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">SQL query to list the ports open on the local machine via Osquery</figcaption></figure></div><p>With the above query, you can list the open ports on your machine at localhost.</p><div><hr></div><h2><strong>How to query Hackernews via SQL</strong></h2><p>Among the many integrations provided by Steampipe, <a href="https://hub.steampipe.io/plugins/turbot/hackernews">Hackernews</a> is an interesting one.</p><p>I chose this integration for my demo since Hackernews' API doesn't require an API token, which makes it easy to query.</p><p>You only need to install the Hackernews plugin via the command <code>steampipe plugin install hackernews</code> and then use Steampipe binary to query that API via <code>steampipe query</code>.</p><p>Each plugin provides multiple tables. You can find the full list of tables at <a href="https://hub.steampipe.io/plugins/turbot/hackernews/tables">Tables in Hacker news</a>.</p><p>In this example, you can use the table <code>hackernews_top</code> to query the top stories for today sorted by their score.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LLhe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LLhe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 424w, https://substackcdn.com/image/fetch/$s_!LLhe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 848w, https://substackcdn.com/image/fetch/$s_!LLhe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 1272w, https://substackcdn.com/image/fetch/$s_!LLhe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LLhe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png" width="747" height="411" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:411,&quot;width&quot;:747,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:39065,&quot;alt&quot;:&quot;SQL query to list the top stories from Hackernews via Steampipe&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="SQL query to list the top stories from Hackernews via Steampipe" title="SQL query to list the top stories from Hackernews via Steampipe" srcset="https://substackcdn.com/image/fetch/$s_!LLhe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 424w, https://substackcdn.com/image/fetch/$s_!LLhe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 848w, https://substackcdn.com/image/fetch/$s_!LLhe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 1272w, https://substackcdn.com/image/fetch/$s_!LLhe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcdf0adf-f3dd-437e-8c6c-fb5f359fb86e_747x411.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">SQL query to list the top stories from Hackernews via Steampipe</figcaption></figure></div><p>I made a recording of a live session with Steampipe at <a href="https://asciinema.org/a/nnBWKsoQLpd0qFvhdkRaSjg1Y">https://asciinema.org/a/nnBWKsoQLpd0qFvhdkRaSjg1Y</a>.</p><p>The same recording is available below as an animated GIF.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ABiY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ABiY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 424w, https://substackcdn.com/image/fetch/$s_!ABiY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 848w, https://substackcdn.com/image/fetch/$s_!ABiY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 1272w, https://substackcdn.com/image/fetch/$s_!ABiY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ABiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif" width="683" height="568" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:568,&quot;width&quot;:683,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:183263,&quot;alt&quot;:&quot;Interactive session with Steampipe and Hackernews plugin&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Interactive session with Steampipe and Hackernews plugin" title="Interactive session with Steampipe and Hackernews plugin" srcset="https://substackcdn.com/image/fetch/$s_!ABiY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 424w, https://substackcdn.com/image/fetch/$s_!ABiY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 848w, https://substackcdn.com/image/fetch/$s_!ABiY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 1272w, https://substackcdn.com/image/fetch/$s_!ABiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57a46146-4aca-4ed7-a550-086a3a342552_683x568.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Interactive session with Steampipe and Hackernews plugin</figcaption></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Powerful Command line tools for DevOps: Nushell and Jc]]></title><description><![CDATA[Episode #39: Revolutionize Your DevOps Toolkit with Nushell and Jc for Maximum Efficiency.]]></description><link>https://cloudnativeengineer.substack.com/p/powerful-command-line-tools-for-devops</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/powerful-command-line-tools-for-devops</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 16 Nov 2024 12:29:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0cMs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0cMs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0cMs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!0cMs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!0cMs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!0cMs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0cMs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:148308,&quot;alt&quot;:&quot;A Linux terminal inside a giant sea shell&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Linux terminal inside a giant sea shell" title="A Linux terminal inside a giant sea shell" srcset="https://substackcdn.com/image/fetch/$s_!0cMs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!0cMs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!0cMs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!0cMs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24a27407-000d-48eb-9c3b-db9799b8b1ec_1024x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A Linux terminal inside a giant sea shell. Image generated with Flux1 Pro</figcaption></figure></div><p>In my 20 years of experience with Linux command tools, I always felt frustrated with having to learn so many different text-processing tools like <code>awk</code>, <code>grep</code>, and <code>sed</code>, every time I wanted to parse the output of command line tools like <code>ls</code>, <code>ps</code> or <code>df</code>.</p><p>If only those commands were using a structured format like JSON as their output, you would only have to learn a single processing tool like <a href="https://jqlang.github.io/jq/">Jq</a>.</p><p>I recently discovered <a href="https://github.com/nushell/nushell">Nushell</a>, a modern alternative to the <a href="https://www.gnu.org/software/bash/">Bash terminal</a> that rewrites some command line tools to export structured data instead of just plain text.</p><p>Nushell makes it extremely easy to work with structured data with its human-friendly programming language and modern approach to the terminal.</p><p>As you might expect, though, since Nushell is a relatively new project, it only rewrites some of the most common command line tools.</p><p>For those tools that are not covered, you either have to hope they expose a <code>--json</code> flag or you can integrate with another command line tool called <a href="https://github.com/kellyjonbrazil/jc">Jc</a> (to not confuse with Jq, the famous JSON parser) that converts 100s of command line tools outputs to JSON format.</p><p>So after years of struggling, I finally got rid of <code>awk</code>, <code>grep</code>, <code>sed</code>, and <code>jq</code> and significantly improved my life.</p><p>I can use Jc to convert legacy Linux command output into structured data and then Nushell to process, filter, update or display that structured data with a human-friendly language.</p><p>In this tutorial, I want to share my experience and the lessons I learned as a Platform Engineer.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p><div><hr></div><h2><strong>Problem statement</strong></h2><p>As a Software Engineer, you interact daily with myriads of Linux command line tools (e.g. <code>ps</code>, <code>grep</code>, <code>dig</code>, <code>ls</code>), each with its output format and list of flags.</p><p>Mastering those tools can take years.</p><p>Most people, myself included, only master the basics and then spend hours consulting the documentation or StackOverflow whenever they encounter a new use case.</p><p>ChatGPT can really help here, especially when you want to create complex scripts. The only caveat is that you are left at the mercy of trusting a machine to do the work for you.</p><p>Furthermore, the more tools are necessary in your script, the harder it will be to make your code portable to other machines and the variety of Operating systems available.</p><p>Sometimes, when I get frustrated by the limitations of Bash (and my knowledge of the tool), I wish I had started directly from a Python script or another compiled language like Golang when things get complicated.</p><p>However, with those languages come other complexities.</p><p>There should be an easier way to use those command line tools in a powerful and human-friendly way.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/powerful-command-line-tools-for-devops?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/powerful-command-line-tools-for-devops?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/powerful-command-line-tools-for-devops?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>A little bit of personal history</strong></h2><p>I got my first Linux distribution almost 20 years ago, in my first year of university.</p><p>A terminal was a scary place to be coming from a Windows desktop.</p><p>So many tools to learn!!</p><p>You had to do anything just by typing commands on a black background.</p><p>Somehow, I managed to survive university and my first few jobs without being a ninja in text processing tools like <code>grep</code>, <code>awk</code>, <code>sed</code> and so on.</p><p>I knew enough to get by but was never fast by any metrics.</p><p>For the young people reading this article, this was long before ChatGPT was even a remote idea.</p><p>You had to invest a lot of upfront time to learn those text processing tools or countless hours on Stackoverflow asking for help whenever needed.</p><p>So, almost 10 years ago, I decided to invest some time into learning those tools and picked up an excellent book called <a href="https://jeroenjanssens.com/dsatcl/">Data Science at the Command Line, 2e</a>. You can now read this book online for free.</p><p>While reading this book, I got so frustrated that each command had a completely different output, and making them work together was so tedious. So, while I finished the book, I never retained big chunks of its content.</p><p>If only those commands had a standard interoperability format that would make it easier to filter, search, and pass along data from one command to another.</p><p>Why has nobody thought about it?</p><p>Fast forward to today.</p><p>ChatGPT can do a great job at crafting a complex pipeline for you. The only thing that you need to provide is the expected input and expected output.</p><p>Except that even ChatGPT makes mistakes, and you don't want to trust it completely.</p><p>If only there was a better way.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2><strong>JC - Convert legacy command line output into JSON</strong></h2><p>Since JSON is the de-facto standard for machine-readable data, it would be nice if any Linux command had a <code>--json</code> flag to output its results in JSON.</p><p>Instead of rewriting tools written in the '70s, JC parses the old and well-establish Linux commands output in a JSON format that can be easily processed by tools like Jq.</p><h3><strong>Examples</strong></h3><p>In the example below, we can see how to get the results of pinging an IP address in Json format by using <code>jc -p ping</code> command.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GEP_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GEP_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 424w, https://substackcdn.com/image/fetch/$s_!GEP_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 848w, https://substackcdn.com/image/fetch/$s_!GEP_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 1272w, https://substackcdn.com/image/fetch/$s_!GEP_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GEP_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png" width="603" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:603,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93421,&quot;alt&quot;:&quot;Ping command with Jc&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Ping command with Jc" title="Ping command with Jc" srcset="https://substackcdn.com/image/fetch/$s_!GEP_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 424w, https://substackcdn.com/image/fetch/$s_!GEP_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 848w, https://substackcdn.com/image/fetch/$s_!GEP_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 1272w, https://substackcdn.com/image/fetch/$s_!GEP_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52da05f9-a587-4a23-aa76-f7b654419ba9_603x859.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ping command - Screenshot from https://github.com/kellyjonbrazil/jc</figcaption></figure></div><p>Jc can also be used as a Python library, as seen in the example below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2iHK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2iHK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 424w, https://substackcdn.com/image/fetch/$s_!2iHK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 848w, https://substackcdn.com/image/fetch/$s_!2iHK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 1272w, https://substackcdn.com/image/fetch/$s_!2iHK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2iHK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png" width="1028" height="334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:334,&quot;width&quot;:1028,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:55907,&quot;alt&quot;:&quot;Jc as a Python library&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Jc as a Python library" title="Jc as a Python library" srcset="https://substackcdn.com/image/fetch/$s_!2iHK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 424w, https://substackcdn.com/image/fetch/$s_!2iHK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 848w, https://substackcdn.com/image/fetch/$s_!2iHK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 1272w, https://substackcdn.com/image/fetch/$s_!2iHK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd44705c-e02e-4755-96a7-e99c41e31998_1028x334.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Jc as a Python library - Screenshot from https://github.com/kellyjonbrazil/jc</figcaption></figure></div><p></p><h3><strong>Documentation</strong></h3><p>More about JC at:</p><ul><li><p><a href="https://kellyjonbrazil.github.io/jc/">jc - official docs</a></p></li></ul><p>The author of Jc has written extensively about the philosophy behind Jc at:</p><ul><li><p><a href="https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/">Bringing the Unix Philosophy to the 21st Century - Brazil's Blog</a></p></li><li><p><a href="https://blog.kellybrazil.com/2021/12/03/tips-on-adding-json-output-to-your-cli-app/">Tips on Adding JSON Output to Your CLI App - Brazil's Blog</a></p></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Nushell: A modern shell with a friendly programming language</strong></h2><p>Now that we have most of the Linux commands output in JSON format, what about processing this data?</p><p>Suddenly, most data processing tools like <code>awk</code>, <code>sed</code>, and <code>grep</code> are completely irrelevant, and you can just use <code>jq</code>.</p><p>But how easy is it to use <code>jq</code> for everything?</p><p>It is easy to start but it becomes pretty complex very soon.</p><p>Discover Nushell, a modern alternative to Bash conceived for the 21st century.</p><blockquote><p>Rather than thinking of files and data as raw streams of text, Nu looks at each input as something with structure.</p><p>In Unix, it's common to pipe between commands to split up a sophisticated command over multiple steps. Nu takes this a step further and builds heavily on the idea of&nbsp;<em>pipelines</em></p></blockquote><h3><strong>Examples</strong></h3><p>In the example below, you can see how to filter the command <code>ls</code> results by size greater than 10 Megabytes and then sort the results by the modified timestamp.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Oi8X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Oi8X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 424w, https://substackcdn.com/image/fetch/$s_!Oi8X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 848w, https://substackcdn.com/image/fetch/$s_!Oi8X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 1272w, https://substackcdn.com/image/fetch/$s_!Oi8X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Oi8X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png" width="1402" height="501" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:501,&quot;width&quot;:1402,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24181,&quot;alt&quot;:&quot;Ls command in Nushell&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Ls command in Nushell" title="Ls command in Nushell" srcset="https://substackcdn.com/image/fetch/$s_!Oi8X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 424w, https://substackcdn.com/image/fetch/$s_!Oi8X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 848w, https://substackcdn.com/image/fetch/$s_!Oi8X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 1272w, https://substackcdn.com/image/fetch/$s_!Oi8X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb02f85d3-56f7-4084-88d2-6c20c43e084b_1402x501.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ls command in Nushell - Screenshot from https://www.nushell.sh</figcaption></figure></div><p>In this other example, we can see how the output of the command <code>ps</code> to list all the running processes in your machines are filtered and sorted in reverse order by the amount of CPU.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t3rJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t3rJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 424w, https://substackcdn.com/image/fetch/$s_!t3rJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 848w, https://substackcdn.com/image/fetch/$s_!t3rJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 1272w, https://substackcdn.com/image/fetch/$s_!t3rJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!t3rJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png" width="933" height="359" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/79554959-3089-417e-a5f1-f99df3565c5b_933x359.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:359,&quot;width&quot;:933,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:43890,&quot;alt&quot;:&quot;Ps command in Nushell&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Ps command in Nushell" title="Ps command in Nushell" srcset="https://substackcdn.com/image/fetch/$s_!t3rJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 424w, https://substackcdn.com/image/fetch/$s_!t3rJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 848w, https://substackcdn.com/image/fetch/$s_!t3rJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 1272w, https://substackcdn.com/image/fetch/$s_!t3rJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79554959-3089-417e-a5f1-f99df3565c5b_933x359.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ps command in Nushell - Screenshot from https://www.nushell.sh</figcaption></figure></div><p></p><p>As you can see from the screenshots above, Nushell is quite a powerful language.</p><h3><strong>Pros and cons</strong></h3><p>Between the benefits we can list:</p><ul><li><p><strong>Nushell is a fully-typed scripting language</strong>. Similar support to compiled programming languages. Errors (like type inconsistencies) are detected before the script execution.</p></li><li><p><strong>Built-in commands</strong>: an extensive list of built-in functions to work with Sqlite, Excel, HTTP endpoints and so much more</p></li><li><p><strong>Cross-platform support</strong>: scripts written in Nushell can run without changes in all major operating systems: Windows, Linux, and Mac.</p></li><li><p><strong>Autocomplete</strong>: for all commands (even your custom-made ones) and programming language functions.</p></li><li><p><strong>Verbose error management</strong>.</p></li><li><p><strong>Fast</strong>: since it's written in Rush.</p></li><li><p><strong>Good support from the community</strong>: it integrates with lots of other tools.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HLU2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HLU2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 424w, https://substackcdn.com/image/fetch/$s_!HLU2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 848w, https://substackcdn.com/image/fetch/$s_!HLU2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 1272w, https://substackcdn.com/image/fetch/$s_!HLU2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HLU2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png" width="1456" height="1050" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1050,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:127419,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HLU2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 424w, https://substackcdn.com/image/fetch/$s_!HLU2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 848w, https://substackcdn.com/image/fetch/$s_!HLU2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 1272w, https://substackcdn.com/image/fetch/$s_!HLU2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82a01a3e-3742-45b8-a8b6-6ae2ee9641d0_1576x1137.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Negative bits:</p><ul><li><p><strong>Nushell is not Posix Compliant</strong>. Bash scripts won't run unmodified in Nushell. Replaced commands (like <code>ls</code> or <code>ps</code> from above) don't have the same parameters. Nushell prefers to have commands with fewer parameters and uses Pipes to combine multiple commands instead.</p></li></ul><h3><strong>Documentation</strong></h3><p>You can find more information about Nushell at:</p><ul><li><p><a href="https://www.nushell.sh/book/">Introduction | Nushell</a></p></li><li><p><a href="https://www.nushell.sh/commands/">Command Reference cheatsheet</a></p></li><li><p><a href="https://www.nushell.sh/cookbook/">Cookbook | Nushell</a></p></li></ul><h2><strong>Conclusion</strong></h2><p>I plan to still use Zsh as my favourite Posix-compliant shell to collaborate with other developers at work and progressively move to Nushell for any automation or personal use.</p>]]></content:encoded></item><item><title><![CDATA[How to deploy Fleet and Elastic Agent on Elastic Cloud Kubernetes]]></title><description><![CDATA[Episode #38: Unlocking the Power of Integrations by Setting up Elastic Cloud on Kubernetes with Fleet and Elastic Agent]]></description><link>https://cloudnativeengineer.substack.com/p/fleet-on-eck</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/fleet-on-eck</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sun, 15 Sep 2024 12:23:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!19u7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!19u7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!19u7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!19u7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!19u7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!19u7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!19u7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:58608,&quot;alt&quot;:&quot;A Fleet of container ships travel from a cloud&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Fleet of container ships travel from a cloud" title="A Fleet of container ships travel from a cloud" srcset="https://substackcdn.com/image/fetch/$s_!19u7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!19u7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!19u7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!19u7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fdd6ec2-7fe8-4482-ade6-c854087f420b_1024x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fleet and Elastic agents on ECK. Image generated with Flux.pro AI model</figcaption></figure></div><p>I published my first article on Elastic Cloud on Kubernetes (ECK) almost a year ago at <a href="https://cloudnativeengineer.substack.com/p/ep-11-elasticsearch-development-environment">Dev environment with Elastic Cloud on Kubernetes (ECK)</a>.</p><p>Several of my readers and mentees have asked for an extended article to help them with installing integrations in Elastic.</p><p>So here in part 2, I will expand on the Kubernetes manifests to explain setting up Fleet and Elastic Agents.</p><p>But first, why do we need Fleet and Elastic agents?</p><p>If you want to observe resources that are scattered on different machines, you need to have one Elastic agent for each node. You also need policies configuring which packages to install and many other configs.</p><p>Those configs can change over time. Managing this complexity by hand can be overwhelming.</p><p>Fleet allows you to centrally manage all your Elastic agents, their configurations, and the installation and upgrading of integrations.</p><p>Why should you bother with integrations?</p><p>Elastic has almost 400 integrations on its page <a href="https://www.elastic.co/integrations/data-integrations">Elastic integrations</a>.</p><p>You can observe anything from the same Kubernetes cluster where Elastic is running to Nginx servers, AWS cloud resources and anything in between.</p><p>For example, I wrote an integration for collecting access logs and metrics from <a href="https://www.elastic.co/docs/current/integrations/istio">Istio</a>.</p><p>Installing and configuring Fleet and the Elastic agents is quite a complex setup when done manually but very simple when running on ECK.</p><p>In this article, I will present a simple setup that can be used in a dev environment to get started and experiment with Elastic.</p><p>Moving to a production cluster needs some improvements to those manifests that can be discovered from the official documentation.</p><p>This article is split into the following sections:</p><ul><li><p><strong>Source code</strong>, with links to a GitHub project and other learning resources</p></li><li><p><strong>Elasticsearch</strong>, where I configure a single Elasticsearch node</p></li><li><p><strong>Kibana</strong>, where I set Kibana to create the Agent policies used by Fleet and the other Elastic agents</p></li><li><p><strong>Fleet and Elastic agents</strong>, where I configure the Fleet servers and the other Elastic agents.</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p><div><hr></div><h2><strong>Source code</strong></h2><p>The complete source code for this project is available at <a href="https://github.com/gsantoro/demos/tree/main/eck">demos/eck</a>.</p><p>Bear in mind that I assume that you are already familiar with Takskfile, direenv, devenv, Helm, K3d and Kustomize.</p><p>If you have never used Taskfile and you would like to learn it, head to <a href="https://cloudnativeengineer.substack.com/p/ep-5-taskfile-a-modern-alternative">Taskfile: a modern alternative to Makefile</a> and then later to <a href="https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile">Supercharge Your Automation Workflows with Taskfile: Say Goodbye to Makefile</a>.</p><p>If you want to learn how to use DevEnv to install 3rd party dependencies like kubectl, kustomize, helm and so on, head to <a href="https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix">Effortless Python Development with Nix</a>.</p><p>If you have Taskfile, direnv and devenv already installed and configured, you should be able to setup the entire project by just running <code>cd envs/eck; task</code>.</p><p>You can find more information at <a href="https://github.com/gsantoro/demos/tree/main/eck">demos/eck/Readme.md</a>.</p><p>As I mentioned already in the past, I prefer <a href="https://k3d.io/v5.7.3/">k3d</a> for setting up a multi-node Kubernetes cluster on my laptop. You might want to learn more about other options at <a href="https://cloudnativeengineer.substack.com/p/revolutionizing-development-exploring-kubernetes-dev-environments-in-2023-2eb0fb1d97e4">Exploring Kubernetes Dev Environments in 2023</a>.</p><p>If you need some extra help getting started with those tools or, in general, with Elastic products, feel free to reach out for some mentoring sessions at <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Giuseppe Santoro - Kubernetes Mentor on MentorCruise</a>.</p><h2><strong>Elasticsearch</strong></h2><p>The Elasticsearch manifest is almost identical to the one from the previous article.</p><p>The only thing that changed:</p><ul><li><p>increased memory and CPU requests and limits to speed up bootstrapping. It used to take up to 10 minutes to bootstrap this setup before I changed those limits. It now takes less than 2 minutes.</p></li><li><p>the version of the stack is now parametrised with an environment variable <code>$ELASTIC_STACK_VERSION</code>. This placeholder is replaced with the actual value of the env variable by the tool <code>envsubst</code> before the manifest is applied by kubectl.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ioTc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ioTc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 424w, https://substackcdn.com/image/fetch/$s_!ioTc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 848w, https://substackcdn.com/image/fetch/$s_!ioTc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 1272w, https://substackcdn.com/image/fetch/$s_!ioTc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ioTc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png" width="622" height="943" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:943,&quot;width&quot;:622,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:139283,&quot;alt&quot;:&quot;Elasticsearch manifest&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Elasticsearch manifest" title="Elasticsearch manifest" srcset="https://substackcdn.com/image/fetch/$s_!ioTc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 424w, https://substackcdn.com/image/fetch/$s_!ioTc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 848w, https://substackcdn.com/image/fetch/$s_!ioTc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 1272w, https://substackcdn.com/image/fetch/$s_!ioTc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F555f46be-6d65-4193-b6e2-643f1bf974a6_622x943.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Elasticsearch manifest</figcaption></figure></div><h2><strong>Kibana</strong></h2><p>The manifest for Kibana is now much larger and too big to fit in a single screenshot, so we have split it into 3 parts even if the actual source code is still a single file.</p><p>Please refer to the full manifest at <a href="https://github.com/gsantoro/demos/blob/main/eck/manifests/eck/kibana.yml">Kibana manifest</a>.</p><p>Part 1 is the same manifest as in the previous articles. We have only changed the resource limit and parametrised the version similarly to the Elasticsearch manifest.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eFnB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eFnB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 424w, https://substackcdn.com/image/fetch/$s_!eFnB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 848w, https://substackcdn.com/image/fetch/$s_!eFnB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 1272w, https://substackcdn.com/image/fetch/$s_!eFnB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eFnB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png" width="681" height="951" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:951,&quot;width&quot;:681,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:139692,&quot;alt&quot;:&quot;Kibana manifest - part 1&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Kibana manifest - part 1" title="Kibana manifest - part 1" srcset="https://substackcdn.com/image/fetch/$s_!eFnB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 424w, https://substackcdn.com/image/fetch/$s_!eFnB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 848w, https://substackcdn.com/image/fetch/$s_!eFnB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 1272w, https://substackcdn.com/image/fetch/$s_!eFnB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7ca0a7e-e4b3-45ef-9838-a1924339d366_681x951.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Kibana manifest - part 1</figcaption></figure></div><p>In part 2, we configure Kibana to talk to the Fleet server and Elasticsearch and we install some required Elastic packages.</p><p>Both Elasticsearch and Fleet server are referenced here by the Kubernetes services deployed by the ECK operator.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Ye5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Ye5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 424w, https://substackcdn.com/image/fetch/$s_!1Ye5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 848w, https://substackcdn.com/image/fetch/$s_!1Ye5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 1272w, https://substackcdn.com/image/fetch/$s_!1Ye5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Ye5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png" width="857" height="723" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:723,&quot;width&quot;:857,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:128862,&quot;alt&quot;:&quot;Kibana manifest - part 2&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Kibana manifest - part 2" title="Kibana manifest - part 2" srcset="https://substackcdn.com/image/fetch/$s_!1Ye5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 424w, https://substackcdn.com/image/fetch/$s_!1Ye5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 848w, https://substackcdn.com/image/fetch/$s_!1Ye5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 1272w, https://substackcdn.com/image/fetch/$s_!1Ye5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb5d072d-c3d2-46eb-ae72-584b3e2e84f6_857x723.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Kibana manifest - part 2</figcaption></figure></div><p>Part 3 is where most of the changes are. Here, we set the agent policies for the fleet server called <code>eck-fleet-server</code> and the other elastic agents called <code>eck-agent</code>.</p><p>As you notice, both of those policies have monitoring enabled to collect logs and metrics from the nodes where they are running.</p><p>While the Fleet server will have the <code>fleet_server</code> package installed, the other elastic agents will install the <code>system</code> package.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-9AZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-9AZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 424w, https://substackcdn.com/image/fetch/$s_!-9AZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 848w, https://substackcdn.com/image/fetch/$s_!-9AZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!-9AZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-9AZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png" width="646" height="1168" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1168,&quot;width&quot;:646,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:183040,&quot;alt&quot;:&quot;Kibana manifest - part 3&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Kibana manifest - part 3" title="Kibana manifest - part 3" srcset="https://substackcdn.com/image/fetch/$s_!-9AZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 424w, https://substackcdn.com/image/fetch/$s_!-9AZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 848w, https://substackcdn.com/image/fetch/$s_!-9AZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 1272w, https://substackcdn.com/image/fetch/$s_!-9AZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddc60892-fed7-4766-b2e3-9b9ea7dd2423_646x1168.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Kibana manifest - part 3</figcaption></figure></div><h2><strong>Fleet and Elastic agent</strong></h2><p>Fleet server is just a normal elastic agent with some extra packages and configuration.<br>That's why it uses the same <code>apiVersion</code> and <code>kind</code> of the other Elastic agents.</p><p>Some settings to keep in mind for the Fleet server:</p><ul><li><p><code>mode: fleet</code></p></li><li><p><code>fleetServerEnabled: true</code></p></li></ul><p>As mentioned in the Kibana manifest, Fleet server uses the policy id <code>eck-fleet-server</code>.</p><p>Since we only need a single Fleet server, this pod is deployed as a Kubernetes deployment with a single replica.</p><p>Also the Fleet server needs to have pointers to Kibana (here called <code>kibanaRef</code>) and Elasticsearch (here called <code>elasticsearchRef</code>) via the respective Kubernetes resource names to correctly communicate with the other components.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pugp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pugp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 424w, https://substackcdn.com/image/fetch/$s_!pugp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 848w, https://substackcdn.com/image/fetch/$s_!pugp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 1272w, https://substackcdn.com/image/fetch/$s_!pugp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pugp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png" width="632" height="861" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d80b0b90-242a-459c-8845-c72a33612ad9_632x861.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:861,&quot;width&quot;:632,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144506,&quot;alt&quot;:&quot;Fleet server manifest&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Fleet server manifest" title="Fleet server manifest" srcset="https://substackcdn.com/image/fetch/$s_!pugp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 424w, https://substackcdn.com/image/fetch/$s_!pugp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 848w, https://substackcdn.com/image/fetch/$s_!pugp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 1272w, https://substackcdn.com/image/fetch/$s_!pugp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd80b0b90-242a-459c-8845-c72a33612ad9_632x861.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Fleet server manifest</figcaption></figure></div><p>Similar to the Fleet server, the Elastic agents use the same <code>apiVersion</code> and <code>kind</code>.</p><p>From a configuration perspective, we can notice:</p><ul><li><p><code>mode: fleet</code></p></li></ul><p>As mentioned in the Kibana manifest, Fleet server uses the policy id <code>eck-agent</code>.</p><p>The Elastic agents are deployed as a DaemonSet, which means that Kubernetes will deploy a pod per node in the cluster.</p><p>In this setup, we have changed the Kubernetes cluster in K3d from the previous article to create a 3-node cluster to see multiple Elastic agents.</p><p>Each elastic agent needs to have pointers to Kibana (here called <code>kibanaRef</code>) and to the Fleet server (here called <code>fleetServerRef</code>) via the respective Kubernetes resource names to correctly communicate with the other components.</p><p>Finally, each Elastic Agent must have a volume mounted to store logs and metrics. Here, we are just using a locally mounted volume called <code>agent-data</code> created via the Kubernetes config <code>emptyDir</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zarn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zarn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 424w, https://substackcdn.com/image/fetch/$s_!zarn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 848w, https://substackcdn.com/image/fetch/$s_!zarn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 1272w, https://substackcdn.com/image/fetch/$s_!zarn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zarn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png" width="629" height="894" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:894,&quot;width&quot;:629,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143686,&quot;alt&quot;:&quot;Elastic agent manifest&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Elastic agent manifest" title="Elastic agent manifest" srcset="https://substackcdn.com/image/fetch/$s_!zarn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 424w, https://substackcdn.com/image/fetch/$s_!zarn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 848w, https://substackcdn.com/image/fetch/$s_!zarn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 1272w, https://substackcdn.com/image/fetch/$s_!zarn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf2032c5-24f2-4820-a1cb-7f67604c5faa_629x894.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Elastic agent manifest</figcaption></figure></div>]]></content:encoded></item><item><title><![CDATA[Maximise Your Productivity: Harness Hot Reloading in Kubernetes]]></title><description><![CDATA[Episode #37: Accelerate Your Kubernetes Workflow with Hot Reloading. Master Fast Feedback Loops Using Tilt, K3d, and ttl.sh!]]></description><link>https://cloudnativeengineer.substack.com/p/hot-reloading-in-kubernetes-with-tilt</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/hot-reloading-in-kubernetes-with-tilt</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Thu, 22 Aug 2024 20:57:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PS76!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PS76!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PS76!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!PS76!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!PS76!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!PS76!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PS76!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93653,&quot;alt&quot;:&quot;A Software Engineer using Tilt for pushing his app to a Kubernetes cluster&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A Software Engineer using Tilt for pushing his app to a Kubernetes cluster" title="A Software Engineer using Tilt for pushing his app to a Kubernetes cluster" srcset="https://substackcdn.com/image/fetch/$s_!PS76!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!PS76!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!PS76!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!PS76!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6bf8ef7-3184-4452-b3c6-a3e02517b308_1024x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Hot reloading a K8s application. Image generated with Flux.pro AI model</figcaption></figure></div><p>What is <strong>hot reloading</strong>?</p><blockquote><p>Developers can use hot reloading to instantly see changes in their code reflected in the running application without needing to restart or rebuild. This speeds up the development process and boosts productivity.</p></blockquote><p>If you have ever programmed in React or any other front-end framework, you might have used hot-reloading before.</p><p>Hot reloading is less common in compiled programming languages like Golang, and it is definitively hard to achieve without Tilt when running applications in Kubernetes.</p><p>You might be asking:</p><blockquote><p>Why would I want hot-reloading in Kubernetes when I can test my application locally without the extra complexity?</p></blockquote><p>With the advent of cloud-native technologies, micro-services must interact with many other services like databases, APIs, distributed caches, etc.</p><p>If you want to develop in such a complex environment, you have a couple of options:</p><ul><li><p>use <a href="https://testcontainers.com/">Testcontainers</a> in your functional tests.</p></li><li><p>use mocks and unit tests. This solution requires quite a large amount of code, and it is not for everyone.</p></li><li><p>"develop in production" with hot-reloading. Among the other solutions, this is the only one that doesn't require to write extra code.</p></li></ul><p>Beware, I'm not suggesting you shouldn't write functional or unit tests with mocks.</p><p>Hot reloading is exclusively for those instances where you want to test something quickly and don't want to mock the rest of the system architecture to test your changes.</p><p>This article will explain how you can achieve hot reloading of a Golang application running in Kubernetes with Tilt.</p><p>You can apply the insights you'll gain from this article to any compiled or interpreted programming language.</p><p>Also, you can extend this solution to using Kubernetes on any cloud provider, remote Docker registry and more complex applications with lots of different Kubernetes resources.</p><p>We have split this article into the following sections:</p><ul><li><p><strong>K3d</strong> and <strong>ttl.sh</strong></p></li><li><p>What is <strong>Tilt</strong>?</p></li><li><p>A Golang sample application</p></li><li><p>Hot reloading with Tilt</p><ul><li><p>Golang compilation</p></li><li><p>Docker build</p></li><li><p>Kubernetes apply and port-forwarding</p></li></ul></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2><strong>K3d and ttl.sh</strong></h2><p>This article is primarily about Tilt, but I would like to introduce two other tools that can contribute to achieving a fast feedback loop: K3d and ttl.sh.</p><p><a href="https://k3d.io/">K3d</a> is the easiest and fastest way to create a Kubernetes cluster on your machine. It's a more lightweight solution both in terms of CPU and memory consumption when compared to <a href="https://minikube.sigs.k8s.io/">Minikube</a> or <a href="https://kind.sigs.k8s.io/">Kind</a> since it uses SQLite instead of Etcd to store the state of your Kubernetes cluster.</p><p>A lightweight Kubernetes cluster with K3d means I can fit more containers in my laptop memory.</p><p>I have already mentioned K3d in a past article <a href="https://cloudnativeengineer.substack.com/p/revolutionizing-development-exploring-kubernetes-dev-environments-in-2023-2eb0fb1d97e4">Exploring Kubernetes Dev Environments in 2023</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;8daf6af7-ff95-4fbd-8785-1a40a8758784&quot;,&quot;caption&quot;:&quot;In 2023, there are many different ways of configuring your Kubernetes development environment. Some of them are Docker Desktop, Minikube, Kind, K3s, and K3d but the list goes on and on.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Exploring Kubernetes Dev Environments in 2023&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-05-19T17:36:09.034Z&quot;,&quot;cover_image&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*K0LLta7Oypi9xr1dzPd9SQ.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/revolutionizing-development-exploring-kubernetes-dev-environments-in-2023-2eb0fb1d97e4&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:130909644,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><p>The other tool in this article is <a href="https://ttl.sh/">ttl.sh</a>, dubbed on their website as an <code>Anonymous &amp; ephemeral Docker image registry</code>.</p><p>From their website, we can read:</p><blockquote><p><strong>Anonymous</strong>: No login required. Image names provide the initial secrecy for access. Add a UUID to your image name to reduce discoverability.</p><p><strong>Ephemeral</strong>: Image tags provide the time limit. The default is 24 hours, and the max is 24 hours (valid time tags :5m, :1600s, :4h, :1d)</p></blockquote><p>I prefer ttl.sh to the default Docker registry when developing with Tilt. It avoids the extra complexity of the Docker login, and there is not need to delete intermediate images created by Tilt. Given its ephemeral nature, ttl.sh will delete those images automatically after 24h.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/hot-reloading-in-kubernetes-with-tilt?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Cloud Native Engineer! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/hot-reloading-in-kubernetes-with-tilt?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/hot-reloading-in-kubernetes-with-tilt?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p></p><h2><strong>What is Tilt?</strong></h2><p>A great description of Tilt is provided on their official website.</p><blockquote><p>Tilt automates all the steps from a code change to a new process: watching files, building container images, and bringing your environment up-to-date. Think&nbsp;<code>docker build &amp;&amp; kubectl apply</code>&nbsp;or&nbsp;<code>docker-compose up</code>.</p></blockquote><p>You might never hear about Tilt, but <a href="https://www.docker.com/blog/welcome-tilt-fixing-the-pains-of-microservice-development-for-kubernetes/">Tilt was acquired by Docker in May 2022</a>.</p><p>Tilt implements its logic in a file called Tiltfile using syntax from a programming language called <a href="https://github.com/bazelbuild/starlark">Starlark</a>, a simplified version of Python designed for configuration files.</p><p>You don't have to be a Python programmer to create a Tiltfile. However, if you want to master more advanced features, it helps if you know Python programming basics.</p><p>To learn more about Tilt, check their <a href="https://docs.tilt.dev/">documentation</a>.</p><h2><strong>A Golang sample application</strong></h2><p>I have created a straightforward Golang application to show you how to implement hot reloading in Kubernetes.</p><p>Here is the Golang application.</p><pre><code><code>package main

import (
&#9;"os"

&#9;"github.com/gin-gonic/gin"
)

func main() {
&#9;r := gin.Default()

&#9;r.GET("/", func(c *gin.Context) {
&#9;&#9;c.JSON(200, gin.H{
&#9;&#9;&#9;"message": "Hello, World!",
&#9;&#9;})
&#9;})

&#9;r.Run(":" + os.Getenv("PORT"))
}
</code></code></pre><p>If you want to skip ahead and look at the final solution, check out the GitHub repository at <a href="https://github.com/gsantoro/demos/tree/main/tilt-go-sample-app">tilt-go-sample-app</a>.</p><p>There is much more in that repository, which I am not explaining here. In particular, I use two tools: Taskfile and Devenv (UI for Nix).</p><p>If you want to learn more about those tools, make sure to check out the articles below:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;5e987eae-82c4-4746-999d-4a7c9184dc12&quot;,&quot;caption&quot;:&quot;This article is my second piece on Taskfile.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Supercharge Your Automation Workflows with Taskfile: Say Goodbye to Makefile&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-03-17T19:05:42.507Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:142696718,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;490c780e-d017-40ce-aed5-cc1a35a9d9e5&quot;,&quot;caption&quot;:&quot;If you ask 100 developers how they set up their Python development environment, getting many different answers is not uncommon.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Effortless Python Development with Nix&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-02-18T00:28:29.202Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d927bed-c1f3-45f1-9313-694f0383ba5a_990x994.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:141779798,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><h2><strong>Hot reloading with Tilt</strong></h2><p>Below is the full code snippet of the Tiltfile I used to implement hot reloading in my application:</p><pre><code><code># -*- mode: Python -*-

load('ext://restart_process', 'docker_build_with_restart')

local_resource(
  'compile',
  'CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -o build/hello cmd/hello.go',
  ignore=['build'],
  deps=['cmd/hello.go', 'go.mod', 'go.sum'])

docker_build_with_restart(
  'ttl.sh/tilt-go-sample-app',
  '.',
  entrypoint=['/app/hello'],
  dockerfile='deploy/docker/Dockerfile',
  only=[
    './build'
  ],
  live_update=[
    sync('./build', '/app')
  ]
)

k8s_yaml('deploy/kubernetes.dev/pod.yaml')

k8s_resource('tilt-go-sample-app', port_forwards=8085,
             resource_deps=['compile'])
</code></code></pre><p>When trying to replicate the results in this article, make sure you have the above Tiltfile and all the resources mentioned in this article from <a href="https://github.com/gsantoro/demos/tree/main/tilt-go-sample-app">tilt-go-sample-app</a>.</p><p>Then, you only need to run <code>tilt up</code> from the root folder where you have your Tiltfile.</p><p>There are three stages in this Tiltfile:</p><ol><li><p>Golang compilation</p></li><li><p>Docker build</p></li><li><p>Kubernetes apply and Port forwarding</p></li></ol><p>Let's analyse each of the stages in detail.</p><h3><strong>Golang compilation</strong></h3><p>Here it is the snippet that we are analysing in this section:</p><pre><code><code>local_resource(
  'compile',
  'CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -o build/hello cmd/hello.go',
  ignore=['build'],
  deps=['cmd/hello.go', 'go.mod', 'go.sum'])
</code></code></pre><p>To build the Golang application, you must define a local resource and assign it a name and a command to run.</p><p>Here, we used the name <code>compile</code> and the command <code>CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -o build/hello cmd/hello.go</code>.</p><p>The command is executed by default from the folder where the Tiltfile is located.</p><p>We are compiling the Golang code to run on <code>linux/amd64</code>, the architecture we chose for our Docker base image.</p><p>Any changes to the file or directory paths specified in the <code>deps</code> array will kick off a rerun of the command. We only have one Golang file <code>cmd/hello.go</code>, and its dependencies are defined in <code>go.mod</code> and <code>go.sum</code>.</p><h3><strong>Docker build</strong></h3><p>Before explaining the Tiltfile command to build the Docker image, let's analyse the content of the Dockerfile.</p><pre><code><code>FROM cgr.dev/chainguard/wolfi-base:latest@sha256:3490ac41510e17846b30c9ebfc4a323dfdecbd9a35e7b0e4e745a8f496a18f25

RUN mkdir /app

COPY build/ /app

CMD ["/app/hello"]
</code></code></pre><p>Here, we use a distroless container from <a href="https://www.chainguard.dev/chainguard-images">Chainguard</a> called <code>wolfi-base</code>, a minimal image with very little in it.</p><p>We have pinned both the tag and the digest of the base image to fully replicate the build in the future.</p><p>The rest is straightforward. We are copying the previous stage's output from the folder <code>build</code> to the path <code>/app</code>. We will use the entrypoint <code>/app/hello</code> to run our application from inside the container.</p><pre><code><code>load('ext://restart_process', 'docker_build_with_restart')

docker_build_with_restart(
  'ttl.sh/tilt-go-sample-app',
  '.', # context = current directory
  entrypoint=['/app/hello'],
  dockerfile='deploy/docker/Dockerfile',
  only=[
    './build'
  ],
  live_update=[
    sync('./build', '/app')
  ]
)
</code></code></pre><p>The command <code>docker_build_with_restart</code> is loaded as an extension to the <code>docker_build</code> command. It provides a crucial part of the hot reloading functionality.</p><p>When the compilation stage changes something in the <code>build</code> folder (specified in the <code>only</code> parameter), this command will:</p><ol><li><p>build a docker image called <code>tilt-go-sample-app</code> using the Dockerfile <code>deploy/docker/Dockerfile</code> with the entrypoint <code>/app/hello</code>.</p></li><li><p>copy that container image to the ttl.sh container registry at the location <code>ttl.sh/tilt-go-sample-app</code></p></li><li><p>at any subsequent change to <code>build</code>, Tilt will skip creating that container image if it doesn't detect any changes in the Dockerfile. Instead, it will just <code>live update</code> the content of the <code>./build/</code> folder to <code>/app/</code> inside that container. As you can imagine, this logic dramatically speeds up the development since it happens almost instantaneously for such a simple application.</p></li></ol><p>Remember that the container image name <code>ttl.sh/tilt-go-sample-app</code> needs to match the container name in the Kubernetes manifest, explained in the next section.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h3><strong>Kubernetes apply and port-forwarding</strong></h3><p>Finally, the last stage in this Tiltfile involves deploying our Kubernetes resource and port-forwarding the port <code>8085</code> from the container to the developer machine.</p><p>The following snippet from the Tiltfile achieves exactly those things.</p><pre><code><code>k8s_yaml('deploy/kubernetes.dev/pod.yaml')

k8s_resource('tilt-go-sample-app', port_forwards=8085,
             resource_deps=['compile'])
</code></code></pre><p>Remember that <code>tilt-go-sample-app</code> in the command <code>k8s_resource</code> is not the container name but the name of the Kubernetes resource. I have fallen in this trap quite a few times before figuring out what was wrong with my Tiltfile.</p><p>You can see that in the <code>pod.yaml</code> definition at <code>metadata.name</code></p><pre><code><code>apiVersion: v1
data:
  HOSTNAME: 0.0.0.0
  PORT: "8085"
kind: ConfigMap
metadata:
  name: app
  namespace: default
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: tilt-go-sample-app
  name: tilt-go-sample-app
spec:
  containers:
  - image: ttl.sh/tilt-go-sample-app:latest
    name: tilt-go-sample-app
    envFrom:
    - configMapRef:
        name: app
    ports:
    - containerPort: 8085
  dnsPolicy: ClusterFirst
  restartPolicy: Always
</code></code></pre><p>As you can see from above, the image name <code>ttl.sh/tilt-go-sample-app</code> matches the first parameter of <code>docker_build_with_restart</code> from the previous section.</p><p>This is the most basic Kubernetes manifest that you could create. Just a pod with a single container and a ConfigMap to pass the port to expose to the application.</p><p>As you can recall from the beginning of this article, this application takes an environment variable to configure the port at which the REST application is listening.</p><p></p><div><hr></div><p>Are you ready to take your skills to new heights? &#128640;</p><p>&#128674; Let's embark on this journey together!&nbsp;</p><p>&#128099;&nbsp;Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a> to receive valuable content on AI, Kubernetes, System Design, Elasticsearch, and much more.&nbsp;</p><p>&#127891; If you&nbsp;want&nbsp;personalised guidance, I am here to support you. Book a mentoring session with me at&nbsp;<a href="https://mentors.to/gsantoro">https://mentors.to/gsantoro</a>&nbsp;on MentorCruise, and&nbsp;let's work together to unlock your full potential.&nbsp;</p><p>&#9851;&#65039; Remember, sharing is caring!&nbsp;If this content has helped you, please re-share it with others so&nbsp;they&nbsp;can&nbsp;benefit from it.&nbsp;</p><p>&#129321; Let's inspire and empower each other to reach new heights!</p>]]></content:encoded></item><item><title><![CDATA[Demystifying Log Collection in Cloud-Native Applications on Kubernetes]]></title><description><![CDATA[Episode #36: A DevOps Engineer&#8217;s Guide to Aggregating Distributed Logs with Kubernetes and Elastic tools.]]></description><link>https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Wed, 24 Jul 2024 22:34:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zJXC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zJXC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zJXC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!zJXC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!zJXC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!zJXC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zJXC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2019313,&quot;alt&quot;:&quot;A person collecting wooden logs&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A person collecting wooden logs" title="A person collecting wooden logs" srcset="https://substackcdn.com/image/fetch/$s_!zJXC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!zJXC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!zJXC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!zJXC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32aae85-634f-48c4-bf5a-fe3dd74a30e6_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A person collecting wooden logs. Image generated by the author with Midjourney</figcaption></figure></div><p>This article continues our journey into Observability and logs.</p><p>So far, I have only examined logging from an application developer's perspective.</p><p>Here, we will analyse the problem from the perspective of a DevOps engineer who wants to aggregate logs from multiple distributed sources into a single log analysis tool, like Elasticsearch.</p><p>The main focus here is on "distributed."</p><p>If you were analysing a single log file from a local application, you wouldn't even need a "log collection" process. You could use command line tools to tail a log file and grep for what you need. I might consider writing an article on this topic, but it won't be our primary focus.</p><p>You can swap the word "distributed" with microservices or "cloud-native applications running on Kubernetes over many nodes".</p><p>My over two years of experience in the Cloud Native Observability team at Elastic, the company behind Elasticsearch, has equipped me with the knowledge to guide you through the complexities of log collection in distributed applications.</p><p>In this article, we will explain how Kubernetes gathers logs from a container and makes them available to possible log collection agents in an effective manner that mitigates some of the typical challenges.</p><p>The insights you'll gain from this article can be easily applied to various solutions, regardless of their relation to Kubernetes or Elastic Observability tools.</p><p>The sections of this article are the following:</p><ul><li><p>Observability and logging</p></li><li><p>Log collection in distributed applications</p></li><li><p>Pitfalls of log collections</p></li><li><p>Log writing in Kubernetes</p></li><li><p>Nginx's logs in Kubernetes</p></li><li><p>Log collection in Kubernetes</p></li><li><p>Node logging agent architecture</p></li><li><p>Logging agents</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Observability and logging</strong></h2><p>If you are new to Observability and logging, I have already written several articles on this topic in this newsletter.</p><p>In <a href="https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging">Exploring Structured Logging with Slog in Go</a>, I have already introduced the concept of Observability as a modern version of monitoring.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;ccda84de-2d15-4d19-9413-df4c5e32a949&quot;,&quot;caption&quot;:&quot;Introduction&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Exploring Structured Logging with slog in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-09-20T13:32:27.260Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae5318e-2a44-4c3f-94ca-123888254731_5568x3712.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:137219726,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:3,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>I have also discussed how it's best to abandon print statements and move to proper Observability with logs, metrics, and traces in <a href="https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements">Observability 101: A Beginner's Journey Free of Print Statements</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;b4ec2021-4e05-4f5a-9649-dd52c6d439c0&quot;,&quot;caption&quot;:&quot;It doesn't matter what stage of your career you are currently in. At some point, you might have used Print statements to debug software. While you might have thought that was fine, I suggest that that's not a good practice you should adopt in 2024. This article should help ab&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Observability 101: A Beginner's Journey Free of Print Statements&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-06-09T21:39:48.621Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:145480963,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:4,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Finally, in <a href="https://cloudnativeengineer.substack.com/p/master-observability-with-logs">Master Observability with Logs: An In-Depth Guide for Beginners</a>, I have debated how logging fits in the picture of Observability, how it compares to other signals (aka Metrics and Traces) and how to get started with logging in Golang.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a1355868-bac9-45e7-ae63-b982b5adc316&quot;,&quot;caption&quot;:&quot;This is the second article I wrote about the basics of observability for beginners. Previously, I have discussed how it's best to abandon print statements, or whatever primitive your programming language supports for writing to standard output, and move to proper observability with logs, metrics, and traces.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Master Observability with Logs: An In-Depth Guide for Beginners&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-06-29T20:23:04.242Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/master-observability-with-logs&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:146117428,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h2><strong>Log collection in distributed applications</strong></h2><p>What does <code>log collection in distributed applications</code> mean in this article?</p><p>The assumption here is that:</p><blockquote><p>You have a non-trivial amount of logs constantly generated by a distributed application, distributed microservices, or many different applications running on a platform like Kubernetes that you want to analyse in a central location.</p></blockquote><p>Let's unwrap the previous sentence:</p><ul><li><p><code>distributed</code> logs are generated in many different machines</p></li><li><p><code>non-trivial amount</code>, more than just a few hundred megabytes.</p></li><li><p><code>continuously</code>, you have a constant stream of data</p></li><li><p><code>central location</code> is the most important of the previous assumptions. Unless you centralise your logs, you won't be able to correlate them to investigate a root cause analysis.</p></li></ul><p>If even one of those assumptions is not valid in your use case, you might not need the solution described here.</p><p>If you have, for example, a few hundred-megabyte files as part of a support case, you could use some CLI tools or ingest your logs as a one-off into an SQL database. There is no need for a complex log collection process.</p><p>Also, if you didn't need to correlate logs from many sources, you could store each application's logs in the node where the logs are generated. You could SSH into the node with the faulty application and inspect the logs where they leave.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Cloud Native Engineer. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Pitfalls of log collection</strong></h2><p>Before discussing the clever pattern used by Kubernetes, I will briefly mention some of the problems with log collection.</p><h3><strong>Filling local disk</strong></h3><p>We have been writing logs into local files since application logging was a thing.</p><p>The biggest problem was implementing log rotation based on time or size to avoid filling the machine disk.</p><p>You could keep the last 30 days or 500MB of logs, depending on which limit was hit first.</p><p>Log rotation on local files has been a problem that has been solved for many years, but it still requires some logging agent to keep truncating the log files.</p><h3><strong>Pushing logs to a log sink</strong></h3><p>It doesn't matter if your application sends logs directly to blob storage, a remote log analyser or any intermediary like a log collection tool.</p><p>The problem is still the same.</p><p>Your application needs to be "aware" of the log sink.</p><p>This means that you might need an application library to deliver log messages to that particular sink or some config management (or maybe just a config file) to store the location of the log sink.</p><p>What if the log analyser tool is temporarily not available? You will lose logs or need to implement some in-memory buffer to account for this inevitable situation. A retry logic with an exponential back-off will be advisable in this case.</p><p>You might want to change the location of the log sink or the type of sink, requiring maybe a restart of your application.</p><p>All the previous requirements affect the application in terms of performance both on CPU (sending the logs) and memory usage (storing them temporarily in a memory buffer).</p><p>To avoid blocking your application's main logic (which is definitively not advisable), you will have to delegate sending logs to a parallel async thread so that it becomes an asynchronous operation.</p><p>As you can see, sending logs directly from your application to a log sink makes the application unnecessarily complicated.</p><h3><strong>3rd party apps</strong></h3><p>To make things worse, you might need to handle log collection from 3rd party software differently from applications where you have control over the source code.</p><p>You won't be able to push logs from 3rd party applications, so you will need to collect them first and then move them to the log sink.</p><h2><strong>Log writing in Kubernetes</strong></h2><p>There must be a better way to deal with log collection.</p><p>Kubernetes has adopted quite a clever trick to avoid some of the pitfalls presented above.</p><p>Kubernetes expect your application (or any 3rd party application) to write its logs to the standard output (aka stdout) and standard error (stderr) device files.</p><p>If you are not already familiar with what stdout and stderr are from Linux, you might want to understand those topics at <a href="https://en.wikipedia.org/wiki/Standard_streams">Standard streams</a> before moving forward with the rest of the section.</p><p>By default, Kubernetes redirects the content of these two stream files for a running container to the same file <code>/var/log/containers/&lt;container_id&gt;.log</code> on the node where the application is running.</p><p>At the same time, Kubernetes allows a user to access those same log files with the command:</p><pre><code><code>kubectl logs &lt;pod-name&gt; -n &lt;namespace&gt;</code></code></pre><p>You can even stream the content of log files as they are written with the following command writes it:</p><pre><code><code>kubectl logs -f &lt;pod-name&gt; -n &lt;namespace&gt;</code></code></pre><p>Thanks to a Kubelet, Kubernetes also implements log rotation based on either time or size to keep each container log to a limited size and avoid overfilling the local disk.</p><h2><strong>Nginx's logs in Kubernetes</strong></h2><p>What if instead of writing to stdout/stderr, the application that you want to collect logs from writes to one or more local files (like, for example, access.log and error.log in the case of Nginx),</p><p>In this case, the container image must be modified to redirect those files to stdout and stderr when running on Kubernetes.</p><p>Let's analyse how this is done in <a href="https://github.com/nginxinc/docker-nginx/blob/a6f7d140744f8b15ff4314b8718b3f022efc7f43/mainline/debian/Dockerfile">Nginx's Dockerfile</a>.</p><pre><code><code>ln -sf /dev/stdout /var/log/nginx/access.log
ln -sf /dev/stderr /var/log/nginx/error.log
</code></code></pre><p>As you can see, two <a href="https://en.wikipedia.org/wiki/Symbolic_link">symlinks</a> are created to redirect access.log and error.log, respectively, to the stdout and stderr device files.</p><p>The above modifications are done so that Kubernetes can treat every application in the same way.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Cloud Native Engineer. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/log-collection-in-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Log collection in Kubernetes</strong></h2><p>Kubernetes effectively separate the log writing step from the log collection, solving most of the pitfalls of log collection that we analysed above.</p><p>The application writes logs to a file synchronously without any performance problems or a need to handle complex retry logic and in-memory buffers; then, logs can be collected and shipped asynchronously by another tool to a log sink.</p><p>Log collection can be delegated to any 3rd party tool and handle both your applications (the ones you have control over the source code) in the same way that it handles 3rd party applications.</p><p>As you can imagine, the benefits are enormous in terms of performance, application complexity and application size.</p><p>Moreover, logs don't have to be streamed at the same speed as they are generated. They can be batched for improved performance.</p><p>Any failure handling technique we discussed above still needs to be handled by a log collection tool, but that's not your application problem.</p><p>There are different ways in which log collection can happen.</p><h2><strong>Node logging agent architecture</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IJM8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IJM8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 424w, https://substackcdn.com/image/fetch/$s_!IJM8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 848w, https://substackcdn.com/image/fetch/$s_!IJM8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 1272w, https://substackcdn.com/image/fetch/$s_!IJM8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IJM8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png" width="500" height="350" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:350,&quot;width&quot;:500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38071,&quot;alt&quot;:&quot;Node logging agent architecture.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Node logging agent architecture." title="Node logging agent architecture." srcset="https://substackcdn.com/image/fetch/$s_!IJM8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 424w, https://substackcdn.com/image/fetch/$s_!IJM8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 848w, https://substackcdn.com/image/fetch/$s_!IJM8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 1272w, https://substackcdn.com/image/fetch/$s_!IJM8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe2bb414-0e76-4197-9aef-652cfb9c1a19_500x350.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Node logging agent architecture. Image taken from Kubernetes.io</figcaption></figure></div><p>The most famous cluster-level logging architecture in Kubernetes is called <a href="https://kubernetes.io/docs/concepts/cluster-administration/logging/#using-a-node-logging-agent">node logging agent</a>.</p><p>One pod per node runs separately from your application and has full access to the underlying Kubernetes node where it is running.</p><p>This pod needs full read access to the location in the Kubernetes node where container logs are stored (aka <code>/var/log/containers/</code>).</p><p>Given that you need one (and only one) log agent per node, this requirement can be easily implemented in Kubernetes as a <a href="https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/">DaemonSet</a>.</p><p>The log collection agent will likely use some form of watermarking to record the last log event correctly delivered on disk. If the node agent fails and is restarted, it can start from where it left off.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Logging agents</strong></h2><p>Historically, Elastic has created or contributed to many tools to collect logs from different sources and dispatch them to Elasticsearch for storage and analysis.</p><p>In order of when those tools were developed:</p><ul><li><p><a href="https://www.elastic.co/logstash">Logstash</a>, a server-side data processing pipeline that ingests, transforms, and ships data to various destinations.</p></li><li><p><a href="https://www.elastic.co/beats">Elastic Beats</a>, lightweight data shippers in Golang that send data from edge devices to Elasticsearch or Logstash.</p></li><li><p><a href="https://www.elastic.co/elastic-agent">Elastic Agent</a>, a single, unified way to add monitoring for logs, metrics, and other types of data to a host. Under the hood, it uses Elastic Beats but also provides extra features for host security.</p></li><li><p><a href="https://opentelemetry.io/docs/collector/">Otel log collector</a> is a vendor-agnostic way to receive, process, and export telemetry data. Elastic did not originally write this tool but has contributed heavily in recent years.</p></li></ul><p>The Otel collector is likely the future of log collection, not just at Elastic but also in the Observability field.</p><blockquote><p><a href="https://opentelemetry.io/docs/concepts/observability-primer/">OpenTelemetry (OTel)</a> is more broadly an open-source observability framework that provides vendor-agnostic APIs, libraries, agents, and instrumentation to generate, collect, process, and export telemetry data (traces, metrics, and logs) for analysis in observability backends.</p></blockquote><div><hr></div><div class="directMessage button" data-attrs="{&quot;userId&quot;:3521121,&quot;userName&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;canDm&quot;:null,&quot;dmUpgradeOptions&quot;:null,&quot;isEditorNode&quot;:true}" data-component-name="DirectMessageToDOM"></div>]]></content:encoded></item><item><title><![CDATA[From Zero to K8s Hero: 5 Must-Have Tools for Kubernetes]]></title><description><![CDATA[Episode #35: Stay ahead of the competition by mastering these 3 tools for beginners and these 2 for more advanced users.]]></description><link>https://cloudnativeengineer.substack.com/p/5-must-have-tools-for-kubernetes</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/5-must-have-tools-for-kubernetes</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 13 Jul 2024 20:55:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2AoJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2AoJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2AoJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!2AoJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!2AoJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!2AoJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2AoJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1399777,&quot;alt&quot;:&quot;a ship captain navigate rough seas at night while looking at a lighthouse&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="a ship captain navigate rough seas at night while looking at a lighthouse" title="a ship captain navigate rough seas at night while looking at a lighthouse" srcset="https://substackcdn.com/image/fetch/$s_!2AoJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!2AoJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!2AoJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!2AoJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cb3354e-7e77-4b47-a112-b644a154ab3d_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The captain (in Greek Kubernetes) of a ship navigates rough seas at night.</figcaption></figure></div><p>In this article, I'll introduce 5 must-have tools to start your journey with Kubernetes.</p><p>The first three tools in this list are absolutely indispensable for beginners. The last two make you stand out as a beginner and look like an advanced user.</p><p>I'll provide my point of view on what tools can give you an edge over your colleagues and which ones are not worth learning.</p><p>What qualifies me to give you such suggestions?</p><p>I have spent countless hours in the last few years trying all the Kubernetes tools I could get my hands on, either during my working hours or during my free time for my side projects.</p><p>I have to admit it. I am a tools nerd. I love to play with all the shiny tools, and the Kubernetes ecosystem has plenty of them.</p><p>Given that new tools pop up every day, like mushrooms, I have always thought I needed advice on which ones are worth learning and which are not worth my time.</p><p>So, I tried as many as possible, and after years of experience, I am now ready to mentor others.</p><p>In this article, I want to give the guidance I missed when I first picked up Kubernetes years ago.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p>So please don't waste any more time, and let's dive deep into this article.</p><h2><strong>1. Browse your Kubernetes cluster: K9s</strong></h2><p>My favourite Kubernetes tool is <a href="https://k9scli.io/">K9s</a>, a terminal-based UI that lets you interact with your Kubernetes cluster.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kdxu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kdxu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 424w, https://substackcdn.com/image/fetch/$s_!kdxu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 848w, https://substackcdn.com/image/fetch/$s_!kdxu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 1272w, https://substackcdn.com/image/fetch/$s_!kdxu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kdxu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png" width="1138" height="542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/baab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:542,&quot;width&quot;:1138,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:132088,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kdxu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 424w, https://substackcdn.com/image/fetch/$s_!kdxu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 848w, https://substackcdn.com/image/fetch/$s_!kdxu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 1272w, https://substackcdn.com/image/fetch/$s_!kdxu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbaab68de-e21d-4fa1-a93c-ab33bb3d374c_1138x542.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">K9s listing all the running pods in all namespaces</figcaption></figure></div><p>If you, like me, have been raised with "Bread and... Linux" " you will appreciate the beauty of using CLI tools that are both open source and highly customisable with Skins, plugins, command aliases and custom key bindings.</p><p>What are the benefits of using K9s as your primary tool for browsing your cluster:</p><ul><li><p><strong>Support for all standard Kubernetes objects</strong>: view and interact with pods, containers, services, RBAC, volumes, events, etc.</p></li><li><p><strong>CRD Support</strong>: Support interacting with Custom Resource Definitions (CRD).</p></li><li><p><strong>Runs everywhere</strong>: Runs on any OS and can be installed with most package managers.</p></li><li><p><a href="https://github.com/derailed/k9s#skins">Skins</a>: Change the look and feel but also the behaviour of the UI based on the cluster and context you are working on. Between the advanced features, you can also make a read-only context, preventing any involuntary modification in your production clusters.</p></li><li><p><a href="https://github.com/derailed/k9s#plugins">Plugins</a>: I personally played with this feature a while ago when I wanted to parse some JSON logs from a Kubernetes pod and display them in tabular form. I created a Kubectl plugin in Python that I called <a href="https://github.com/gsantoro/rich-json-logs#k9s-plugin">rich-json-logs</a> and then plugged it into K9s. Almost straightforward.</p></li><li><p><a href="https://github.com/derailed/k9s#plugins">Command aliases</a>: Command aliases are less powerful than plugins but can save some keystrokes.</p></li><li><p><a href="https://github.com/derailed/k9s#hotkey-support">Custom key bindings</a>: With one or two keystrokes, you can either view a specific type of Kubernetes resource, call a plugin, a command alias or many other features.</p></li></ul><p>What are the alternatives:</p><ul><li><p><a href="https://k8slens.dev/">Lens</a>: a paid alternative with a generous free personal plan. This desktop application doesn't offer more than K9s unless you have a quite expensive Pro or an Enterprise license.</p></li><li><p><a href="https://github.com/MuhammedKalkan/OpenLens">OpenLens</a>: an open-source version of Lens. Since Mirantis, the company behind Lens, has moved away from open-source, this project won't get any more updates.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Cloud Native Engineer&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Cloud Native Engineer</span></a></p><h2><strong>2. Automate everything: Kubectl</strong></h2><p>If you have ever worked with Kubernetes, you will have already encountered <a href="https://kubernetes.io/docs/reference/kubectl/">Kubectl</a>, the Kubernetes command line tool.</p><p>Why did I only put it second on my list?</p><p>This tool can do anything you need with Kubernetes, but it doesn't provide such a nice user experience as K9s.</p><p>When working with Kubernetes, especially if you are a DevOps and in the middle of an incident, you must move fast!</p><p>Given that I can't remember the syntax of the Kubectl commands and that each command involves a lot of typing, K9s is a much superior tool for my needs.</p><p>Why do I still suggest Kubectl?</p><p>Whenever I need to write some automation that interacts with Kubernetes, Kubectl is my tool of choice.</p><p>The best part is that you don't have to choose between these two.</p><p>You can use K9s for the speed and UX and Kubectl for its extensibility and make them work together.</p><p>Look at the command below. Without using any other tool, I'll get the version label of all pods with the label <code>app=cassandra</code>.</p><pre><code><code>kubectl get pods --selector=app=cassandra -o jsonpath='{.items[*].metadata.labels.version}'
</code></code></pre><p>I took this last command from <a href="https://kubernetes.io/docs/reference/kubectl/quick-reference/">Kubernetes quick reference</a>, a great resource if you ever want to <a href="https://cloudnativeengineer.substack.com/p/prepare-for-your-cka-exam-e1c33883eaf2">Prepare for your Certified Kubernetes Administrator exam</a> since you can use it at the exam.</p><p>What are the alternatives:</p><ul><li><p>K9s: we have already discussed this in the previous section.</p></li><li><p><a href="https://kubernetes.io/docs/reference/using-api/client-libraries/">Kubernetes client libraries</a>: If you need to automate interacting with your Kubernetes cluster in code and you want to avoid using Kubectl in bash, you can use the Kubernetes SDK in your language of choice.</p></li></ul><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/5-must-have-tools-for-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Cloud Native Engineer. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/5-must-have-tools-for-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/5-must-have-tools-for-kubernetes?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>3. Package manager: Krew</strong></h2><p>The third tool on my list is <a href="https://krew.sigs.k8s.io/plugins/">Krew</a>, the official package manager of Kubectl.</p><p>I recently learned about this tool, but it is an excellent addition to my arsenal.</p><p>Like any package manager, there is not much to say about it other than it does its job well and is supported by all operating systems.</p><p>The tool's best part is the documentation with the list of <a href="https://krew.sigs.k8s.io/plugins/">official plugins</a> that Krew supports.</p><p>If you go through that list, you might discover plugins you did not know existed.</p><h2><strong>4. Aggregate logs from multiple Kubernetes resources: Stern</strong></h2><p>Stern is the first in this list of tools geared towards more advanced users.</p><p>If you have looked at pod logs in Kubernetes, you may have encountered a use case when you wanted to combine logs from various pods or containers within a pod in the same output.</p><blockquote><p><a href="https://github.com/stern/stern">Stern</a> allows you to&nbsp;<code>tail</code>&nbsp;multiple pods on Kubernetes and multiple containers within the pod. Each result is color-coded for quicker debugging.</p></blockquote><h2><strong>5. Look under the hood: node-shell</strong></h2><p>Node-shell allows you to start a shell to access the underlying OS of a Kubernetes node.</p><p>This tool has been invaluable when developing observability tools for Kubernetes.</p><p>As I explain in my in-depth article <a href="https://cloudnativeengineer.substack.com/p/ep-2-kubernetes-node-shell">Kubernetes: node-shell</a>, more than a few times, I had to look at a Kubernetes node in order to tail pods/container logs that are written directly to the node host to feed into Elasticsearch.</p><p>I couldn't have done it without node-shell.</p><p>Node-shell, like many other tools in this list, can be installed via Krew and integrated into K9s.</p><h2><strong>Conclusion</strong></h2><p>The list of tools in this article is definitively incomplete.</p><p>I could have mentioned:</p><ul><li><p>Helm</p></li><li><p>Kustomize</p></li><li><p>K3d</p></li><li><p>Kind</p></li></ul><p>And many more.</p><p>Most of them are a bit more advanced and deserve an article on their own.</p><p>I might cover some of them in the future.</p><div><hr></div><h2><strong>&#127919; In case you missed</strong></h2><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;830d6ecc-7020-413f-9fb7-1040d0b4d1f3&quot;,&quot;caption&quot;:&quot;Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber. Introduction This article provides an introduction to the concept of sidecar containers in Kubernetes but also discusses some advanced use cases that even an experienced developer m&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Discover sidecar containers in Kubernetes&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-07-23T16:08:26.570Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9774ff52-d182-4baa-b66e-62d983dc3482_5603x3735.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ep-6-discover-sidecar-containers&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:135378853,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;3da85ac2-6959-491b-8c8d-30bf28879a12&quot;,&quot;caption&quot;:&quot;I recently passed my CKA exam and I would like to share with you some tips that might enable you to pass the exam. Here is my CKA certificate. If you are looking for books to prepare for the exam have a look at this other story I wrote. Booking You need to allow 24h from when you schedule an exam to when the exam can take place. This includes any possible &#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Tips and tricks to pass the Certified Kubernetes Administrator exam&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-04-02T17:30:34.835Z&quot;,&quot;cover_image&quot;:&quot;https://cdn-images-1.medium.com/max/800/0*ETVut7mj2JZduWdA&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/tips-and-tricks-to-pass-the-certified-kubernetes-administrator-cka-exam-38bf4be9e39c&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:130909647,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;79b47954-672e-41e7-a1b3-57007dd7025e&quot;,&quot;caption&quot;:&quot;These two concepts seem very much unrelated in other technical fields but when talking about Kubernetes containers you can reduce the first while improving the latter. For once you don&#8217;t have to choose between security and performance. &#8220;You can have your cake and eat it too&#8221;.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Shrink to Secure: Kubernetes and Compact Containers&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro &#128674;&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch), Blogger on Medium, Mentor on Mentorcruise, Book reviewer.\n\nhttps://bento.me/cloudnative-eng&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-06-23T21:11:19.845Z&quot;,&quot;cover_image&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*ZDoJgUCkzcNuXjRzQgtalA.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/shrink-to-secure-kubernetes-and-compact-containers-296b67d9975a&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:130909641,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><h2><strong>&#128483;&#65039; Shoutout</strong></h2><ul><li><p><a href="https://newsletter.finopsweekly.com/">FinOps Weekly</a> by my friend Victor Garcia.</p></li></ul><p>In his own words</p><blockquote><p>Optimize your Cloud Costs! Become a Master of understanding Billing and Optimizing Workloads. Join the FinOps Weekly and get the latest FinOps news every Sunday.</p></blockquote><div><hr></div><p>Are you ready to take your skills to new heights? &#128640;</p><p>&#128674; Let's embark on this journey together!&nbsp;</p><p>&#128099;&nbsp;Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a> to receive valuable content on AI, Kubernetes, System Design, Elasticsearch, and much more.&nbsp;</p><p>&#127891; If you&nbsp;want&nbsp;personalised guidance, I am here to support you. Book a mentoring session with me at&nbsp;<a href="https://mentors.to/gsantoro">https://mentors.to/gsantoro</a>&nbsp;on MentorCruise, and&nbsp;let's work together to unlock your full potential.&nbsp;</p><p>&#9851;&#65039; Remember, sharing is caring!&nbsp;If this content has helped you, please re-share it with others so&nbsp;they&nbsp;can&nbsp;benefit from it.&nbsp;</p><p>&#129321; Let's inspire and empower each other to reach new heights!</p>]]></content:encoded></item><item><title><![CDATA[Master Observability with Logs: An In-Depth Guide for Beginners]]></title><description><![CDATA[Episode #23: Dive into the world of observability with logs through this beginner-friendly in-depth guide. Gain valuable insights from real-world experience.]]></description><link>https://cloudnativeengineer.substack.com/p/master-observability-with-logs</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/master-observability-with-logs</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 29 Jun 2024 20:23:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GRoK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GRoK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GRoK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!GRoK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!GRoK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!GRoK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GRoK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2275034,&quot;alt&quot;:&quot;a beaver building a dam by collecting logs flowing down a river&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="a beaver building a dam by collecting logs flowing down a river" title="a beaver building a dam by collecting logs flowing down a river" srcset="https://substackcdn.com/image/fetch/$s_!GRoK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!GRoK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!GRoK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!GRoK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0d5a7cb-5e67-415a-9b9c-2828f27c6d7a_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A beaver building a dam by collecting logs flowing down a river. Image generated by the author with Midjourney</figcaption></figure></div><p>This is the second article I wrote about the basics of observability for beginners.</p><p>Previously, I have discussed how it's best to abandon print statements, or whatever primitive your programming language supports for writing to standard output, and move to proper observability with logs, metrics, and traces.</p><p>To learn more about this topic, head to <a href="https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements">Observability 101: A Beginner's Journey Free of Print Statements</a>.</p><p>I've also already introduced the concept of observability as a modern version of monitoring at <a href="https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging">Exploring Structured Logging with slog in Go</a>. </p><p>Here is an excerpt to refresh your memory</p><blockquote><p>You can think of observability like the 2020s version of monitoring, where the sheer amount of logs and metrics introduced with cloud-native distributed applications pose enormous scaling challenges on what you can collect, how much you can store, and what is just noise and can be discarded. These new challenges made us rethink the tools we use, introduce new ones or adapt the old ones.</p></blockquote><p>In this article, I would like to dive deeper into one of the three pillars of Observability: Logs.</p><p>Why start with Logs?</p><p>Logs are the most primitive form of observability.</p><p>You have already implemented some basic form of logging in your very first application and never called it observability.</p><p>In this article, you will discover the basics of logging, best practices and code snippets in Golang from the real-world knowledge I have collected during my career.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This article has the following sections:</p><ul><li><p>Logs and Observability</p></li><li><p>Logs vs Metrics</p></li><li><p>Logs vs Traces</p></li><li><p>Logs vs Print statements</p></li><li><p>Unstructured Logs</p></li><li><p>Structured logs</p></li><li><p>Log levels</p></li><li><p>Log context</p></li><li><p>Conclusion</p></li></ul><p>What is out of scope:</p><ul><li><p>Metrics and Traces</p></li><li><p>In-depth discussion about the benefits of observability</p></li><li><p>Log collection</p></li><li><p>Log analysis</p></li></ul><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9HnS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9HnS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 424w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 848w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1272w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png" width="240" height="238.08764940239044" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:240,&quot;bytes&quot;:394934,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9HnS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 424w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 848w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1272w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentors.to/gsantoro">Mentorcruise profile</a>.</p><h2><strong>Logs and Observability</strong></h2><p>The challenges introduced by cloud-native applications and modern software concepts like observability have changed how we write and collect logs in 2024 compared to 10 years ago.</p><p>The biggest challenge with logging is to maximise observability by increasing the log context size and the amount of logs produced while at the same time keeping the costs down.</p><p>Since the cost is directly proportional to the amount of text produced, you only want to log the relevant events that might help a developer investigate an error.</p><p>But how do you know what is relevant and what is not?</p><p>As with anything in computer science, there is a trade-off between storage cost and increasing observability.</p><p>In recent years, since storage is getting cheaper with time, most recent optimisations on logging have focused on reducing the amount of processing required to extract useful contextual information from logs more than the storage cost.</p><p>Hence, there is a shift from unstructured logs that need to be parsed and processed to machine-readable logs in JSON format ready to be stored.</p><p>Given the vast amount of logs that modern applications produce, logs are no longer something a software engineer can eyeball in real time to understand what the software is doing.</p><p>The recent trend is to use human-friendly colour-coded logs in console output for the development phase and switch to machine-readable logs in JSON format for production.</p><p>This requires that the output format might change depending on the environment the application runs in.</p><p>Changing the default log level between different environments is also common.</p><p>Those challenges require a shift from writing logs with print statements to a logging library that allows customising the behaviour according to the environment in which the application is running.</p><p>In the following sections, we will see practical implementations of the benefits of using a logging library over print statements by using code snippets in Golang.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/master-observability-with-logs?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Cloud Native Engineer. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/master-observability-with-logs?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/master-observability-with-logs?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Logs vs Metrics</strong></h2><p>How do Logs compare to the other pillars/signals of observability?</p><p>Metrics are collected at regular intervals (like with polling) even if the metric value hasn't changed from the last measurement.</p><p>Logs, instead, can happen at any time (similar to event-based systems).</p><p>From an observability point of view, log events (like for example errors) might happen less frequently than metrics measurements.</p><p>Unless you sample the logs, or logs go missing by mistake, no other event happens between two log events.</p><p>With metrics instead, you have no visibility of what happened between two consecutive metric collections.</p><p>You need to set the metrics frequency high enough not to miss important information but low enough to avoid high storage costs.</p><p>Metrics are generally more compact than logs.</p><p>Metrics have a predictable cost since if you know the size of a metric and its frequency, you can easily calculate the storage requirements in a given time frame. A small caveat is that the metric storage cost can get out of hand if you have metric labels that might cause a metric cardinality explosion.</p><p>More on this topic in a future article about metrics.</p><p>Logs at the right logging level and verbosity can be a lot cheaper than metrics since they are event-based, but log frequency is a lot less predictable.</p><p>You might have spikes in log cost exactly when you need it the most, meaning when errors occur.</p><p>The total cost of logging depends a lot on the verbosity of each log entry, the configured log level, and the frequency of events at that log level.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/master-observability-with-logs?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Cloud Native Engineer. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/master-observability-with-logs?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/master-observability-with-logs?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Logs vs Traces</strong></h2><p>Traces can be considered an enhanced version of logs with a specific fixed structure.</p><p>Traces are mainly used to track the duration of operations and how operations are nested within each other.</p><p>Distributed traces are an extension of such logs where you can connect a trace from an application running on a node with another application running on another. This way, you can have a more complete picture of what is involved in a user transaction in a microservice architecture.</p><h2><strong>Logs vs Print Statements</strong></h2><p>Logging has been used in history for many purposes, from a simple form of debugging to a primitive form of tracing (like getting the duration of a piece of code) to error reporting or even exposing system or application metrics.</p><p>Some common uses of logs are:</p><ul><li><p><strong>application logs</strong>, a log entry is created at every event in the application</p></li><li><p><strong>audit logs</strong>, capture events by recording who performed an activity, what activity and how the system responded (e.g. exit code or response code)</p></li><li><p><strong>infrastructure log</strong>, record events that happen to the infrastructure (e.g. lambda invocations on AWS cloud or a pod starting in Kubernetes)</p></li></ul><p>As I already discussed in a previous article <a href="https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements">Observability 101: A Beginner's Journey Free of Print Statements</a>, you should abandon print statements in favour of one or more of the three pillars of observability.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;1b829690-3c32-4301-a8ed-ce7f29d82bfe&quot;,&quot;caption&quot;:&quot;It doesn't matter what stage of your career you are currently in. At some point, you might have used Print statements to debug software. While you might have thought that was fine, I suggest that that's not a good practice you should adopt in 2024. This article should help ab&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Observability 101: A Beginner's Journey Free of Print Statements&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-06-09T21:39:48.621Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:145480963,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:3,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>In the following sections, I want to discuss in a bit more detail the benefits of a logging library over just using Print Statements with some real-world code snippets in Golang.</p><p>We will use code snippets that use a standard library called <a href="https://pkg.go.dev/golang.org/x/exp/slog">Slog</a>, which I previously covered in my article <a href="https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging">Exploring Structured Logging with slog in Go</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;e662b0cf-204e-4938-bcc0-d5c69283a385&quot;,&quot;caption&quot;:&quot;In this article, we will introduce the concept of Application Observability. Later, we are going to dive into logging and, more specifically, into structured logging. Finally, we will introduce the package called slog and explain why it is revolutionary for the Golang ecosystem.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Exploring Structured Logging with slog in Go&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-09-20T13:32:27.260Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ae5318e-2a44-4c3f-94ca-123888254731_5568x3712.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:137219726,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:3,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><h2><strong>Unstructured logging</strong></h2><p>Even in its simplest form of unstructured logging, using a library significantly simplifies the user experience.</p><p>The standard format for unstructured logs is as follows:</p><pre><code><code>{Timestamp} {log_level} {message}</code></code></pre><p>These three fields are present in various forms in every log entry.</p><p>The timestamp is automatically calculated from the library at the time of the function call, while the log level is encoded in the function call name.</p><p>In this specific library, the default log level is <code>Info</code>, so it can be omitted.</p><pre><code><code>package main

import (
    "log"
    "log/slog"
)

func main() {
    log.Print("Info message")
    // 2024/01/03 10:24:22 Info message

    slog.Info("Info message")
    // 2024/01/03 10:24:22 INFO Info message
}</code></code></pre><p>There is no standard format for the message field.</p><p>Given that each application has its format, if you want to extract useful bits of information from a Nginx web server logs, you should consult the application documentation to understand what regex to use to extract fields from plain text.</p><p>If you ingest Apache Web server logs, the regex format will be totally different.</p><p><strong>For expert only:</strong><br>Elastic, the company where I work, provides a complete Observability solution to collect, parse, and ingest unstructured logs from various famous applications thanks to <a href="https://www.elastic.co/integrations">integrations</a>.</p><p>Each integration is aware of the log format of the application that is observing and can extract useful bits of information from the message field.</p><p>Unstructured logs are automatically parsed by integrations into JSON logs to be ingested into Elasticsearch.</p><p>In my two years working in the Observability department at Elastic, I wrote an integration for Istio to parse proxy logs and Istiod logs. You can find this integration at <a href="https://www.elastic.co/docs/current/integrations/istio">Istio</a>.</p><h2><strong>Structured logging</strong></h2><p>Using a library instead of print statements allows the output format to be switched from unstructured to structured (in this case, JSON format) in a single place.</p><p>Logging, traditionally meant for the human eyes, has historically been unstructured.</p><p>In recent years, given the vast amount of logs generated by cloud-native applications and the need for more observability, it is slowly becoming more machine-friendly.</p><pre><code><code>package main

import (
    "log/slog"
)

func main() {
    opts := &amp;slog.HandlerOptions{
        Level: slog.LevelDebug,
    }

    handler := slog.NewJSONHandler(os.Stdout, opts)

    logger := slog.New(handler)
    
    logger.Info("Info message")
    // {"time":"2023-03-15T12:59:22.227408691+01:00",
    // "level":"INFO","msg":"Info message"}
}</code></code></pre><p>Applications that historically have using unstructured logging are transitioning to support both structured and unstructured logging, with JSON logging being the default option.</p><p><strong>For experts only:</strong><br>Elastic, can collect and ingest JSON logs without any parsing necessary. No need for integrations to parse the message field.</p><p>In support of what I mentioned above about the current trend to move to structured logs, Kubernetes has "recently" (in 2020) moved its application logs from unstructured text logs to structured JSON logs. More info at <a href="https://kubernetes.io/blog/2020/09/04/kubernetes-1-19-introducing-structured-logs/">Kubernetes introduce structured logging</a>.</p><h2><strong>Logging levels</strong></h2><p>Most logging libraries support changing the default logging level in a single statement.</p><p>The logging levels in order of importance from the most important are:</p><ul><li><p>Error</p></li><li><p>Warn or Warning</p></li><li><p>Info</p></li><li><p>Debug</p></li><li><p>Trace</p></li></ul><p>It is common to set the default logging level in production to WARN or WARNING in order to reduce the logging cost and use a Trace or Debug logging level while in development.</p><p>If you set the default logging level to WARN, any call to lower logging levels will be handled as a NoOp and print nothing to the standard output.</p><pre><code><code>package main

import (
    "log/slog"
)

func main() {
    opts := &amp;slog.HandlerOptions{
        Level: slog.LevelDebug,
    }

    handler := slog.NewJSONHandler(os.Stdout, opts)

    logger := slog.New(handler)
    logger.Debug("Debug message")
    logger.Info("Info message")
    logger.Warn("Warning message")
    
    logger.Error("Error message")
    // {"time":"2023-03-15T12:59:22.227472149+01:00",
    // "level":"ERROR","msg":"Error message"}
}</code></code></pre><h2><strong>Log context</strong></h2><p>Logging libraries can avoid code duplication when some logging context needs to be shared between multiple log events.</p><p>As described below, you can create a child logger with the common context and use that logger instead for the different events (e.g. Info and Warn events here). Both events will have fields shared from the common context.</p><pre><code><code>package main

import (
    "log/slog"
)

func main() {
    handler := slog.NewJSONHandler(os.Stdout, nil)
    buildInfo, _ := debug.ReadBuildInfo()

    logger := slog.New(handler)
    child := logger.With(
        slog.Group("program_info",
            slog.Int("pid", os.Getpid()),
            slog.String("go_version", buildInfo.GoVersion),
        ),
    )

    child.Info("image upload successful", 
        slog.String("image_id", "39ud88"))
    child.Warn("storage is 90% full",
        slog.String("available_space", "900.1 mb"),
    )
}</code></code></pre><h2><strong>Conclusion</strong></h2><p>Various Logging libraries can provide more features like hiding sensitive information (e.g. passwords or API keys) or adding stack traces when logging errors.</p><p>You can read more about Slog for Golang at <a href="https://betterstack.com/community/guides/logging/logging-in-go/#error-logging-with-slog">Logging in Go with Slog: The Ultimate Guide</a>.</p><p>I hope you enjoyed learning about logging and observability.</p><p>I might write future articles about the other pillars of Observability.</p>]]></content:encoded></item><item><title><![CDATA[Observability 101: A Beginner's Journey Free of Print Statements]]></title><description><![CDATA[Episode #22: Ready to level up your troubleshooting skills? Abandon your Print statements and embark on a long journey to master Observability.]]></description><link>https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sun, 09 Jun 2024 21:39:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9o80!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9o80!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9o80!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!9o80!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!9o80!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!9o80!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9o80!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2339205,&quot;alt&quot;:&quot;A software engineer watching wood logs floating down the river&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A software engineer watching wood logs floating down the river" title="A software engineer watching wood logs floating down the river" srcset="https://substackcdn.com/image/fetch/$s_!9o80!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!9o80!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!9o80!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!9o80!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2225b06-f820-4e92-8c1a-d523ceb72ef2_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Observing logs passing by the river. Image generated by the author with Midjourney</figcaption></figure></div><p>It doesn't matter what stage of your career you are currently in.</p><p>At some point, you might have used Print statements to debug software.</p><p>While you might have thought that was fine, I suggest that that's not a good practice you should adopt in 2024.</p><p>This article should help abandon Print statements in favour of some form of Observability.</p><p>Before we go any further, what is Observability?</p><blockquote><p>Observability pertains to how a system&#8217;s internal state can be understood by examining its external outputs, especially its data.</p></blockquote><p>Wait a second. You might argue that you have used logs and metrics in the past when it was still called Monitoring.</p><p>Is Observability just a different name? Is it just semantics? Why do we need a different term for Monitoring?</p><p>Logs are still logs, no matter what you call the practice of using them in your applications. Right?</p><p>We will discuss all of that in this article and more.</p><p>This article's audience spans from Junior Software Developers who have only used Print statements to more experienced Senior Software Engineers who want to brush up on best practices and get pointers to up their Observability game.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p>In this article:</p><ul><li><p>Meaning of the front page image</p></li><li><p>Print statements as a Poor Man's Observability solution</p></li><li><p>Application Observability</p></li><li><p>Short history of Observability</p></li><li><p>Conclusion</p></li></ul><p>What is out of scope:</p><ul><li><p>A deep dive into Logs, Metrics and Traces. I plan to cover those three pillars of Observability in future articles.</p></li><li><p>Error tracking, application profiles, crash dumps and other more advanced forms of Observability.</p></li><li><p>Libraries and tools to implement Observability.</p></li></ul><p></p><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9HnS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9HnS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 424w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 848w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1272w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png" width="240" height="238.08764940239044" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:240,&quot;bytes&quot;:394934,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9HnS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 424w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 848w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1272w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentors.to/gsantoro">Mentorcruise profile</a>.</p><p></p><h2><strong>Meaning of the front page image</strong></h2><p>A software engineer is sitting on the bank of the river, watching wood logs floating down the river.</p><p>Some logs get stuck on the river bank and never reach the bottom of the valley.</p><p>This is a metaphor for how not all logs are useful for getting to the root cause of an incident.</p><p>I generated the above picture with Midjourney using the prompt below.</p><blockquote><p>A software engineer on his laptop is immersed in nature on the bank of a river, watching wood logs being transported by the river current down to the valley. Use a comic style.</p></blockquote><p></p><h2><strong>Print statements as a Poor Man's Observability tool</strong></h2><p>Countless articles for beginners suggest using Print statements to debug software.</p><p>In the rest of this article, by Print statement, I assume that in your language of choice, there is a way to print text to the standard output. It doesn't matter what the API looks like; for me, this will always be a practice to avoid as much as possible.</p><p>I don't suggest using Print statements, even if you are starting your journey into Software Engineering now.</p><p>The reason is that, especially at the beginning, once you learn to use a tool, you might use it everywhere. The famous phrase <code>if all you have is a hammer, everything looks like a nail</code> couldn't be more accurate in this case.</p><p>Instead of wasting time with print statements, they should teach some form of logging straight away.</p><p>As I have already discussed in my article <a href="https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging">Exploring Structured Logging with slog in Go</a>, the bare minimum in logging should be using a logging library for structured logs. We will discuss logging more in the future.</p><p>Spending extra time implementing some form of Observability or even just using a debugger with breakpoints always pays dividends in the long term.</p><p>I find it even more troubling when Senior or even Principal Engineers still suggest using Print statements because it is the easiest option over more complex setups like debuggers or logs.</p><p>Observability is still hard to master.</p><p>Hopefully, with this article, we can make things clearer.</p><p>There are many ways a print statement should be replaced with better Observability options:</p><ul><li><p>Tracking a specific event (e.g. an error or a warning) =&gt; Logs</p></li><li><p>Counting the number of times an event occurs (e.g. number of times a web application receives a request) =&gt; Metrics</p></li><li><p>Timing the duration of a function (e.g. how long does it take to query a database?) =&gt; Traces</p></li><li><p>Printing error Stacktraces =&gt; Error tracking software</p></li><li><p>Checking the internal state of variables while developing =&gt; Debugger with breakpoints</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/observability-101-free-of-print-statements/comments"><span>Leave a comment</span></a></p><h2><strong>Application Observability</strong></h2><p>In this and future articles about Observability, we will primarily focus on application observability, even though the basic concepts are the same for other forms of Observability, like infrastructure observability.</p><p>Every Cloud-Native Engineer should be very familiar with application observability and at least have a basic understanding of infrastructure observability since he/she will probably be involved in deploying apps on the cloud.</p><p>The concept of application observability was popularised by Etsy&#8217;s John Allspaw and Paul Hammond in 2003, but 20 years later, it is still somewhat misunderstood.</p><p>I briefly discussed application observability in a previous article titled <a href="https://cloudnativeengineer.substack.com/p/ep-9-exploring-structured-logging">Exploring Structured Logging with slog in Go</a>.</p><p>A quote from that article:</p><blockquote><p>You can think of Observability like the 2020s version of Monitoring, where the sheer amount of logs and metrics introduced with cloud-native distributed applications pose some huge scaling challenges on what you can collect, how much you can store, and what is just noise and can be discarded. These new challenges made us rethink the tools we use, introduce new ones or adapt the old ones.</p></blockquote><p></p><h2><strong>Short History of Observability</strong></h2><p>I can imagine that it all started with a Print statement, the most basic way to observe an application's internal state.</p><p>As discussed in this article, before Observability was a thing, we used to call the practice of using logs and metrics in our applications Monitoring.</p><p>So where does Observability come from, and why does it differ from Monitoring?</p><p>An in-depth discussion of the reasons Observability is different from Monitoring is outside the scope of this article. Here, I just want to mention some of those reasons that are more relevant to my audience.</p><p>Before the cloud-native movement started, there was a much clearer distinction between developers and System Administrators.</p><p>Once you were done writing the application code as a developer, you would metaphorically throw it over the fence to be deployed and monitored in production by a different set of people.</p><p>With the arrival of cloud-native applications, developers are now responsible not just for writing the code but also for deploying it to production, keeping it running via on-call rotations, and investigating issues via root cause analysis.</p><p>Things get very complicated when the application is not a process running on a single machine but a bundle of microservices running on multiple machines on the cloud. This is what is now called a cloud-native application.</p><p>It was about time that I covered observability in this newsletter.</p><p>What worked in the past with monitoring, doesn't scale anyone with tens, hundreds or even thousands of microservices talking to each other over the network.</p><p>What was before a local syscall is now a network call.</p><p>New types of applications call for different challenges and different ways of doing things. Hence, the move from monitoring to observability.</p><p>It's not just semantics. It is a different discipline, with its own practices, challenges, and tools.</p><p>The essential components, the three pillars (also called the three signals) logs, metrics and traces might be the same, but how they are implemented, interconnected, and processed in different ways.</p><p>You must keep observability in mind from the beginning when designing your applications.</p><p>Otherwise, if you are not careful, you may experience a cardinality explosion and some hefty bills at the end of the month.</p><p>Observability can't be an afterthought; otherwise, it will bite you when an incident happens, as you won't have all the information you need to investigate the root cause.</p><p>For more information about Observability, I highly recommend the book <a href="https://www.oreilly.com/library/view/observability-engineering/9781492076438/">Observability Engineering</a>.</p><p>If you are instead into a more practical approach to learning about the three pillars of observability and how to implement them into your application, have a look at the <a href="https://github.com/cncf/tag-observability/blob/main/whitepaper.md">Observability whitepaper</a> by the CNCF.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share&quot;,&quot;text&quot;:&quot;Share Cloud Native Engineer&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share Cloud Native Engineer</span></a></p><h2><strong>Conclusion</strong></h2><p>In this article, we just scratched the surface of what observability is and why it is necessary.</p><p>I plan to cover each pillar of observability (Logs, metrics, and Traces) in its own article so that I have enough space to suggest best practices and tools.</p><p>Furthermore, I would also like to discuss some other forms of observability that go beyond those three pillars, like debugging, application profiles, and crash dumps.</p><p>In the interest of brevity, I prefer to split the discussion into multiple articles.</p>]]></content:encoded></item><item><title><![CDATA[Goodbye Dependency Headaches: Discover the Power of Pipx for Python Package Management]]></title><description><![CDATA[Episode #21: Escape Python dependency hell with Pipx by creating an isolated virtual environment for each application.]]></description><link>https://cloudnativeengineer.substack.com/p/goodbye-python-dependency-hell-with-pipx</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/goodbye-python-dependency-hell-with-pipx</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sun, 05 May 2024 22:26:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XKPU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XKPU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XKPU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!XKPU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!XKPU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!XKPU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XKPU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2168745,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XKPU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!XKPU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!XKPU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!XKPU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F332a01e2-2a62-4ec0-8f25-fc57b4a57dac_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Escaping the dependency hell with Pipx - Generated with Midjourney</figcaption></figure></div><p>If you have been a Software Developer as long as I have (more than ten years now), you might have encountered dependency hell at some point in your career.</p><p>If you haven't (lucky you), let me introduce the concept:</p><blockquote><p><strong>Dependency hell</strong> describes the complex web of software dependencies that can arise, making it challenging to install, update, or run applications due to version conflicts and compatibility issues. It is a common problem in software development and deployment, especially across different platforms and ecosystems.</p></blockquote><p>As the term describes, it is not a great state of mind.</p><p>Software Engineers have written entire programming languages and countless tools out of the frustration of dealing with some sort of dependency hell.</p><p>In this article, I would like to describe my recent experience of dependency hell in Python and how I solved the problem once and for all&#8212;at least, I hope.</p><p>I'll introduce a tiny tool called <a href="https://github.com/pypa/pipx">Pipx</a>, which allows you to install a CLI Python application (and its dependency) in a totally isolated virtual environment, avoiding any dependency conflict.</p><p>I&#8217;ll explain how to use Pipx and what are its benefits over Pip and other similar tools.</p><p>This article is specifically tailored for Python developers, both experienced and inexperienced.</p><p>Whether you're a seasoned pro or just starting out, the insights and solutions I'll be sharing can be invaluable in your Python development journey.</p><p>As a Python developer, I hope you can gain valuable insights from this article that you might apply at some point in your career, further enhancing your skills and knowledge.</p><p>In this article:</p><ul><li><p>Meaning of the front page image</p></li><li><p>&#128176; (paid content) My encounter with Pipx</p></li><li><p>&#128176; (paid content) What is Pipx?</p></li><li><p>&#128176; (paid content) Pip vs Pipx</p></li><li><p>&#128176; (paid content) How to get started</p></li><li><p>&#128176; (paid content) Example usage</p></li><li><p>&#128176; (paid content) Pipx run</p><p></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Meaning of the front page image</strong></h2><p>When exploring a Midjourney prompt for this article, I wanted to convey the concept of "Dependency Hell".</p><p>What better metaphor for Dependency Hell than a sea of lava?</p><p>So, a Python snake avoids the sea of lava (the dependency hell) by crawling over a precarious tree log hanging above it.</p><p>I generated the above picture with Midjourney using the prompt below.</p><blockquote><p>A vibrant, comic-book inspired image of a green Python snake slithering across a weathered log, its head tilted curiously as it navigates a fiery, lava-filled chasm beneath.</p></blockquote><p></p><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9HnS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9HnS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 424w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 848w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1272w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png" width="240" height="238.08764940239044" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:240,&quot;bytes&quot;:394934,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9HnS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 424w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 848w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1272w, https://substackcdn.com/image/fetch/$s_!9HnS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1844ea5b-40e0-4982-abbe-4a9f1bf6a278_1004x996.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentors.to/gsantoro">Mentorcruise profile</a>.</p><h2><strong>My encounter with Pipx</strong></h2><p>My first (and most horrific) experience of dependency hell goes back to the time that I was writing Java code early on in my professional career.</p><p>Things didn't change much later when I began writing Scala code (mainly for Spark) but it got a lot better when after a few years I started writing Python code.</p><p>I love creating virtual environments in Python to isolate each project I am working on.</p><p>So, I stayed away from dependency hell for a while.</p><p>Last week, I had my first experience of dependency hell in Python. I had to install at least four different CLI applications in Python.</p><p>As usual, I added them all to my <a href="https://python-poetry.org/">Poetry</a> config. Soon, Poetry started complaining that those tools were using incompatible library versions.</p><p>As years of experience solving similar problems in Java taught me, I started checking if there was a way to solve those conflicts, but after 30 minutes of struggling, I gave up.</p><p>Since I knew the maintainers of those tools, I reached out to check if they were willing to update one ancient legacy dependency library. I even opened a public GitHub issue to get this fixed.</p><p>To my surprise, they suggested I use a separate virtual environment for each tool.</p><p>My first thought was... Are you crazy? One virtual environment for each of those? It will take me ages to set everything up. Are you sure you cannot upgrade this tiny dependency? I could fork the tool and update it myself; that would have been much faster, but potentially, it could still have taken hours.</p><p>After a few minutes of complaining, they finally suggested a tool I never heard of: Pipx.</p><p>What the hell is pipx? was my first reaction. I have never heard of it.</p><p>Surprisingly, this tool did precisely that: installing each Python CLI application in an isolated virtual environment.</p><p>Here I am, with this new piece of knowledge, trying to teach you about the benefits of Pipx for your Python development.</p><h2><strong>What is Pipx?</strong></h2><p><a href="https://github.com/pypa/pipx">Pipx</a> simplifies your life by enabling you to install CLI applications written in Python (and their dependencies) in isolated virtual environments.</p><p>It's as easy as <code>pipx install &lt;package&gt;</code>.</p><p>It creates one virtual environment for each CLI application to avoid dependency conflicts.</p><p>It looks similar to <code>brew</code> or other package managers you might have used in different languages.</p><p>Between the benefits, you can count on a clean uninstall of your packages, no need to use <code>sudo</code> to install global packages and the ability to list packages already installed by <code>pipx</code>.</p><p>Behind the scenes, <code>pipx</code> uses the Python module <code>venv</code> to create a virtual environment and <code>pip</code> to install those dependencies.</p><p>Those virtual environments are installed under a fixed location, <code>~/.local/share/pipx/venvs/&lt;package&gt;</code>, and the Python applications installed have symlinks added to the <code>~/.local/bin</code>.</p><p>Those two locations differ on Windows but are the same on macOS and Linux.</p><p>More information about <code>pipx</code> can be found at the <a href="https://github.com/pypa/pipx">pipx&#8212;GitHub repository</a>.</p><h3><strong>Some GitHub stats</strong></h3><p>Pipx is open source and actively developed at the time of writing.</p><p>It counts 146 contributors and 8.9k GitHub stars.</p><p>The number of stars has grown exponentially since the beginning of the year.</p><p>The latest version <a href="https://github.com/pypa/pipx/releases/tag/1.5.0">1.5.0</a> has been released on&nbsp;Mar 29, 2024.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s-57!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s-57!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 424w, https://substackcdn.com/image/fetch/$s_!s-57!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 848w, https://substackcdn.com/image/fetch/$s_!s-57!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!s-57!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s-57!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png" width="1456" height="1040" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1040,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:136497,&quot;alt&quot;:&quot;Graph of GitHub Stars for Pipx &quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Graph of GitHub Stars for Pipx " title="Graph of GitHub Stars for Pipx " srcset="https://substackcdn.com/image/fetch/$s_!s-57!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 424w, https://substackcdn.com/image/fetch/$s_!s-57!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 848w, https://substackcdn.com/image/fetch/$s_!s-57!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!s-57!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb177623a-1027-4866-9ce8-f531d8c40588_1832x1308.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Star history of pipx project - Generated on https://star-history.com/</figcaption></figure></div><p></p><h2><strong>Pip vs Pipx</strong></h2><p>As the name implies, "Pipx" has a similar purpose to Pip.</p><p>The main difference is that while Pip installs a package globally or in the current virtual environment, Pipx instead creates a new virtual environment for each package and then adds a symlink to the package entry point to a dedicated location.</p><p>Similarly to Pip, Pipx installs packages from PyPi by default, but it can optionally install from Git repositories, folders, and any other place Pip can install from.</p><h2><strong>How to get started</strong></h2><p>Getting started with Pipx is quite simple.</p><p>You install the tool first, then add the default location <code>~/.local/bin</code> to your PATH, and finally, install your packages.</p><p>Installing pipx varies for all operating systems.</p><p>If you, like me, are a MacOS user, you can use <code>brew</code> to install pipx. Otherwise, for Linux, you can use one of the many package managers for your operating system.</p><p>Warning: Installing <code>pipx</code> with <code>pipx</code> is not suggested.</p><p>The <a href="https://pipx.pypa.io/stable/">pipx official documentation</a> provides more information on how to install <code>pipx</code>.</p><h2><strong>Example usage</strong></h2><p>Let's say you are installing the famous Python formatter called <a href="https://github.com/psf/black">Black</a>.</p><p>How would you install this package? And what does it get created under the hood?</p><p>You can install Black with Pipx using the command:</p><pre><code><code>pipx install black</code></code></pre><p>Behind the scenes, Pipx will go through these three steps:</p><ol><li><p>Creates a virtual environment via the Python module <code>venv</code> at <code>~/.local/share/pipx/venvs/black</code></p></li><li><p>Install the package and its dependencies in that venv</p></li><li><p>Create a symlink at <code>~/.local/bin/black</code> to the command installed at <code>~/.local/share/pipx/venvs/black/bin/black</code></p></li></ol><p>Since <code>pipx ensurepath</code> has already added the location "~/.local/bin" to your PATH, the command <code>black</code> should be available immediately.</p><h2><strong>Pipx run</strong></h2><p>Pipx allows you to avoid installing a package if you only need to run a command once.</p><p>Instead of using, <code>pipx install &lt;package&gt;</code>, you can use <code>pipx run &lt;package&gt; &lt;package params&gt;</code>.</p><p>This command will create a temporary virtual environment that will be destroyed when the command finishes running.</p><p>I love this feature since it reminds me how Nix shell works.</p><p>If you want only run a command in Nix once without installing it, you can run <code>nix-shell -p &lt;command&gt; --run &lt;command and params&gt;</code></p><pre><code>nix-shell -p jq --run jq .</code></pre><p>If you have never heard of Nix before I have written an article about it at <a href="https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix">Effortless Python Development with Nix</a>.</p><p>This article explains how I use Nix to install Python, create a virtual environment, install Poetry and much more.</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Taking April off]]></title><description><![CDATA[Taking a short break from writing to recharge my batteries]]></description><link>https://cloudnativeengineer.substack.com/p/taking-april-off</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/taking-april-off</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Thu, 11 Apr 2024 20:47:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0A6B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dear subscribers,</p><p>I am writing to inform you that I will be taking a break from writing until the end of the month in order to recharge mentally. </p><p>Thank you for your understanding.</p><p>I have not been very active in the past few weeks as I have been busy with the technical review of a book being written by my colleagues, Huage Chen and Yazid Akadiri.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0A6B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0A6B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0A6B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0A6B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0A6B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0A6B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg" width="1216" height="1500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1500,&quot;width&quot;:1216,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101586,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0A6B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0A6B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0A6B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0A6B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4582300-ce68-41c7-8d68-5b3671699de8_1216x1500.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Elastic Stack 8.x Cookbook</figcaption></figure></div><p>The book should be available in a couple of months at <a href="https://www.amazon.co.uk/Elastic-Stack-8-x-Cookbook-visualization/dp/1837634297">Elastic Stack 8.x Cookbook</a>.</p><p>It took me a considerable amount of time to do this technical review, so I am quite exhausted.</p><p>You might ask. What is involved in a technical review?</p><p>I didn&#8217;t know either before starting this one.</p><p>It required me to read the entire book, verify the accuracy of the content, and ensure that all of the code was functioning properly.</p><p>As this particular book is a cookbook, it involved practical applications and required me to run the Elastic stack on the cloud while learning about almost all of the services within the stack.</p><div><hr></div><h2><strong>&#128218;</strong>Recommendations</h2><ul><li><p><a href="https://theramenbowl.substack.com/">The Ramen Bowl</a> - If you are a foody like me, you can&#8217;t miss this food-related substack from my friend <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;The Ramen Bowl&quot;,&quot;id&quot;:137985218,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0534f625-80d8-4698-af8d-0c9f545773ed_1024x1024.png&quot;,&quot;uuid&quot;:&quot;abd8bc58-f514-4c9c-991d-71cd6602390f&quot;}" data-component-name="MentionToDOM"></span> . He doesn&#8217;t talk about Ramen only. He has been branching off to sweets and ingredients from Asian cuisine.</p></li></ul><div class="embedded-publication-wrap" data-attrs="{&quot;id&quot;:1544781,&quot;name&quot;:&quot;The Ramen Bowl&quot;,&quot;logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb90f26-1617-496a-ba9d-472de72a5aa4_1024x1024.png&quot;,&quot;base_url&quot;:&quot;https://theramenbowl.substack.com&quot;,&quot;hero_text&quot;:&quot;All things Ramen and Japanese-inspired cuisine from a foodie nerd.\nGet bi-weekly posts with stories, recipes, and experiments - &#9697; -&quot;,&quot;author_name&quot;:&quot;The Ramen Bowl&quot;,&quot;show_subscribe&quot;:true,&quot;logo_bg_color&quot;:&quot;#FFFBF6&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="EmbeddedPublicationToDOMWithSubscribe"><div class="embedded-publication show-subscribe"><a class="embedded-publication-link-part" native="true" href="https://theramenbowl.substack.com?utm_source=substack&amp;utm_campaign=publication_embed&amp;utm_medium=web"><img class="embedded-publication-logo" src="https://substackcdn.com/image/fetch/$s_!Wf-6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffb90f26-1617-496a-ba9d-472de72a5aa4_1024x1024.png" width="56" height="56" style="background-color: rgb(255, 251, 246);"><span class="embedded-publication-name">The Ramen Bowl</span><div class="embedded-publication-hero-text">All things Ramen and Japanese-inspired cuisine from a foodie nerd.
Get bi-weekly posts with stories, recipes, and experiments - &#9697; -</div></a><form class="embedded-publication-subscribe" method="GET" action="https://theramenbowl.substack.com/subscribe?"><input type="hidden" name="source" value="publication-embed"><input type="hidden" name="autoSubmit" value="true"><input type="email" class="email-input" name="email" placeholder="Type your email..."><input type="submit" class="button primary" value="Subscribe"></form></div></div><p></p><div><hr></div><h2>&#127919;In case you missed it&#8230;</h2><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;b53d985c-8cde-4d83-9654-98982c7f2045&quot;,&quot;caption&quot;:&quot;This article is my second piece on Taskfile. My first article Taskfile: a modern alternative to Makefile went viral (at least for my standards). Here you have some stats: 95 points and 212 comments on HackerNews 10k views and 31 new subscribers on Substack (this newsletter).&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Supercharge Your Automation Workflows with Taskfile: Say Goodbye to Makefile&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-03-17T19:05:42.507Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:142696718,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4824a667-c636-4af0-a70f-df5f8bea48bd&quot;,&quot;caption&quot;:&quot;If you ask 100 developers how they set up their Python development environment, getting many different answers is not uncommon. Why hasn't the problem been solved yet? In the last decade, many tools have promised to simplify your life. At best, they solve one issue and introduce many more.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Effortless Python Development with Nix&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-02-18T00:28:29.202Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d927bed-c1f3-45f1-9313-694f0383ba5a_990x994.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:141779798,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;aa6201e0-c1cf-434b-b3ae-1abf58a61960&quot;,&quot;caption&quot;:&quot;If you are a busy software engineer, you can't spend weeks thinking about the best solution for the job and then learning those tools. Let me help make this choice much more manageable. In this article, we will discuss SQLite, which I believe is the best tool for data analysis for relatively small datasets.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Unlock SQLite: Easy Data Analysis for Busy Software Engineers&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-03-09T12:24:05.327Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/easy-data-analysis-for-busy-software-engineers&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:142447458,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><h2>&#128302;Future articles</h2><p>I&#8217;m planning to write more about:</p><ul><li><p>Elastic Stack (given that I learned some nice tricks from my book review)</p></li><li><p>DevOps tools like <a href="https://www.crossplane.io/">Crossplane</a>. </p></li><li><p>Container security tools like <a href="https://snyk.io/">Snyk</a>.</p></li></ul><div><hr></div><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p>]]></content:encoded></item><item><title><![CDATA[Supercharge Your Automation Workflows with Taskfile: Say Goodbye to Makefile]]></title><description><![CDATA[Episode #20: Why is Taskfile an attractive alternative to Makefile for beginners and more advanced users alike?]]></description><link>https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sun, 17 Mar 2024 19:05:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ywb0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ywb0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ywb0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Ywb0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Ywb0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Ywb0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ywb0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1636548,&quot;alt&quot;:&quot;Humanoid robots working on a assembly line&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Humanoid robots working on a assembly line" title="Humanoid robots working on a assembly line" srcset="https://substackcdn.com/image/fetch/$s_!Ywb0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Ywb0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Ywb0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Ywb0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F680a54f9-e7b9-4eb0-aef8-f01d3ca924c9_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Assembly line - Generated with Midjourney</figcaption></figure></div><p>This article is my second piece on Taskfile.</p><p>My first article <a href="https://cloudnativeengineer.substack.com/p/ep-5-taskfile-a-modern-alternative">Taskfile: a modern alternative to Makefile</a> went viral (at least for my standards).</p><p>Here you have some stats:</p><ul><li><p>95 points and 212 comments on <a href="https://news.ycombinator.com/item?id=36744450">HackerNews</a></p></li><li><p>10k views and 31 new subscribers on Substack (this newsletter).</p></li><li><p>3.6k views and 2k reads on Medium where I cross-posted the article.</p></li></ul><p>Makefile is a fascinating and controversial topic that sparks passionate debates.</p><p>Individuals have diverse and firm opinions on the matter.</p><p>The debate on HackerNews became quite intense very quickly. Both sides presented their hot takes&#8212;the supporters of Makefile and those who dislike it but have yet to discover a better alternative.</p><p>This article is directed towards the latter group.</p><p>If you strongly favour Makefile and are unwilling to consider counterarguments, please refrain from reading further.</p><p>However, this article may interest you if you dislike Makefile and have been searching for a suitable alternative for years.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Want to&nbsp;connect?</strong></h2><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, feel free to check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p><div><hr></div><h2><strong>What is Taskfile?</strong></h2><p><a href="https://taskfile.dev/">Task</a> (the name says already) is a task runner written in Golang that adopts a YAML-like syntax called Taskfile for writing tasks and their dependencies.</p><div class="paywall-jump" data-component-name="PaywallToDOM"></div><p>I understand that Task is the name of the tool and Taskfile is the format, but I use the terms interchangeably as people do with Make and Makefile. So keep that in mind when reading the rest of this article.</p><p>I already know what people are going to say about Taskfile.</p><p>YAML again! YAML is everywhere and... I hate it!</p><p>I am not a huge fan of YAML either, but in this case, YAML doesn't get in the way.</p><p>Some stats about Task's adoption</p><ul><li><p>9.8k stars. When I wrote my first article, there were 8k stars. As you can see from the graph below, they are increasing exponentially in time.</p></li><li><p>159 contributors (including me). I have created some GitHub issues in the past and started discussions.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jeFk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jeFk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 424w, https://substackcdn.com/image/fetch/$s_!jeFk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 848w, https://substackcdn.com/image/fetch/$s_!jeFk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!jeFk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jeFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png" width="1456" height="1040" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1040,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:138228,&quot;alt&quot;:&quot;Graph of GitHub Stars for Task project&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Graph of GitHub Stars for Task project" title="Graph of GitHub Stars for Task project" srcset="https://substackcdn.com/image/fetch/$s_!jeFk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 424w, https://substackcdn.com/image/fetch/$s_!jeFk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 848w, https://substackcdn.com/image/fetch/$s_!jeFk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 1272w, https://substackcdn.com/image/fetch/$s_!jeFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50ee377e-eccf-438c-bea6-6a8ac7c8c3b0_1832x1308.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">GitHub Star history of Task project - Generated on https://star-history.com/</figcaption></figure></div><h2><strong>Taskfile vs Makefile</strong></h2><p>I have to say that comparing Taskfile and Makefile is somehow unfair.</p><p>Makefile has been around for almost 50 years and is widely used by a vast community. Taskfile has only been around for about 6 years and has a much smaller user group.</p><p>What is terrible about Makefile?</p><ul><li><p>Hard to write and read.</p></li><li><p>Not user-friendly for beginners.</p></li><li><p>Documentation is extensive but very hard to search.</p></li><li><p>Cannot easily list targets.</p></li><li><p>It doesn't support attaching a help description to a target. You need to look into the Makefile source to understand what the target is meant to be doing.</p></li><li><p>Hard to break a Makefile into multiple files.</p></li><li><p>If a target is not a filename, you need to label that target as <code>PHONY</code>.</p></li><li><p>Targets (hence filenames of the source code to build) have some legacy limitations. No spaces, no colons, etc.</p></li></ul><p>Makefile was initially conceived to be a build system and is very good at it, but when used as a task runner, it is not a very ergonomic tool.</p><p>When compared to more modern building tools like <a href="https://gruntjs.com/">Grunt</a>, <a href="https://github.com/rust-lang/cargo">Cargo</a>, or <a href="https://maven.apache.org/">Maven</a>, respectively, for Javascript, Rust, and Java, Makefile feels like ancient history and should be replaced with something better.</p><p>What do Makefile and Taskfile have in common?</p><ul><li><p><strong>Single binary</strong>. Any other solution based on interpreted languages (like Python) is more challenging to use.</p></li><li><p><strong>Runs everywhere</strong> on all Operating Systems thanks to its single binary nature.</p></li><li><p><strong>Small</strong> wrapper around command line tools.</p></li></ul><p>Why is Taskfile better than Makefile?</p><p>Some reasons in no particular order:</p><ul><li><p><strong>Simple</strong> to read/write and friendly to newcomers.</p></li><li><p><strong>Great documentation</strong>. Not extensive, but good enough.</p></li><li><p>Simple to break a Taskfile into multiple files and import other Taskfiles as dependencies</p></li><li><p>You can list the available tasks or see a <strong>short description</strong> of a task or a more extended <strong>summary</strong>.</p></li><li><p>Easy templating with <strong>Go templates</strong>.</p></li><li><p><strong>Dry-run mode</strong> allows printing the shell commands that make a task and easily reproducing the results elsewhere without a Task.</p></li><li><p><strong>Cross-platform shell interpreter</strong> (it works for Windows, too).</p></li><li><p>Public vs private (aka <strong>internal) tasks</strong>.</p></li><li><p>You can <strong>defer</strong> a command to run after the end of the task.</p></li><li><p><strong>Watch</strong> feature. It can rerun a task when it detects that a list of files has changed. More on this later.</p></li></ul><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thank you for reading Cloud Native Engineer. This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/p/say-goodbyte-to-makefile?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2><strong>Feedback from my first article</strong></h2><p>As stated already, my article <a href="https://cloudnativeengineer.substack.com/p/ep-5-taskfile-a-modern-alternative">Taskfile: a modern alternative to Makefile</a> raised quite a few comments on <a href="https://news.ycombinator.com/item?id=36744450">HackerNews</a>.</p><p></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;4c15254e-df81-4e63-aece-18b8c91d64de&quot;,&quot;caption&quot;:&quot;Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber. Introduction I meant to write this post for a while now, but I never thought many people would read it. I'm writing it now for those few people brave enough to try something new around autom&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Taskfile: a modern alternative to Makefile&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-07-15T17:00:18.720Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b3d6874-886e-43d3-865f-cb74b7c827f2_2030x1522.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ep-5-taskfile-a-modern-alternative&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:134951085,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:4,&quot;comment_count&quot;:9,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>I'm sorry if I upset some people in the process.</p><p>The passage highlighted below caused most of the discontent.</p><blockquote><p>As anyone that writes or interacts with software these days, I need to run automation scripts every day but I am still stuck with a tool that (according to&nbsp;<a href="https://en.wikipedia.org/wiki/Make_(software)">Wikipedia</a>) has been written 47 years ago. Don't get me wrong, Makefile was really useful 20 years ago but I think we can do better than that in 2023.</p></blockquote><p>Someone commented:</p><blockquote><p>[Makefile is...] ...Proof tested because it has been used for 47y.</p></blockquote><p>I agree with that point, but that is not motivation enough to not develop a more modern alternative that better serves the needs of the 21st century.</p><p>I realise now that almost 50 years of use have created pockets of fanatic users that are hard to convince.</p><p>Even though, I got some positive feedback from HackerNews as follows:</p><blockquote><p>Make is much the same way. It gets the job done, that doesn&#8217;t mean it&#8217;s good at getting the job done when better alternatives exist.</p><p>The attitude of &#8220;well it should be hard, the shouldn&#8217;t even learn C if they can&#8217;t handle make&#8221; is explains why my students love Rust so much. Rust has a sane and standardised build system they prefer to use. Make is the Stone Age to them.</p><p>I&#8217;m just saying Make is an issue for a lot of reasons like accessibility and portability to multiple toolchains and systems</p></blockquote><p>I won't mention the more negative comments here since some are not very productive, but I suggest you have a look if you're interested.</p><p>Here is my strong opinion about the topic of hardcore fanatics about Makefile. I believe people who are unhappy about Makefile but still use it somehow suffer from Stockholm syndrome.</p><blockquote><p>Stockholm syndrome is&nbsp;<strong>a proposed condition or theory that tries to explain why hostages sometimes develop a psychological bond with their captors</strong></p></blockquote><p>My article on Taskfile inspired my friend Edoardo Tenani to write a piece on the same topic titled <a href="https://endorama.dev/2023/to-make-or-not-to-make/">To make or not to make</a>.</p><p>I share most of the opinions in that article, and I think Edo made some excellent points.</p><blockquote><p>[Makefile...] ...may also be ... affected by &#8220;we always do it like that&#8221; or &#8220;no one has ever been fired for buying IBM&#8221; and this is a culture I&#8217;m more than happy to abandon.</p><p>Make is far from perfect&nbsp;<strong>when used as a task runner</strong>, something it has not been designed for.</p></blockquote><p>More recently, I watched a video by Viktor Farcic on the benefits of Taskfile vs Makefile called <a href="https://www.youtube.com/watch?v=Z7EnwBaJzCk">Say Goodbye to Makefile - Use Taskfile to Manage Tasks in CI/CD Pipelines and Locally</a></p><div id="youtube2-Z7EnwBaJzCk" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;Z7EnwBaJzCk&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/Z7EnwBaJzCk?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>The video highlights the importance of being able to run the same tasks on both your laptop and your CI system.</p><p>To achieve consistency, the suggestion is to use Taskfile for all your tasks and wrap it around a GitHub action that sets up Taskfile itself.</p><p>This is an alternative to tools like <a href="https://github.com/nektos/act">Act</a> that allow you to run GitHub workflows locally. In fact, these tools can only partially replicate GitHub actions on your laptop.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?coupon=f6ff5849&amp;utm_content=142696718&quot;,&quot;text&quot;:&quot;Get 20% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/subscribe?coupon=f6ff5849&amp;utm_content=142696718"><span>Get 20% off for 1 year</span></a></p><h2><strong>Resources</strong></h2><p>I have mentioned Taskfile in one of my latest paid articles, <a href="https://cloudnativeengineer.substack.com/p/easy-data-analysis-for-busy-software-engineers">Unlock SQLite: Easy Data Analysis for Busy Software Engineers</a>. </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;55c0e94d-c9fb-4c6f-a4a5-9103f601d5bc&quot;,&quot;caption&quot;:&quot;If you are a busy software engineer, you can't spend weeks thinking about the best solution for the job and then learning those tools. Let me help make this choice much more manageable. In this article, we will discuss SQLite, which I believe is the best tool for data analysis for relatively small datasets.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Unlock SQLite: Easy Data Analysis for Busy Software Engineers&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-03-09T12:24:05.327Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa46622a3-43aa-41fd-839b-d82ba54833a4_1024x1024.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/easy-data-analysis-for-busy-software-engineers&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:142447458,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>You can find the relative taskfiles to install SQLite extensions and analyse some CSV files at the GitHub repository <a href="https://github.com/gsantoro/demos/tree/main/weather-sqlite">Demos</a>.</p><p>In the same original article about Taskfile, I also wrote about other automation tools like DevEnv and Direnv that together with Taskfile are part of all my projects. If you are interested more in those technologies instead, look at <a href="https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix">Effortless Python Development with Nix</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a38777e8-e99e-4602-8ffe-b46642ac6684&quot;,&quot;caption&quot;:&quot;If you ask 100 developers how they set up their Python development environment, getting many different answers is not uncommon. Why hasn't the problem been solved yet? In the last decade, many tools have promised to simplify your life. At best, they solve one issue and introduce many more.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Effortless Python Development with Nix&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-02-18T00:28:29.202Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F157a7f2c-cd29-47a4-8d30-639f0934b9fe_819x819.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:141779798,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>I have a GitHub repository with some generic taskfiles that I reuse in most projects at <a href="https://github.com/gsantoro/taskfiles">Taskfiles</a>.</p><p>I have also used Taskfiles to set up a development environment to run Elastic Cloud on Kubernetes. You can find the paid article at <a href="https://cloudnativeengineer.substack.com/p/ep-11-elasticsearch-development-environment">Dev environment with Elastic Cloud on Kubernetes (ECK)</a> and the relative taskfiles at <a href="https://github.com/gsantoro/demos/tree/main/eck">ECK taskfiles</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;3a2cca48-067f-432e-bf01-46f2cb40093e&quot;,&quot;caption&quot;:&quot;Disclaimer The views and opinions expressed in this article are solely my own and do not necessarily reflect the views of Elastic, where I am currently employed. This article is for informational purposes only and should not be understood as an endorsement of any particular company, product, or policy. It should not be mistaken for official communication&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Dev environment with Elastic Cloud on Kubernetes (ECK)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:3521121,&quot;name&quot;:&quot;Giuseppe Santoro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer at Elastic (formerly Elasticsearch). Blogger on Medium, Mentor on Mentorcruise&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c78f52a-d04c-4a9c-b4f9-2da1733ca4ca_1024x1024.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2023-11-02T10:56:05.414Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad8d36af-f44f-45cf-95cf-7fdf0f154e27_1000x808.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://cloudnativeengineer.substack.com/p/ep-11-elasticsearch-development-environment&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:138515207,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Cloud Native Engineer&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfd1bebd-56cb-42c8-a510-84280bd535bf_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Unlock SQLite: Easy Data Analysis for Busy Software Engineers]]></title><description><![CDATA[Episode #19: Let me help you navigating the myriad of tools and solutions for data analysis.]]></description><link>https://cloudnativeengineer.substack.com/p/easy-data-analysis-for-busy-software-engineers</link><guid isPermaLink="false">https://cloudnativeengineer.substack.com/p/easy-data-analysis-for-busy-software-engineers</guid><dc:creator><![CDATA[Giuseppe Santoro 🚢]]></dc:creator><pubDate>Sat, 09 Mar 2024 12:24:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!E__b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E__b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E__b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 424w, https://substackcdn.com/image/fetch/$s_!E__b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 848w, https://substackcdn.com/image/fetch/$s_!E__b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 1272w, https://substackcdn.com/image/fetch/$s_!E__b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E__b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png" width="988" height="992" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:992,&quot;width&quot;:988,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2162865,&quot;alt&quot;:&quot;Feeling overwhelmed by the tools in data analysis&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Feeling overwhelmed by the tools in data analysis" title="Feeling overwhelmed by the tools in data analysis" srcset="https://substackcdn.com/image/fetch/$s_!E__b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 424w, https://substackcdn.com/image/fetch/$s_!E__b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 848w, https://substackcdn.com/image/fetch/$s_!E__b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 1272w, https://substackcdn.com/image/fetch/$s_!E__b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bc3597-3366-4113-ae9e-06f7eb8c83b7_988x992.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Feeling overwhelmed by the tools in data analysis</figcaption></figure></div><p>If you are a busy software engineer, you can't spend weeks thinking about the best solution for the job and then learning those tools.</p><p>Let me help make this choice much more manageable.</p><p>In this article, we will discuss SQLite, which I believe is the best tool for data analysis for relatively small datasets.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?coupon=f6ff5849&amp;utm_content=142447458&quot;,&quot;text&quot;:&quot;Get 20% off for 1 year&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://cloudnativeengineer.substack.com/subscribe?coupon=f6ff5849&amp;utm_content=142447458"><span>Get 20% off for 1 year</span></a></p><p>The article is divided into the following sections:</p><ul><li><p>When is SQLite the best tool for the job?</p></li><li><p>How to get started with SQLite</p></li><li><p>Extensions and tools for SQLite</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://cloudnativeengineer.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Cloud Native Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1><strong>Want to&nbsp;connect?</strong></h1><p>&#128073; Follow me on <a href="https://www.linkedin.com/in/santorogiuseppe/">LinkedIn</a> and <a href="https://twitter.com/gsantoro15">Twitter</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XdtN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg" width="298" height="295.62549800796813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:996,&quot;width&quot;:1004,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:93564,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XdtN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XdtN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd76079f6-cbdb-4bb1-9801-ef1336377273_1004x996.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Giuseppe Santoro</figcaption></figure></div><p>If you need 1-1 mentoring sessions, please check my <a href="https://mentorcruise.com/mentor/giuseppesantoro/">Mentorcruise profile</a>.</p><h2><strong>When is SQLite the best tool for the job?</strong></h2><p>You are a busy Software engineer who needs to analyse a relatively small dataset (e.g., 30-100MB of CSV or JSON logs) for a new project.</p><p>What tools should you use?</p><p>Any big data tools like Spark or Hadoop would be an overkill for such a small dataset.</p><p>Setting up a Python project with a Pandas data frame is the best option in most cases, however, depending on the complexity of the analysis, that might even be overkill.</p><p>As I explained in a previous article called <a href="https://cloudnativeengineer.substack.com/p/effortless-python-development-with-nix">Effortless Python Development with Nix</a>, setting up a Python project comes with some complexity.</p><p>You need to set up a virtual environment and install dependencies in a reproducible way. If you are sharing this project with someone else, you need to provide documentation on how to get started.</p><p>Using Nix makes onboarding new people, or even automating the setup process, a lot easier, but at the cost of installing Nix on your laptop.</p><p>Using command-line tools like awk and grep is definitively more straightforward to set up, but those tools may not provide enough flexibility. You also need to install those tools. Nix can also help you in this case, but you still have to install Nix.</p><p>I'm a huge fan of command-line tools; I use them all the time in my daily job.</p><p>I found a fascinating book on this topic called <a href="https://jeroenjanssens.com/dsatcl/">data science at the command line</a>. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hmKG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hmKG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 424w, https://substackcdn.com/image/fetch/$s_!hmKG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 848w, https://substackcdn.com/image/fetch/$s_!hmKG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 1272w, https://substackcdn.com/image/fetch/$s_!hmKG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hmKG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png" width="448" height="589" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:589,&quot;width&quot;:448,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:260823,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hmKG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 424w, https://substackcdn.com/image/fetch/$s_!hmKG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 848w, https://substackcdn.com/image/fetch/$s_!hmKG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 1272w, https://substackcdn.com/image/fetch/$s_!hmKG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7ebadb-2fb8-491a-b4fa-fa932e7d4e7f_448x589.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Data science at the command line</figcaption></figure></div><p>The book is now free, so I recommend reading it. While I enjoyed reading it, I don't agree with all the tools presented in this book. For example, I am not a fan of Makefile. If you want to learn more about this topic, I wrote an article at <a href="https://cloudnativeengineer.substack.com/p/ep-5-taskfile-a-modern-alternative">Taskfile: a modern alternative to Makefile</a>. Having said that, knowing those tools is highly beneficial when learning about command line tools.</p><p>Given that, as most software engineers, you know SQL, you could probably load all your data into a MySql or PostegreSQL database. You could install those databases locally or use managed services. You are trading installation time for the cost of paying for cloud services.</p><p>Is there a more straightforward solution that doesn't involve complex setup or cloud costs?</p><p>What else can you do?</p><p>If only we could come up with a solution that is powerful, flexible, easy to onboard, doesn't require cloud costs, and doesn't feel like an overkill for such a small dataset and simple analysis.</p><p>Am I asking too much?</p><p>I think I have a solution to this problem.</p><p>Discover SQLite:</p><blockquote><ul><li><p>SQLite is the most common DBMS in the world, shipped with all popular operating systems.</p></li><li><p>SQLite is serverless.</p></li><li><p>For developers, SQLite is embedded directly into the app.</p></li><li><p>For everyone else, there is a convenient database console (REPL), provided as a single file (sqlite3.exe on Windows, sqlite3 on Linux / macOS).</p></li></ul></blockquote><p>Those quotes are from an excellent article called <a href="https://antonz.org/sqlite-is-not-a-toy-database/">SQLite is not a toy database</a>.</p><h2><strong>How to get started with SQLite</strong></h2><blockquote><p>The console is a killer SQLite feature for data analysis: more powerful than Excel and simpler than&nbsp;<code>pandas</code>. One can import CSV data with a single command, and the table is created automatically:</p></blockquote><pre><code><code>&gt; .import --csv city.csv city
&gt; select count(*) from city;
1117
</code></code></pre><p>The quote and code are from this excellent article <a href="https://antonz.org/sqlite-is-not-a-toy-database/">SQLite is not a toy database</a>.</p><p>There are plenty of resources on how to get started with SQLite. I don't think I'll provide helpful information by repeating the same information here, so I'll give some good starting points below.</p><p>Some other learning resources:</p><ul><li><p><a href="https://www.sqlite.org/">SQLite official documentation</a></p></li><li><p><a href="https://pytechacademy.medium.com/unlocking-the-power-of-sqlite-a-comprehensive-guide-958041e701c8">Unlocking the Power of SQLite: A Comprehensive Guide (paid article)</a></p></li></ul><h2><strong>Extensions and tools for SQLite</strong></h2><p>As we discussed before, SQLite is not a toy database. Sometimes, though, it can feel like it is not as powerful as well-known alternatives like MySQL or PostgreSQL.</p><p>In the last few years, many extensions and tools have been developed to extend SQLite's functionality.</p><p>To name a few extensions:</p><ul><li><p><a href="https://github.com/asg017/sqlite-xsv">sqlite-xsv</a>: fast extension for CSV files</p></li><li><p><a href="https://github.com/asg017/sqlite-url">sqlite-url</a>: functions to work with URLs.</p></li><li><p><a href="https://github.com/nalgeon/sqlean">sqlean</a>: extension pack with some missing functions like math functions, cryptographic algorithms, regex support and much more.</p></li></ul><p>All those extensions are libraries that must be downloaded locally and then loaded into the database at runtime. For more information on how to load a SQLite extension, see <a href="https://www.sqlite.org/loadext.html">Runtime Loadable Extensions</a>.</p><p>Other than extensions, there are also some tools which can improve your experience working with SQLite:</p><ul><li><p><a href="https://sqlite-utils.datasette.io/">sqlite-utils</a>: library and command-line utility that helps create SQLite databases from an existing collection of data</p></li><li><p><a href="https://github.com/nalgeon/sqlpkg-cli">sqlpkg-cli</a>: manages SQLite extensions, just like&nbsp;<code>pip</code>&nbsp;does with Python packages or&nbsp;<code>brew</code>&nbsp;does with macOS programs. This tool allows you to install those SQLite extensions that we mentioned before (and many more) from a <a href="https://sqlpkg.org/">SQLite package registry</a>.</p></li></ul><p>I have created a <a href="https://github.com/gsantoro/demos/tree/main/weather-sqlite">GitHub repo</a> with some Nix files, Taskfile and a <a href="https://github.com/gsantoro/demos/tree/main/weather-sqlite">Readme</a> to make the experience of installing those extensions much more pleasant.</p>]]></content:encoded></item></channel></rss>