<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>DevOps on Panic! At The Terminal</title>
    <link>https://blog.nousiainen.xyz/categories/devops/</link>
    <description>Recent content in DevOps on Panic! At The Terminal</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 19 Jul 2025 21:04:22 +0300</lastBuildDate>
    <atom:link href="https://blog.nousiainen.xyz/categories/devops/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How to Restore a Broken KVM VM from Backup</title>
      <link>https://blog.nousiainen.xyz/docs/kvm-vm-restore-from-backup/</link>
      <pubDate>Fri, 18 Jul 2025 20:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/kvm-vm-restore-from-backup/</guid>
      <description>&lt;h1 id=&#34;how-to-restore-a-broken-kvm-vm-from-backup&#34;&gt;&#xA;  How to Restore a Broken KVM VM from Backup&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#how-to-restore-a-broken-kvm-vm-from-backup&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Sometimes things go wrong with virtual machines — maybe a filesystem corruption or a bad update. When that happens, restoring from a backup is your best friend.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s how I restored my broken KVM VM disk image using weekly backups stored on a NAS share.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-situation&#34;&gt;&#xA;  The situation&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#the-situation&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;I have a VM called &lt;code&gt;runner.home.arpa&lt;/code&gt; running on KVM, and its disk got corrupted. The VM disk images live at &lt;code&gt;/var/lib/libvirt/images/&lt;/code&gt;, and my backups are stored on a NAS mounted at &lt;code&gt;/mnt/backups/runner.home.arpa/&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Infrastructure as Code with Ansible Automation Platform</title>
      <link>https://blog.nousiainen.xyz/docs/ansible-automation-platform-iac-setup/</link>
      <pubDate>Sun, 13 Jul 2025 15:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/ansible-automation-platform-iac-setup/</guid>
      <description>&lt;h1 id=&#34;infrastructure-as-code-for-ansible-automation-platform-setup&#34;&gt;&#xA;  Infrastructure as Code for Ansible Automation Platform Setup&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#infrastructure-as-code-for-ansible-automation-platform-setup&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;&#xA;  Introduction&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#introduction&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Setting up Ansible Automation Platform (AAP) manually through the web interface is tedious and highly prone to errors.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve written an Ansible playbook that completely automates the setup of my AAP environment, from credentials and projects to job templates and workflow orchestration. So in case I ever need to rebuild the environment from scratch, all I would need to do is just add the project where that playbook is stored, and add a single template by hand and run it. I&amp;rsquo;d do it that way because I don&amp;rsquo;t like running ansible playbooks from the CLI, I always, always use AAP!&lt;/p&gt;</description>
    </item>
    <item>
      <title>SSH Hardening and Automation User Setup with Ansible</title>
      <link>https://blog.nousiainen.xyz/docs/ssh-hardening-ansible/</link>
      <pubDate>Sat, 12 Jul 2025 12:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/ssh-hardening-ansible/</guid>
      <description>&lt;h1 id=&#34;ssh-hardening-and-automation-user-setup-with-ansible&#34;&gt;&#xA;  SSH Hardening and Automation User Setup with Ansible&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#ssh-hardening-and-automation-user-setup-with-ansible&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a little post about how I do SSH hardening for my RHEL9 homelab and how I ensure that the Ansible automation user is properly set. The playbook stems from an incident I had in Red Hat Insights where it was reported that I had an SSH configuration that allowed legacy ciphers. It was also adviced to create a crypto policy that disables weak algorithms.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automated Network Monitoring: Adding Servers to LibreNMS with Ansible</title>
      <link>https://blog.nousiainen.xyz/docs/guide-librenms-ansible/</link>
      <pubDate>Mon, 07 Jul 2025 14:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/guide-librenms-ansible/</guid>
      <description>&lt;h1 id=&#34;automated-network-monitoring-adding-servers-to-librenms-with-ansible&#34;&gt;&#xA;  Automated Network Monitoring: Adding Servers to LibreNMS with Ansible&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#automated-network-monitoring-adding-servers-to-librenms-with-ansible&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Adding servers to LibreNMS by hand is tedious, and should be done by automation. In this post, I&amp;rsquo;ll show you how I&amp;rsquo;ve automated the entire process of configuring SNMP and adding servers to LibreNMS using Ansible.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-workflow&#34;&gt;&#xA;  The Workflow&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#the-workflow&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Basically what the playbook does is:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Install and configure SNMP&lt;/li&gt;&#xA;&lt;li&gt;Set up necessary firewall rules&lt;/li&gt;&#xA;&lt;li&gt;Add the server to LibreNMS&lt;/li&gt;&#xA;&lt;li&gt;Add it to the correct device group.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;the-playbook&#34;&gt;&#xA;  The Playbook&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#the-playbook&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;step-1-installing-snmp-components&#34;&gt;&#xA;  Step 1: Installing SNMP Components&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#step-1-installing-snmp-components&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Ensure snmp is installed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;ansible.builtin.dnf&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;net-snmp&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;net-snmp-utils&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;state&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;present&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;net-snmp&lt;/code&gt; package is needed for the SNMP daemon.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimizing KVM Virtual Machines with Tuned Profiles</title>
      <link>https://blog.nousiainen.xyz/docs/kvm-vm-tuning-ansible/</link>
      <pubDate>Mon, 07 Jul 2025 12:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/kvm-vm-tuning-ansible/</guid>
      <description>&lt;h1 id=&#34;optimizing-kvm-virtual-machines-with-tuned-profiles&#34;&gt;&#xA;  Optimizing KVM Virtual Machines with Tuned Profiles&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#optimizing-kvm-virtual-machines-with-tuned-profiles&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;The &lt;code&gt;tuned&lt;/code&gt; service on Red Hat-based systems provides pre-configured performance profiles that can significantly improve your VM performance with minimal effort.&lt;/p&gt;&#xA;&lt;p&gt;In this post, I&amp;rsquo;ll show you how to optimize your KVM VMs using tuned profiles and automate the entire process with Ansible.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-playbook&#34;&gt;&#xA;  The Playbook&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#the-playbook&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Since I manage dozens of VMs in my homelab, doing this manually would be tedious. Instead, I use this Ansible playbook to apply tuned optimization to all my VMs:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automating RHEL Server Updates with Ansible</title>
      <link>https://blog.nousiainen.xyz/docs/rhel-server-updates-ansible/</link>
      <pubDate>Sat, 05 Jul 2025 16:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/rhel-server-updates-ansible/</guid>
      <description>&lt;h1 id=&#34;automating-rhel-server-updates-with-ansible&#34;&gt;&#xA;  Automating RHEL Server Updates with Ansible&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#automating-rhel-server-updates-with-ansible&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;&#xA;  Introduction&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#introduction&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;I hate updating my servers manually so I&amp;rsquo;ve set up this playbook to run updates. This was probably the first playbook I ever wrote for my home lab, and it&amp;rsquo;s been running automatically for years now on a weekly schedule every Friday night through AAP (Ansible Automation Platform).&lt;/p&gt;&#xA;&lt;p&gt;This guide shows you how to automate RHEL (and other yum/dnf based distros like Fedora, CentOS etc.) server updates using Ansible, including proper reboot handling.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automated KVM VM Provisioning with Ansible and OSBuild on RHEL9</title>
      <link>https://blog.nousiainen.xyz/docs/automated-vm-provisioning-with-ansible-and-osbuild/</link>
      <pubDate>Thu, 03 Jul 2025 14:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/automated-vm-provisioning-with-ansible-and-osbuild/</guid>
      <description>&lt;h1 id=&#34;automated-kvm-vm-provisioning-with-ansible-and-osbuild-on-rhel9&#34;&gt;&#xA;  Automated KVM VM Provisioning with Ansible and OSBuild on RHEL9&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#automated-kvm-vm-provisioning-with-ansible-and-osbuild-on-rhel9&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;&#xA;  Introduction&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#introduction&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;When I started looking into automating my homelab VM provisioning, I was surprised by the lack of examples combining Ansible with OSBuild for KVM environments. Not many tutorials focus on KVM, so I wanted something that used Red Hat&amp;rsquo;s tooling - as I run a RHEL homelab.&lt;/p&gt;&#xA;&lt;p&gt;I used to provision my homelab virtual machines by hand and eventually I got tired of doing it since I like to tinker around a lot and constantly add new VMs. So, I decided to automate the process using the combination of Ansible and OSBuild.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to setup Ansible Vault</title>
      <link>https://blog.nousiainen.xyz/docs/ansible-vault-guide/</link>
      <pubDate>Thu, 03 Jul 2025 10:00:00 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/ansible-vault-guide/</guid>
      <description>&lt;h1 id=&#34;how-to-setup-ansible-vault&#34;&gt;&#xA;  How to setup Ansible Vault&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#how-to-setup-ansible-vault&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a little guide on how I setup Ansible Vault for my Ansible playbook repository. It&amp;rsquo;s surprisingly simple and now all of my secrets are encrypted.&lt;/p&gt;&#xA;&lt;h2 id=&#34;setting-up-ansible-vault&#34;&gt;&#xA;  Setting Up Ansible Vault&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#setting-up-ansible-vault&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-create-the-directory-structure&#34;&gt;&#xA;  1. Create the Directory Structure&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#1-create-the-directory-structure&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;p&gt;First, create the standard Ansible directory structure for group variables:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p group_vars/all&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-create-your-vault-file&#34;&gt;&#xA;  2. Create Your Vault File&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#2-create-your-vault-file&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h3&gt;&#xA;&lt;p&gt;Create a vault file to store your encrypted credentials:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Use ansible-lint with Vault Files</title>
      <link>https://blog.nousiainen.xyz/docs/ansible-lint-vault/</link>
      <pubDate>Mon, 30 Jun 2025 18:46:13 +0300</pubDate>
      <guid>https://blog.nousiainen.xyz/docs/ansible-lint-vault/</guid>
      <description>&lt;h1 id=&#34;use-ansible-lint-with-vault-files&#34;&gt;&#xA;  Use ansible-lint with Vault Files&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#use-ansible-lint-with-vault-files&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;why-i-wrote-this-post&#34;&gt;&#xA;  Why I wrote this post&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#why-i-wrote-this-post&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;I decided to write this post because I struggled to find clear, practical examples of how to make &lt;code&gt;ansible-lint&lt;/code&gt; work with Ansible Vault files in CI/CD environments. While searching for solutions, I found &lt;a href=&#34;https://github.com/ansible/ansible-lint/discussions/3899&#34;&gt;a GitHub discussion&lt;/a&gt; where someone was asking the exact same question I had.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;a href=&#34;https://ansible.readthedocs.io/projects/lint/usage/#vaults&#34;&gt;official ansible-lint documentation&lt;/a&gt; mentions that decrypting Ansible Vault in CI is possible, but frustratingly, it doesn&amp;rsquo;t provide any actual examples of how to implement it. After some trial and error, I figured out a working solution that I want to share.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
