<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>svnscha - automation</title>
    <subtitle>automating annoying tasks, sharing tips, and embracing less frustration</subtitle>
    <link rel="self" type="application/atom+xml" href="https://svnscha.de/tags/automation/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://svnscha.de"/>
    <generator uri="https://astro.build/">Astro</generator>
    <updated>2025-05-04T00:00:00+00:00</updated>
    <id>https://svnscha.de/tags/automation/atom.xml</id>
    <entry xml:lang="en">
        <title>AI Meets WinDBG: A Different Way to Analyze Crashes</title>
        <published>2025-05-04T00:00:00+00:00</published>
        <updated>2025-05-04T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/ai-meets-windbg/"/>
        <id>https://svnscha.de/posts/ai-meets-windbg/</id>
        <summary type="html">Because manually squinting at hex dumps is so last century. Let me show you how AI-assisted debugging is leaving WinDBG's command line in the dust.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/ai-meets-windbg/">&lt;h2 id=&quot;old-meets-new-bringing-crash-analysis-into-2025&quot;&gt;Old Meets New: Bringing Crash Analysis into 2025&lt;/h2&gt;
&lt;p&gt;Let's face it - while the rest of software development has evolved at warp speed, crash dump analysis feels like it's been preserved in digital amber for decades. We've got self-driving cars and pocket-sized supercomputers, yet here we are, still pecking away at command prompts like it's the dawn of the internet. Why is debugging the only area where we cling to tools that look like they belong in a computer history museum?&lt;/p&gt;
&lt;p&gt;Picture this: You, a professional software engineer in 2025, hunched over a terminal, manually typing arcane commands like &lt;code&gt;!analyze -v&lt;/code&gt; and &lt;code&gt;.ecxr&lt;/code&gt;, squinting at hexadecimal memory addresses, and mentally translating stack traces. All while your friends in other industries are delegating their work to AI assistants that can write entire documents, create art, or automate complex workflows.&lt;/p&gt;
&lt;p&gt;Something's wrong with this picture, right?&lt;/p&gt;
&lt;p&gt;I wanted a simpler workflow: ask questions in plain language and let an AI assistant run the relevant debugger commands. This is more than a new interface for WinDBG; it changes how you interact with the debugger.&lt;/p&gt;
&lt;h2 id=&quot;when-inspiration-strikes&quot;&gt;When Inspiration Strikes&lt;/h2&gt;
&lt;p&gt;During a debugging session at work, I had one of those lightning bolt moments. What if - and stick with me here - we could apply the same AI-assisted &quot;vibe coding&quot; approach to crash dump analysis?&lt;/p&gt;
&lt;p&gt;Picture this: instead of manually slogging through memory dumps and command outputs, you simply ask, &quot;Hey, why did this application crash?&quot; and get an intelligent, contextual answer that actually helps you solve the problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The idea was too compelling not to pursue. So I built it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;see-it-in-action-ai-powered-crash-analysis&quot;&gt;See It In Action: AI-Powered Crash Analysis&lt;/h2&gt;
&lt;p&gt;Before diving into the technical details, let me show you what this looks like in practice. I have prepared a demo application to showcase two different use cases:&lt;/p&gt;
&lt;h3 id=&quot;video-1-crash-analysis-and-automated-bugfix&quot;&gt;Video 1: Crash Analysis and Automated Bugfix&lt;/h3&gt;
&lt;p&gt;In this video, I show how Copilot can analyze a crash dump, identify the bug and auto-fix the issue.&lt;/p&gt;
&lt;video class=&quot;cast&quot; src=&quot;/casts/2025-05-03-CrashDump1.webm&quot; controls&gt;
  Your browser does not support the video tag.
&lt;/video&gt;
&lt;p&gt;As you can see in the video, instead of manually running WinDBG commands and interpreting the cryptic output, I'm having a natural conversation with GitHub Copilot. The AI quickly identifies that the application crashed, explains which specific conditions led to the crash, and suggests a fix.&lt;/p&gt;
&lt;h3 id=&quot;video-2-automated-crash-dump-analysis-of-multiple-crash-dump-files&quot;&gt;Video 2: Automated Crash Dump Analysis of multiple crash dump files&lt;/h3&gt;
&lt;p&gt;This video demonstrates a different capability: analyzing multiple crash dump files at once. It shows how the tool can quickly identify which dumps belong to your application and which don't.&lt;/p&gt;
&lt;video class=&quot;cast&quot; src=&quot;/casts/2025-05-03-CrashDump2.webm&quot; controls&gt;
  Your browser does not support the video tag.
&lt;/video&gt;
&lt;p&gt;Worth noting, it takes just a few seconds until you get your first useful answer. I've played around with this for many hours and let me tell you one thing: You can really go deep. If you ask the right questions, the AI runs WinDBG/CDB commands that I haven't seen in all these years of debugging, and that is simply amazing.&lt;/p&gt;
&lt;h2 id=&quot;how-can-this-help-the-industry&quot;&gt;How can this help the industry?&lt;/h2&gt;
&lt;p&gt;I believe this is one of the really good examples of how AI can boost productivity. Analyzing crash dumps is a very tedious task. It begins with quickly checking and identifying whether crashes are the same or different, and often requires very advanced knowledge when a crash is challenging - really challenging.&lt;/p&gt;
&lt;p&gt;Copilot can help here tremendously; it knows how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interpret assembly code (without you having to remember what EAX stands for)&lt;/li&gt;
&lt;li&gt;Check memory contents (so you don't have to count hex bytes on your fingers)&lt;/li&gt;
&lt;li&gt;Traverse structures with symbols (goodbye to manual pointer arithmetic!)&lt;/li&gt;
&lt;li&gt;And so much more&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This can help engineers, support teams, and QA staff work with crash dumps without memorizing every debugger command.&lt;/p&gt;
&lt;h2 id=&quot;how-did-i-build-this&quot;&gt;How did I build this?&lt;/h2&gt;
&lt;p&gt;If you've ever worked with WinDBG, you know the drill: cryptic commands, obscure syntax, and endless scrolling through memory addresses and stack traces that make your eyes glaze over. It's the kind of specialized knowledge that takes years to master and feels like speaking an alien language even when you do.&lt;/p&gt;
&lt;p&gt;The trick here is connecting WinDBG with AI. To do that, you first need to programmatically control a debugging session, right? There are plenty of options on how to do this. I prefer to keep things simple, so I have chosen &lt;a href=&quot;https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-using-cdb-and-ntsd&quot;&gt;CDB&lt;/a&gt;, which is Microsoft's Console Debugger. It operates on standard input and output, and that's so much more fun to deal with than setting up COM APIs or similar approaches.&lt;/p&gt;
&lt;p&gt;The second part is &quot;connecting with AI.&quot; That's where Model Context Protocol Servers come into the game.&lt;/p&gt;
&lt;h2 id=&quot;understanding-model-context-protocol-servers&quot;&gt;Understanding Model Context Protocol Servers&lt;/h2&gt;
&lt;p&gt;MCP is an open standard developed by Anthropic, released in November 2024. This protocol allows AI models to interact with external tools and data sources - think of it as giving AI assistants &quot;hands&quot; to work with other software. It defines a way for AI assistants to discover, access, and use tools through a consistent interface. In essence, it's what allows GitHub Copilot to &quot;talk&quot; to external programs like WinDBG.&lt;/p&gt;
&lt;p&gt;An MCP server acts as the intermediary between the AI model and the tool. It:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Registers available tools with the client&lt;/li&gt;
&lt;li&gt;Handles requests from AI models to use these tools&lt;/li&gt;
&lt;li&gt;Executes the tool operations and returns results&lt;/li&gt;
&lt;li&gt;Maintains context across interactions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Any tool can be made available to an AI model through an MCP server. I built one for WinDBG's CDB debugger.&lt;/p&gt;
&lt;h3 id=&quot;why-mcp-instead-of-languagemodeltool-api&quot;&gt;Why MCP Instead of LanguageModelTool API?&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://code.visualstudio.com/api/extension-guides/tools&quot;&gt;LanguageModelTool API&lt;/a&gt; might eventually be a better fit for this specific use-case. Creating a Visual Studio Extension that &quot;just works&quot; out of the box would potentially simplify the integration process significantly.&lt;/p&gt;
&lt;p&gt;However, using MCP directly offers several notable advantages. It works with any AI model, not just limiting itself to Copilot. The server can be used outside VS Code, functioning with various other tools. New features can be easily added without necessitating changes to the core integration. Moreover, it remains platform-independent, avoiding lock-in to any single company's implementation.&lt;/p&gt;
&lt;h2 id=&quot;the-mcp-windbg-project&quot;&gt;The MCP-WinDBG Project&lt;/h2&gt;
&lt;p&gt;I've implemented a &lt;a href=&quot;https://www.anthropic.com/news/model-context-protocol&quot;&gt;Model Context Protocol&lt;/a&gt; server that wraps WinDBG/CDB and exposes its capabilities to AI models within VS Code. Better yet, I've made it open source so everyone can experience this new workflow.&lt;/p&gt;
&lt;p&gt;The project, &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;mcp-windbg&lt;/a&gt;, connects VS Code and GitHub Copilot to WinDBG's analysis commands.&lt;/p&gt;
&lt;p&gt;The actual &quot;hard part&quot; was implementing the CDB (Command-Line WinDBG) interaction layer. And by &quot;hard&quot;, I mean vibe-coding with two coffees on a Saturday morning, where I spent more time being annoyed by pyTest failures than actual coding difficulties. The core implementation came together surprisingly quickly!&lt;/p&gt;
&lt;p&gt;The rest is primarily wrapper code that implements the Model Context Protocol specifications. Now that I've established and defined the core WinDBG interaction logic, I'm considering refactoring the project to TypeScript. This would enable me to create both an MCP Server in TypeScript and a dedicated Visual Studio Extension, with both implementations leveraging the same underlying CDB interaction layer.&lt;/p&gt;
&lt;h2 id=&quot;what-does-this-mean-in-practice&quot;&gt;What Does This Mean In Practice?&lt;/h2&gt;
&lt;p&gt;Let me walk you through what this enables:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Natural language crash analysis&lt;/strong&gt;: &quot;Why is this application crashing with an access violation at this address?&quot; (Instead of: &quot;What the $%#@ is this heap corruption!?&quot;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Contextual debugging&lt;/strong&gt;: &quot;Show me the stack trace for thread 5 and explain what each function is doing based on the symbols.&quot; (Instead of staring at call stacks like they're ancient hieroglyphics)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Root cause identification&lt;/strong&gt;: &quot;What's causing this null pointer dereference and where should I look in the code to fix it?&quot; (Instead of playing detective with memory addresses)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Instead of typing obscure commands like &lt;code&gt;!analyze -v&lt;/code&gt; followed by a series of manual investigations, you simply ask questions in plain language, and the AI interprets the crash data for you. It's like having a WinDBG expert whispering in your ear, except it doesn't get annoyed when you ask the same question five times.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h2&gt;
&lt;p&gt;The MCP server connects GitHub Copilot to WinDBG:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It provides a set of tools that Copilot can use to interact with crash dumps&lt;/li&gt;
&lt;li&gt;It translates natural language questions into appropriate WinDBG commands&lt;/li&gt;
&lt;li&gt;It parses and interprets the often cryptic WinDBG output into more useful information&lt;/li&gt;
&lt;li&gt;It maintains context throughout a debugging session, enabling follow-up questions to work naturally&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The technical implementation uses Python to spawn and communicate with CDB (the command-line version of WinDBG), parses the output, and exposes the functionality through the Model Context Protocol to VS Code.&lt;/p&gt;
&lt;h2 id=&quot;getting-started-with-mcp-windbg&quot;&gt;Getting Started With mcp-windbg&lt;/h2&gt;
&lt;p&gt;Ready to try it yourself? Here's how to get started:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, make sure you have the Windows SDK installed with Debugging Tools for Windows&lt;/li&gt;
&lt;li&gt;Clone the repository: &lt;code&gt;git clone https://github.com/svnscha/mcp-windbg.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set up a Python virtual environment and install the package&lt;/li&gt;
&lt;li&gt;Configure VS Code to use the MCP server&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For complete details, check out the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;repository README&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once configured, create a &lt;code&gt;.vscode/mcp.json&lt;/code&gt; file in your project that points to the server:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;    &quot;servers&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;        &quot;mcp_server_windbg&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;stdio&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;command&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;python&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;args&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;                &quot;-m&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;                &quot;mcp_server_windbg&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;            ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;            &quot;env&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;                &quot;_NT_SYMBOL_PATH&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;SRV*C:&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Symbols*https://msdl.microsoft.com/download/symbols&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might need to update the command, depending on where and how you have installed the mcp_server_windbg to.&lt;/p&gt;
&lt;h2 id=&quot;the-human-touch-still-matters&quot;&gt;The Human Touch Still Matters&lt;/h2&gt;
&lt;p&gt;Just like with &lt;a href=&quot;/posts/vscode-vibe-coding/&quot;&gt;code refactoring&lt;/a&gt;, the AI assistance isn't perfect. The human element - your experience, intuition, and domain knowledge - remains crucial. Sometimes you'll need to guide the analysis, ask follow-up questions, or provide additional context.&lt;/p&gt;
&lt;p&gt;The useful part is the combination: AI can process a large amount of debugger output quickly, while you provide the context needed to judge the result. It still needs supervision and can follow the wrong lead, so treat its findings as a starting point rather than a final answer.&lt;/p&gt;
&lt;h2 id=&quot;join-the-experience&quot;&gt;Join The Experience&lt;/h2&gt;
&lt;p&gt;I'd love for you to try this out, contribute to the project, and share your experiences. If you're interested:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Star the &lt;a href=&quot;https://github.com/svnscha/mcp-windbg&quot;&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Try it on your own crash dumps&lt;/li&gt;
&lt;li&gt;Report issues, suggest improvements, or contribute code&lt;/li&gt;
&lt;li&gt;Share your success stories (or even failures - we learn from those too!)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;the-magic-is-in-the-flow&quot;&gt;The Magic Is In The Flow&lt;/h2&gt;
&lt;p&gt;Just like with my code refactoring experience, the real magic isn't about any single capability - it's about the flow. When debugging stops being a tedious chore and becomes a fluid conversation, something fundamentally changes in how you approach problem-solving.&lt;/p&gt;
&lt;p&gt;Gone are the days of dreading crash analysis. Instead, each debugging session becomes an opportunity for collaboration with an AI partner that helps you understand what's happening at a deeper level.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Crash dump analysis has traditionally been one of the most technically demanding and least enjoyable parts of software development. It's like archaeology with a keyboard - painstakingly excavating through layers of memory and CPU state to unearth what went wrong. With AI assistance through tools like mcp-windbg, it becomes another area where we can experience that perfect &quot;vibe state&quot; of frictionless problem-solving.&lt;/p&gt;
&lt;p&gt;If you're still manually typing WinDBG commands and squinting at memory dumps in 2025, you're not just missing out on productivity - you're missing out on a fundamentally more enjoyable way to work.&lt;/p&gt;
&lt;p&gt;Try it. Debug it. Vibe it.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Moving to Fedora: Automating Discord Updates with Ansible</title>
        <published>2024-11-15T00:00:00+00:00</published>
        <updated>2024-11-15T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/fedora-discord-ansible/"/>
        <id>https://svnscha.de/posts/fedora-discord-ansible/</id>
        <summary type="html">Because life's too short to manually update Discord every week.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/fedora-discord-ansible/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;So, you've found yourself running Fedora and decided to install Discord, huh? Great choice  -  Fedora is fantastic. But then you realize Discord's tarball updates are a hassle. Every week, it's the same story: download, extract, and pray you didn't miss a step. Tedious, right?&lt;/p&gt;
&lt;p&gt;I use the following Ansible playbook to install and update Discord on Fedora. It handles the repetitive steps and makes the setup easy to reuse on another machine.&lt;/p&gt;
&lt;h2 id=&quot;step-1-understanding-the-process&quot;&gt;Step 1: Understanding the Process&lt;/h2&gt;
&lt;p&gt;Discord on Linux isn't as straightforward as we'd like. Flatpak is an option, but it can be slow with updates or cause compatibility issues. For those of us who prefer the direct tarball approach, we need a way to automate the mess. With Ansible, we can ensure Discord is always up-to-date with just one command. No more hunting for the latest download link or worrying about cleaning up old versions.&lt;/p&gt;
&lt;h2 id=&quot;step-2-the-playbook&quot;&gt;Step 2: The Playbook&lt;/h2&gt;
&lt;p&gt;Here's an Ansible playbook to make your life easier. It handles everything  -  downloading the tarball, extracting it to the proper location, and cleaning up afterward.&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Install and Update Discord on Fedora 41 using Ansible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  hosts&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;localhost&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  become&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  tasks&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Ensure /usr/share/discord is removed if it exists&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      file&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        path&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/usr/share/discord&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        state&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;absent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Download Discord tarball&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      get_url&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        url&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;https://discord.com/api/download/stable?platform=linux&amp;amp;format=tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        dest&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;/tmp/discord.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        mode&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;0644&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Create /usr/share/discord directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      file&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        path&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/usr/share/discord&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        state&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        mode&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;0755&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Extract Discord tarball to /usr/share/discord&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      unarchive&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        src&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;/tmp/discord.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        dest&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;/usr/share/discord/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        remote_src&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        extra_opts&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;--strip-components=1&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      args&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        creates&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;/usr/share/discord/discord&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Clean up temporary files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      file&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        path&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;/tmp/discord.tar.gz&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        state&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;absent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-3-what-this-playbook-does&quot;&gt;Step 3: What This Playbook Does&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Step 1: If Discord is already installed, it removes the existing files to prevent conflicts.&lt;/li&gt;
&lt;li&gt;Step 2: It downloads the latest stable Discord tarball directly from the official API.&lt;/li&gt;
&lt;li&gt;Step 3: Creates the required directory at &lt;code&gt;/usr/share/discord&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Step 4: Extracts the tarball into &lt;code&gt;/usr/share/discord&lt;/code&gt;, stripping unnecessary folder components.&lt;/li&gt;
&lt;li&gt;Step 5: Cleans up temporary files, leaving your system tidy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;a-note-about-bash-aliases&quot;&gt;A Note About Bash Aliases&lt;/h2&gt;
&lt;p&gt;If you're like me and love shortcuts, consider adding a bash alias to streamline running the playbook. This way, updating Discord becomes as simple as typing a single command. Here's how you can set it up:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;cat&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; ~/.bashrc.d/alias.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; ansible-venv&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;. ~/repos/ansible/.venv/bin/activate&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; update-discord&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;ansible-venv &amp;amp;&amp;amp; ansible-playbook ~/repos/ansible/update-discord.yml --connection=local -K&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this in place:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ansible-venv&lt;/code&gt; activates your virtual environment for Ansible.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update-discord&lt;/code&gt; runs the playbook with local connection and prompts for sudo permissions when needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, keeping Discord updated is literally a one-liner. Perfect, right?&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The same playbook handles both the first installation and later updates, so keeping Discord current only takes one command.&lt;/p&gt;
&lt;p&gt;So, go ahead  -  run it, relax, and enjoy Fedora without the hassle. Because let's face it: managing updates manually is so last year.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Moving to Fedora: Automating PowerShell Installation with Ansible</title>
        <published>2024-11-15T00:00:00+00:00</published>
        <updated>2024-11-15T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/fedora-powershell-ansible/"/>
        <id>https://svnscha.de/posts/fedora-powershell-ansible/</id>
        <summary type="html">Because repeating manual steps on multiple machines isn't fun anymore.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/fedora-powershell-ansible/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;I use PowerShell on Fedora for scripting and automation. Installing it manually is fine once, but it becomes repetitive across workstations, VMs, dev containers, and servers.&lt;/p&gt;
&lt;p&gt;This Ansible playbook automates the installation and keeps the setup consistent across those environments.&lt;/p&gt;
&lt;h3 id=&quot;step-1-the-problem&quot;&gt;Step 1: The Problem&lt;/h3&gt;
&lt;p&gt;Installing PowerShell on Fedora involves downloading Microsoft's repository package, registering it, updating the package index, and then installing the actual PowerShell package. It's fine if you're doing it once, but if you have to repeat the process on multiple systems, it quickly becomes a chore.&lt;/p&gt;
&lt;p&gt;The solution? Use Ansible to do it for you. Write the playbook once, and it works everywhere  -  no matter how many machines you're dealing with.&lt;/p&gt;
&lt;h3 id=&quot;step-2-the-playbook&quot;&gt;Step 2: The Playbook&lt;/h3&gt;
&lt;p&gt;Here's the Ansible playbook that automates PowerShell installation on Fedora:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Install PowerShell on Fedora 41 using Ansible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  hosts&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;localhost&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  become&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;yes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  gather_facts&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;  tasks&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Download Microsoft repository package&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.get_url&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        url&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;https://packages.microsoft.com/config/rhel/8/packages-microsoft-prod.rpm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        dest&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/tmp/packages-microsoft-prod.rpm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Register Microsoft repository&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.command&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        cmd&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;rpm -i /tmp/packages-microsoft-prod.rpm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      args&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        creates&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/etc/yum.repos.d/microsoft-prod.repo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Remove repository package after registration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.file&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        path&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/tmp/packages-microsoft-prod.rpm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        state&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;absent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Update package index&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.dnf&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        update_cache&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;yes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        state&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Install PowerShell&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.dnf&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;powershell&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        state&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;present&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Verify PowerShell installation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.command&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        cmd&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;pwsh --version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      register&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;pwsh_version_output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;Display PowerShell version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;      ansible.builtin.debug&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;        msg&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;Installed PowerShell version: {{ pwsh_version_output.stdout }}&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;step-3-usage&quot;&gt;Step 3: Usage&lt;/h3&gt;
&lt;p&gt;Running this playbook is straightforward. If you're working with a virtual environment for Ansible, make sure it's activated. Then, execute the playbook locally with the following command:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ansible-playbook&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; /path/to/install-powershell.yml&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; --connection=local&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -K&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's a quick breakdown:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ansible-playbook&lt;/code&gt;: Runs the playbook.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/path/to/install-powershell.yml&lt;/code&gt;: Path to the playbook file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--connection=local&lt;/code&gt;: Executes the playbook on the local machine instead of a remote host.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-K&lt;/code&gt;: Prompts for sudo privileges to perform the installation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this command, you can easily install PowerShell on your Fedora system without worrying about missing steps.&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;With this playbook, installing PowerShell on a new Fedora system takes one command and produces the same setup each time.&lt;/p&gt;
&lt;p&gt;So, the next time you're staring down the prospect of yet another manual PowerShell install, let Ansible take care of it. Because honestly, you've got better things to do.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Simplify SSH</title>
        <published>2024-10-03T00:00:00+00:00</published>
        <updated>2024-10-03T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/simplify-ssh/"/>
        <id>https://svnscha.de/posts/simplify-ssh/</id>
        <summary type="html">How to stop typing your SSH Key passphrase every time. (because, let's be real, we're all a little lazy)</summary>
        <content type="html" xml:base="https://svnscha.de/posts/simplify-ssh/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;I was tired of entering my SSH key passphrase every time I connected to a server. The setup below lets &lt;code&gt;ssh-agent&lt;/code&gt; remember it for the current terminal session and also keeps host settings in one place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It's time-consuming and frustrating. I'm tired of it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;So, you've got your shiny new SSH key and every time you want to connect to a server, you're greeted with that ever-familiar password prompt. Sure, typing your SSH key passphrase every time is good for security, but, come on  -  who wants to do that? I mean, I don't know about you, but I've got enough passwords to remember without constantly dealing with this nonsense.&lt;/p&gt;
&lt;p&gt;Let's save ourselves some time and effort by getting the SSH agent to remember our keys for us. That way, you can just run your commands like the seasoned developer you are without worrying about the whole &quot;password entering&quot; thing every single time.&lt;/p&gt;
&lt;h2 id=&quot;step-1-start-the-ssh-agent&quot;&gt;Step 1: Start the SSH Agent&lt;/h2&gt;
&lt;p&gt;First things first  -  let's get the SSH agent up and running. It's like your personal SSH butler, here to remember your key so you don't have to.&lt;/p&gt;
&lt;p&gt;Open up your terminal and type:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; $(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ssh-agent&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -s&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Boom! Now the agent is running in the background, ready to hold your keys like the responsible little daemon it is.&lt;/p&gt;
&lt;h2 id=&quot;step-2-add-your-key-to-the-ssh-agent&quot;&gt;Step 2: Add your key to the SSH Agent&lt;/h2&gt;
&lt;p&gt;Now that the agent is up, let's give it your key. You only need to do this once per session, and the agent will keep it ready for you.&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ssh-add&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; ~/.ssh/your_key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;your_key&lt;/code&gt; with the name of your private key file. Enter the passphrase once and &lt;code&gt;ssh-agent&lt;/code&gt; will remember it for the rest of the terminal session.&lt;/p&gt;
&lt;h2 id=&quot;step-3-configure-your-ssh-setup-to-be-even-lazier-i-mean-efficient&quot;&gt;Step 3: Configure your SSH setup to be even lazier (I mean efficient)&lt;/h2&gt;
&lt;p&gt;Okay, we've got the agent running and the key added, but we can take it one step further. Why not tell SSH exactly what key to use for which server, so you never have to worry about it picking the wrong one?&lt;/p&gt;
&lt;p&gt;To do this, we're going to set up a &lt;code&gt;~/.ssh/config&lt;/code&gt; file. If you don't have this file yet, don't worry  -  it's as easy as creating it:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;touch&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; ~/.ssh/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, crack open that file with your favorite text editor and set things up like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;Host&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; your-server-alias&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    HostName&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; your.server.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    User&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; your-username&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    IdentityFile&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; ~/.ssh/your_key&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;    IdentitiesOnly&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;breaking-it-down&quot;&gt;Breaking it down&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Host&lt;/strong&gt;: You can use any alias here that makes sense to you. This is what you'll type when you want to connect to this server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HostName&lt;/strong&gt;: The actual domain or IP address of the server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User&lt;/strong&gt;: Your username on that server, so you do not have to specify it each time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IdentityFile&lt;/strong&gt;: The path to your SSH private key.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IdentitiesOnly yes&lt;/strong&gt;: Tells SSH to use &lt;em&gt;only&lt;/em&gt; this key, rather than trying every key it can find in the agent (which is how you avoid that annoying &quot;user mismatch&quot; issue).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;step-4-create-a-wrapper-script-for-ssh-agent-control&quot;&gt;Step 4: Create a wrapper script for SSH Agent control&lt;/h2&gt;
&lt;p&gt;Alright, you want control over when your SSH agent starts up  -  totally understandable! Instead of running the agent automatically on login (which might feel a bit &lt;em&gt;too&lt;/em&gt; autonomous), we'll create a neat little wrapper script. You can trigger it whenever you feel like starting the agent and adding your SSH key for the session.&lt;/p&gt;
&lt;p&gt;Here's how to set that up.&lt;/p&gt;
&lt;h3 id=&quot;create-the-wrapper-script&quot;&gt;Create the wrapper script&lt;/h3&gt;
&lt;p&gt;Let's create a script that starts the SSH agent, adds your key, and gives you control over when it runs. We'll call this script &lt;code&gt;init-ssh&lt;/code&gt;, and we'll stick it somewhere like &lt;code&gt;/usr/local/bin&lt;/code&gt; so it's available from anywhere in your terminal.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create the script:&lt;/strong&gt;
Open your terminal and create the &lt;code&gt;init-ssh&lt;/code&gt; script:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; nano&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; /usr/local/bin/init-ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the script content:&lt;/strong&gt;
Paste the following content into the file:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;# Start the SSH agent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; $(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ssh-agent&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -s&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;# Add the key to the agent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ssh-add&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; ~/.ssh/your_key&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;# Optional: Display agent status for peace of mind&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ssh-add&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Make the script executable:&lt;/strong&gt;
Give the script executable permissions:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; chmod&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; +x&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; /usr/local/bin/init-ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;how-to-use-the-script&quot;&gt;How to use the script&lt;/h4&gt;
&lt;p&gt;Whenever you want to start your SSH agent for a session, just run:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; init-ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will start the agent, add your key, and show you a list of the keys currently loaded in the agent. You've got full control  -  start the agent when you want, stop it when you're done, and enjoy a password-free SSH experience for the duration of that session.&lt;/p&gt;
&lt;h3 id=&quot;optional-stopping-the-ssh-agent&quot;&gt;Optional: Stopping the SSH Agent&lt;/h3&gt;
&lt;p&gt;If you want to stop the SSH agent after you're done with it, you can either let it die when you close your terminal or manually kill it with:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;eval&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; $(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;ssh-agent&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -k&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That way, you get all the convenience of an SSH agent when you need it, without it running indefinitely in the background. You're now in complete control of your SSH setup, and you can keep things secure and efficient, exactly the way you like it.&lt;/p&gt;
&lt;p&gt;Happy SSH'ing!&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Simplify Elasticsearch and Kibana Installation</title>
        <published>2024-04-24T00:00:00+00:00</published>
        <updated>2024-04-24T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/simplify-elasticsearch-kibana/"/>
        <id>https://svnscha.de/posts/simplify-elasticsearch-kibana/</id>
        <summary type="html">Let me walk you through how I created a bash script that sets up Elasticsearch and Kibana on a single-node cluster with minimal fuss.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/simplify-elasticsearch-kibana/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;Setting up Elasticsearch and Kibana involves the same steps each time: update the system, configure repositories, install packages, and apply the initial configuration. I wrote a script to automate that work and make the setup reusable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It's time-consuming and frustrating. I'm tired of it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;automating-the-setup&quot;&gt;Automating the Setup&lt;/h2&gt;
&lt;p&gt;This Bash script installs Elasticsearch and Kibana as a single-node cluster. I use it when I need a small, repeatable setup without adding another configuration tool.&lt;/p&gt;
&lt;h2 id=&quot;why-choose-a-bash-script&quot;&gt;Why Choose a Bash Script?&lt;/h2&gt;
&lt;p&gt;I chose Bash instead of Ansible because the script also works well with cloud-init and inside Docker environments. It has no extra tooling requirements and is easy to copy to a new machine.&lt;/p&gt;
&lt;h2 id=&quot;building-the-script-a-step-by-step-guide&quot;&gt;Building the Script: A Step-by-Step Guide&lt;/h2&gt;
&lt;p&gt;Let's walk through the crafting of the script that automates setting up Elasticsearch and Kibana. Here's how I pieced it together, one step at a time:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Checking for Superuser Privileges
The script needs administrative access, so it starts by checking for root privileges.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C586C0&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; [ &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -u&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;)&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; != &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; ]; &lt;/span&gt;&lt;span style=&quot;color:#C586C0&quot;&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;   echo&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;This script must be run as root&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; 1&amp;gt;&amp;amp;2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;   exit&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#C586C0&quot;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Updating the System and Installing Essential Packages
Updating the system first helps avoid installation problems caused by outdated packages.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;apt&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;apt&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -y&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; apt-transport-https&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; gnupg&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; curl&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; jq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
&lt;p&gt;Adding the Elasticsearch Repository
Getting this right is like picking the perfect ingredients for a master chef recipe - it ensures the rest of the meal turns out just right.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Installing Elasticsearch and Kibana
Next, the script installs Elasticsearch and Kibana.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configuring and Starting Services
The plot thickens! Setting up the services and getting them running is like reaching the climax of our story - where all elements come together to unveil the full potential of our setup.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Rather than churn out another cookie-cutter guide on setting up Elasticsearch and Kibana, you can view the complete script &lt;a href=&quot;https://gist.github.com/svnscha/676291c9e1cdbfa261202b3897afba37&quot;&gt;here&lt;/a&gt;. However, I do want to emphasize the initial configuration process involving enrollment tokens and security settings. I've automated these aspects because, let's face it, I've read too many guides that suggest just turning off security for the sake of simplicity. That's not my style - I'd rather keep things secure automatically. It's not rocket science, but it sure is critical. Why simplify by compromising security when you can automate it effectively, right?&lt;/p&gt;
&lt;p&gt;This approach ensures you get the functionality you need without the hassle of manual setup or the risks of disabled security.&lt;/p&gt;
&lt;h2 id=&quot;perfecting-the-automation-securing-and-finalizing-the-setup&quot;&gt;Perfecting the Automation: Securing and Finalizing the Setup&lt;/h2&gt;
&lt;p&gt;The final part configures security and leaves both services ready to use.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Broadcasting the Good News
First things first, let's make sure any user logging into the system knows what's been accomplished:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;=== init-vm.sh: Initial ===&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; &amp;gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/etc/motd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;[&amp;gt; Elasticsearch 'elastic' password: &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$ELASTIC_PASSWORD&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; &amp;gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/etc/motd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;[&amp;gt; Test instance with 'curl -k -X GET https://elastic:&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$ELASTIC_PASSWORD&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;@localhost:9200'&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; &amp;gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/etc/motd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;=== init-vm.sh: Get started ===&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; &amp;gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/etc/motd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -e&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;[&amp;gt; Reset 'elastic' password with '/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'.&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; &amp;gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;/etc/motd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we're updating the message of the day (MOTD) file to ensure anyone who logs in is immediately informed about how to interact with Elasticsearch and what steps to take next. It's like leaving a note on the fridge - impossible to ignore and incredibly helpful.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Decoding the Secrets
Automation isn't just about doing things without human intervention; it's also about doing them securely and wisely:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A9955&quot;&gt;# Because who likes doing setup manually, right?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;decoded_token&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; $KIBANA_ENROLLMENT_TOKEN&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;base64&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; --decode&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;address&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; $decoded_token&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;jq&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -r&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '.adr[0]'&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;fingerprint&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; $decoded_token&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;jq&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -r&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '.fgr'&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;api_key&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; $decoded_token&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;jq&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -r&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '.key'&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Decoding the enrollment token reveals the essential elements needed to securely configure Kibana: the address, fingerprint, and API key.&lt;/p&gt;
&lt;p&gt;Harnessing Version and Build Information
Knowing exactly which version and build of Kibana you're working with is required for the API, so let's get that:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;ver&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;jq&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -r&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '.version'&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; /usr/share/kibana/package.json&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;jq&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -r&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '.build.number'&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; /usr/share/kibana/package.json&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Re-encoding and Verification
Secrecy is paramount, and so is verification. Here's how we handle both:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;encoded_api_key&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -n&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; $api_key&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;base64&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; /usr/share/kibana/bin/kibana-verification-code&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;verification_code&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt; $output&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;awk&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;: &quot;&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '{print $2}'&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt; | &lt;/span&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;sed&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; 's/ //g'&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The API key needs to be re-encoded to maintain security, and we also extract a verification code necessary for the next step - enrolling Kibana.&lt;/p&gt;
&lt;h2 id=&quot;the-final-act-enrolling-kibana&quot;&gt;The Final Act: Enrolling Kibana&lt;/h2&gt;
&lt;p&gt;And now, the final piece of our automation puzzle:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#DCDCAA&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -k&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -v&lt;/span&gt;&lt;span style=&quot;color:#569CD6&quot;&gt; -X&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; POST&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;http://localhost:5601/internal/interactive_setup/enroll&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;Accept: */*&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;Host: localhost:5601&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;Origin: http://localhost:5601&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;Referer: http://localhost:5601/&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;kbn-build-number: &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$build&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;kbn-version: &lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$ver&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;x-elastic-internal-origin: Kibana&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -H&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; &quot;x-kbn-context: %7B%22type%22%3A%22application%22%2C%22name%22%3A%22interactiveSetup%22%2C%22url%22%3A%22%2F%22%7D&quot;&lt;/span&gt;&lt;span style=&quot;color:#D7BA7D&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#569CD6&quot;&gt;     -d&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt; '{&quot;hosts&quot;:[&quot;https://'&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$address&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;'&quot;],&quot;apiKey&quot;:&quot;'&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$encoded_api_key&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;'&quot;,&quot;caFingerprint&quot;:&quot;'&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$fingerprint&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;'&quot;,&quot;code&quot;:&quot;'&lt;/span&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;$verification_code&lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;'&quot;}'&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This curl command not only sends all the needed parameters to Kibana for configuration but also uses the verification code to ensure that the setup is both authorized and secure. It's akin to dotting the i's and crossing the t's in our setup script.&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;The script turns a fresh system into a secured, working Elasticsearch and Kibana installation. Feel free to adapt it to your own environment.&lt;/p&gt;
&lt;p&gt;Check out the complete script here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/svnscha/676291c9e1cdbfa261202b3897afba37&quot;&gt;init-elastic-search-kibana-vm.sh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy automating, and here's to many insightful data explorations!&lt;/p&gt;
&lt;p&gt;P.S.: This script is tailored for automating development environments. Remember, a single-node cluster isn’t suited for production use, and storing passwords in the message of the day (MOTD) file? That’s a no-go for serious deployments. 😏&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Simplify Visual Studio Installation</title>
        <published>2024-02-12T00:00:00+00:00</published>
        <updated>2024-02-12T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/simplify-vs/"/>
        <id>https://svnscha.de/posts/simplify-vs/</id>
        <summary type="html">Quickly master Visual Studio installation with this easy guide. Ideal for developers seeking a hassle-free setup and efficient development environment.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/simplify-vs/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;Every year, like clockwork, I find myself setting up my local dev environment from scratch. And every time, it's the same old song and dance: downloading, installing, configuring.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It's time-consuming and frustrating. I'm tired of it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;can-it-be-easier&quot;&gt;Can It Be Easier?&lt;/h2&gt;
&lt;p&gt;What if setting up a new machine, rolling it back, or tweaking it could be as simple as running a build on a server? What if I told you we could apply the same principles of automation to our local setups?&lt;/p&gt;
&lt;h2 id=&quot;lets-find-a-solution&quot;&gt;Let's Find A Solution&lt;/h2&gt;
&lt;p&gt;Creating a new development environment shouldn't be a chore. It should be quick, painless, and even a little bit fun. To turn this dream into reality, I need two things: the right software and the perfect setup. That's where &lt;code&gt;winget&lt;/code&gt; and &lt;code&gt;.vsconfig&lt;/code&gt; come in.&lt;/p&gt;
&lt;p&gt;With a list of essential software and some PowerShell tricks, I began to make boring tasks automatic. I picked each program, from 7Zip to Visual Studio, for its important use. But the adventure of automating everything is a story for another time.&lt;/p&gt;
&lt;h3 id=&quot;streamlining-visual-studio-installation&quot;&gt;Streamlining Visual Studio Installation&lt;/h3&gt;
&lt;p&gt;My main event? Automating Visual Studio installation. Using &lt;code&gt;winget&lt;/code&gt;, I can install Visual Studio with just a line:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;powershell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;winget install -e --id Microsoft.VisualStudio.&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;2022.&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;Enterprise --silent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I didn't stop there. With the &lt;code&gt;--override&lt;/code&gt; flag, I tailored the installation to include specific workloads, like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;powershell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;winget install -e --id Microsoft.VisualStudio.&lt;/span&gt;&lt;span style=&quot;color:#B5CEA8&quot;&gt;2022.&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;Enterprise --silent --override &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;--wait --quiet --addProductLang En-us --config C:\vs2022.vsconfig&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This method sets up Visual Studio with the workload I need without having to manually select each package.&lt;/p&gt;
&lt;h4 id=&quot;whats-vsconfig&quot;&gt;What's &lt;code&gt;.vsconfig&lt;/code&gt;?&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.vsconfig&lt;/code&gt; helps me easily replicate my development environment wherever I am. It's a JSON file that, with just a few clicks in the Visual Studio Installer, allows me to compress my environment workloads into a neat package. This approach is not only perfect for keeping &lt;strong&gt;build servers&lt;/strong&gt; and &lt;strong&gt;personal development environments in sync&lt;/strong&gt; with identical workloads, but it also simplifies sharing updates and changes with teammates.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example: vs2022.vsconfig&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code dark-plus&quot; style=&quot;background-color:#1E1E1E;color:#D4D4D4; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9CDCFE&quot;&gt;  &quot;components&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Roslyn.Compiler&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.Component.MSBuild&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Roslyn.LanguageServices&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.SQL.LocalDB.Runtime&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.CoreEditor&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Workload.CoreEditor&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.TypeScript.TSServer&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.JavaScript.TypeScript&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.TextTemplating&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.NuGet&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.IntelliTrace.FrontEnd&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Debugger.JustInTime&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Component.Microsoft.VisualStudio.LiveShare.2022&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.IntelliCode&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.ClassDesigner&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.GraphDocument&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.CodeMap&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.CoreIde&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.Tools.x86.x64&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Graphics.Tools&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.DiagnosticTools&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Windows11SDK.22621&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.ATL&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.SecurityIssueAnalysis&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.ComponentGroup.ArchitectureTools.Native&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.Redist.14.Latest&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Windows11Sdk.WindowsPerformanceToolkit&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.CppBuildInsights&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.CMake&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.CMake.Project&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.ASAN&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.Vcpkg&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.Tools.ARM64EC&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Workload.NativeDesktop&quot;&lt;/span&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CE9178&quot;&gt;    &quot;Microsoft.VisualStudio.Component.VC.Runtimes.ARM64EC.Spectre&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D4D4D4&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can create a .vsconfig file with these easy steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Launch the Visual Studio Installer and choose to modify your setup.&lt;/li&gt;
&lt;li&gt;Hit More and then select the option to Export your settings into a .vsconfig file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That's it!&lt;/p&gt;
&lt;h3 id=&quot;why-bother-with-all-this&quot;&gt;Why Bother With All This?&lt;/h3&gt;
&lt;p&gt;I'm all about making life easier, not harder. Thanks to &lt;code&gt;winget&lt;/code&gt; and Visual Studio's &lt;code&gt;.vsconfig&lt;/code&gt;, what used to eat up a lot of time now takes no time at all.&lt;/p&gt;
&lt;p&gt;Setting up a fresh development environment is now a piece of cake - and I mean the kind of delicious cake you can buy ready-made but tastes as good as anything you'd bake yourself. So here's to spending less time on setup and more on the fun stuff: coding.&lt;/p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Blog Motivation</title>
        <published>2024-02-10T00:00:00+00:00</published>
        <updated>2024-02-10T00:00:00+00:00</updated>
        <author>
          <name>Sven Scharmentke</name>
        </author>
        <link rel="alternate" type="text/html" href="https://svnscha.de/posts/blog-motivation/"/>
        <id>https://svnscha.de/posts/blog-motivation/</id>
        <summary type="html">Why, You Ask? This is how I blog about automating annoying tasks, sharing tips, and embracing less frustration.</summary>
        <content type="html" xml:base="https://svnscha.de/posts/blog-motivation/">&lt;h2 id=&quot;why-you-ask&quot;&gt;Why, You Ask?&lt;/h2&gt;
&lt;p&gt;We all have those annoying little tasks that pop up a few times a year. They're too rare to make fixing them a big deal but happen just enough to be really annoying. Think about setting up a new laptop, sorting out files, refactor that &lt;code&gt;NULL&lt;/code&gt; to &lt;code&gt;nullptr&lt;/code&gt; or those updates that take forever. It eats up time and patience. &lt;strong&gt;I'm tired of it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;changing-things-up&quot;&gt;Changing Things Up&lt;/h2&gt;
&lt;p&gt;I started this blog not just to talk tech but to tackle these annoying moments head-on. My goal? To stop saying &lt;em&gt;&quot;it's not worth fixing&quot;&lt;/em&gt; and start finding ways to make these tasks less of a headache. Even those things we do once in a blue moon? Yeah, I want to automate those too. And I'll share every step right here.&lt;/p&gt;
&lt;h2 id=&quot;why-i-share&quot;&gt;Why I Share&lt;/h2&gt;
&lt;p&gt;This blog is my playground and my megaphone. It's where I try out new ideas to make life easier and then shout out what works. Each post starts with my cheeky&lt;/p&gt;
&lt;center&gt;&quot;Why, You Ask?&quot;&lt;/center&gt;
&lt;p&gt;and always circles back to me spilling the beans on how I truly feel, which usually is&lt;/p&gt;
&lt;center&gt;&quot;I'm tired of it.&quot;&lt;/center&gt;
&lt;p&gt;It's my unique approach, sprinkled with a dash of sarcasm, as I navigate through the mayhem, assuring you that behind every vent, there's a solid reason and, believe it or not, a solution waiting to be uncovered.&lt;/p&gt;
&lt;h2 id=&quot;sharing-what-i-learn&quot;&gt;Sharing What I Learn&lt;/h2&gt;
&lt;p&gt;Making things easier is only part of it. I also want to share useful ideas, opinions, and the occasional rant. When I find a good way to avoid repetitive work, I'll write it down here so others can use it too.&lt;/p&gt;
&lt;h2 id=&quot;come-along-for-the-ride&quot;&gt;Come Along for the Ride&lt;/h2&gt;
&lt;p&gt;If that sounds familiar, have a look around and share your own ideas. None of us should spend more time on repetitive work than necessary.&lt;/p&gt;
&lt;p&gt;Welcome to my quest for a smoother, simpler tech life. Here's to less frustration and more time doing what we love. Let's kick those annoying tasks to the curb.&lt;/p&gt;
</content>
    </entry>
</feed>
