<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Homelab on inherent site</title>
		<link>https://inherently.xyz/tags/homelab/</link>
		<description>Recent content in Homelab on inherent site</description>
		<generator>Hugo</generator>
		<language>en-us</language>
			<lastBuildDate>Sat, 07 Jun 2025 14:12:34 +0300</lastBuildDate>
			<atom:link href="https://inherently.xyz/tags/homelab/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Home Assistant</title>
				<link>https://inherently.xyz/blog/home-assistant/</link>
				<pubDate>Sat, 07 Jun 2025 14:12:34 +0300</pubDate>
				<guid>https://inherently.xyz/blog/home-assistant/</guid>
				<description>&lt;p&gt;I recently set up Home Assistant as a way of getting into home automation.&#xA;It&amp;rsquo;s a really cool piece of software and took a bit of time to set up so I&amp;rsquo;d like to document everything I&amp;rsquo;ve changed here.&lt;/p&gt;&#xA;&lt;h2 id=&#34;getting-started&#34;&gt;Getting started&lt;/h2&gt;&#xA;&lt;p&gt;Home Assistant is an open-source home automation solution, possibly the most well-known in its category.&#xA;It&amp;rsquo;s a great DIY and self-hosted alternative to smart home offering from bigger vendors.&#xA;As a platform it can integrate with tons of products available on the market and is very easy to run.&#xA;I&amp;rsquo;ve been interested in using Home Assistant for a few years but I never had anything to use it for or with.&#xA;Recently I decided I should look more into it so I ordered a SNZB-02D temperature and humidity sensor as well as a ZBdongle-E ZigBee stick also by Sonoff.&#xA;ZigBee is a protocol that a lot of the smart home devices use to communicate, including my temperature/humidity monitor.&#xA;This means that as long nothing goes wrong, I should be able to track my room&amp;rsquo;s temperature inside Home Assistant.&#xA;Sonoff also has smart power plugs, look for the ones that have &lt;code&gt;ZB&lt;/code&gt; in the model number like the S26R2ZB or S60ZBTPF (I didn&amp;rsquo;t check and wasted 10 euros).&lt;/p&gt;&#xA;&lt;p&gt;I picked up the items I ordered, dusted off the old Raspberry Pi 3b+ I&amp;rsquo;ve had for years and installed Home Assistant OS on it.&#xA;It took about an hour because for some reason the ethernet port on the Pi decided to not work.&#xA;After facing its demons and working through the childhood neglect trauma I had given it, the ethernet blinky light blessed the little Pi.&#xA;A little network setup and ta-da! I can log in using a browser on my desktop.&#xA;Following that I shut it down, connected the Sonoff USB ZigBee stick and turned it back on.&#xA;With a few clicks the USB stick was detected and ready to be used inside Home Assistant.&#xA;I made it scan for devices and set the temperature and humidity monitor into pairing mode and then connected to it.&#xA;This was a surprisingly straightforward process and right after there was data visible in the homepage.&lt;/p&gt;&#xA;&lt;p&gt;A couple weeks later I picked up another two sensors and two zigbee power plugs.&#xA;As a word of advice, the S26R2ZB is cheap so it only supports on/off functionality and not power measurement.&#xA;The S60ZBTPF should support both though, I have the non-ZigBee version and it does but only using eWeLink.&lt;/p&gt;&#xA;&lt;h2 id=&#34;graphing-the-worst-stars-waste-heat&#34;&gt;Graphing the worst star&amp;rsquo;s waste heat&lt;/h2&gt;&#xA;&lt;p&gt;I keep the monitoring device on my desk so I can look at it and check that I&amp;rsquo;m not going crazy and the weather is indeed getting warmer.&#xA;I also have one out in the balcony and one in the living room.&#xA;After few days I could look at the pretty graphs and see how the temperature fluctuated throughout the days which was quite interesting.&#xA;I could visibly see when I had opened the balcony door for some fresh air or how much the air-conditioner actually drops the temperature.&#xA;In general the whole solution works very well.&#xA;One day there was notification about a firmware updated for the ZigBee USB stick which I could install directly through Home Assistant.&#xA;The sensors also had a firmware update and could also be updated directly through HomeAssistant.&#xA;I don&amp;rsquo;t know why this seems like such a big deal to me but it&amp;rsquo;s surprising to see this process be supported and vendors not pulling some bs for once.&#xA;I still hate warm weather and the sun but now I can track how much it&amp;rsquo;s affecting me.&lt;/p&gt;&#xA;&lt;h2 id=&#34;add-ons&#34;&gt;Add-ons&lt;/h2&gt;&#xA;&lt;p&gt;For any web interface I consider it necessary to have an HTTPs certificate and some way to remotely access it.&#xA;Thankfully using add-ons, it&amp;rsquo;s possible to get certs from LetsEncrypt, use nginx as a reverse proxy and also install cloudflared.&#xA;Cloudflared is not official but it does work well even if it was a bit troublesome to set up initially.&#xA;It does require some fiddling in the YAML configuration file (using the editor add-on) but it&amp;rsquo;s not too difficult.&#xA;I also enabled prometheus metrics, which require authentication to scrape so it will be a slight bit more complicated than usual but nothing unusual.&#xA;There is a lot of other software available as an add-on, many things which I don&amp;rsquo;t care to run on Home Assistant on my Raspberry Pi, but it&amp;rsquo;s good to see such robust support and that they are available for use cases where they make sense.&lt;/p&gt;&#xA;&lt;h2 id=&#34;later-expansion&#34;&gt;Later expansion&lt;/h2&gt;&#xA;&lt;p&gt;I plan to add more stuff in the future and start playing with automations.&#xA;Currently it&amp;rsquo;s just a couple lights, the sensors and the power plugs.&#xA;There is no inclination to do something extra with them, just having control of all of them through one place is helpful enough.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a cool setup that works for what I want to do right now and also has a lot of room for expansion.&#xA;Now that I can access it from the outside and have TLS certificates it been a very nice experience.&#xA;If you&amp;rsquo;ve been waiting to start as well, it&amp;rsquo;s a lot easier than you might think.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Remote Access Homelab</title>
				<link>https://inherently.xyz/blog/remote-access-homelab/</link>
				<pubDate>Sun, 04 May 2025 18:26:25 +0300</pubDate>
				<guid>https://inherently.xyz/blog/remote-access-homelab/</guid>
				<description>&lt;p&gt;One of the remaining things for my homelab to have is remote access.&#xA;I set up a couple options and faced some issues during the process which I want to document here.&lt;/p&gt;&#xA;&lt;h2 id=&#34;tailscale&#34;&gt;Tailscale&lt;/h2&gt;&#xA;&lt;p&gt;Tailscale is wireguard-based VPN solution.&#xA;Its main idea is that you run it alongside whatever you want to be accessible in your tailscale virtual network and then you can get to it.&#xA;My primary concern was replacing something like openvpn where it can be set up so it&amp;rsquo;s almost like being connected to the local network.&#xA;In tailscale this can be achieved by making it announce that it can route to a specific subnet.&#xA;This way things like local DNS works normally (for example I can access &lt;code&gt;opnsense.home.inherently.xyz&lt;/code&gt;and see the web interface of my router).&#xA;Additionally, you can make your traffic be routed through a specific device.&#xA;This might be the router at home which will be marked as an exit node and then in the mobile app select it to be used as such.&#xA;The choice of tailscale dates back to when I was still running pfSense.&#xA;In pfSense there has been a built-in integration for quite a while that can work as an exit node and subnet router.&#xA;In OPNSense it used to require a very manual install and setup process through the FreeBSD ports system but now there is a plugin which is a lot more user-friendly.&#xA;I set it up that way and then joined my phone and my tablet to the tailnet which means I can access all of my servers remotely.&#xA;Problem solved, let&amp;rsquo;s go home, roll the outro.&#xA;Not yet.&#xA;The thing is that while this works fine for just myself, if I want someone to check out some new selfhosted service I have or connect to a database I&amp;rsquo;m hosting I don&amp;rsquo;t want them to have to set up tailscale first.&lt;/p&gt;&#xA;&lt;h2 id=&#34;cloudflare-tunnel&#34;&gt;Cloudflare Tunnel&lt;/h2&gt;&#xA;&lt;p&gt;To address that need, I chose Cloudflare Tunnel.&#xA;This works a bit differently than Tailscale, you run cloudflared and tell it where traffic for a domain name should be redirected.&#xA;In my case it runs inside kubernetes and points to the ingress controller.&#xA;This&amp;hellip; took a while for me to get working.&#xA;It was mostly my own fault and lack of knowledge of how cloudflare works.&#xA;There are certificates that cloudflare generates which encrypt traffic between clients and cloudflare.&#xA;This process is done automatically and only for the root domain, for any subdomains you better get your wallet out.&#xA;This meant that since I was trying to access services that were something like &lt;code&gt;service.home.inherently.xyz&lt;/code&gt;, TLS was broken.&#xA;Took about 2 days to figure this out and I only managed it thanks to Kryptonian in the Home Operationsdiscord server.&#xA;The way I fixed the TLS problem was by just putting everything under the root domain which then made it work.&#xA;There is a bit more work to do because I think &lt;a href=&#34;https://github.com/onedr0p/cluster-template&#34;&gt;cluster-template&lt;/a&gt; does have a good idea with separating services that should be externally accessible by running two ingress controllers.&#xA;However, at this point it gets the job done so I&amp;rsquo;m reasonably happy with it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Access do be external.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Talos Linux Setup and Configuration</title>
				<link>https://inherently.xyz/blog/talos-linux-setup-and-configuration/</link>
				<pubDate>Tue, 11 Mar 2025 19:28:45 +0200</pubDate>
				<guid>https://inherently.xyz/blog/talos-linux-setup-and-configuration/</guid>
				<description>&lt;p&gt;After about two weeks since the first time I installed Talos, I think I&amp;rsquo;ve figured out a good setup.&#xA;In the previous post I went over the PXE setup more than the kubernetes part of it so now I&amp;rsquo;ll cover the other half.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-the-talos-configuration-works&#34;&gt;How the Talos configuration works&lt;/h2&gt;&#xA;&lt;p&gt;Following &lt;a href=&#34;https://www.talos.dev/v1.9/introduction/getting-started/&#34;&gt;the getting started guide&lt;/a&gt; tells us that to generate the configuration files we need to run something like &lt;code&gt;talosctl gen config homecluster https://10.0.50.69:6443&lt;/code&gt;.&#xA;This command will generate 3 files. These are &lt;code&gt;controlplane.yaml&lt;/code&gt;, &lt;code&gt;worker.yaml&lt;/code&gt; and &lt;code&gt;talosconfig&lt;/code&gt;.&#xA;The control-plane nodes will use the first file, the worker nodes will use the second file and the third one should be placed into &lt;code&gt;~/.talos/config&lt;/code&gt; (with an edit to specify the node IP addresses or as Talos calls them in this case, endpoints).&#xA;If we run the command we&amp;rsquo;ll get some output like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;generating PKI and tokens&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;created controlplane.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;created worker.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;created talosconfig&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Then, if we try to re-run the same command we will get a message like the following:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;generating PKI and tokens&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;file &amp;#34;/home/angle/talos/controlplane.yaml&amp;#34; already exists, use --force to overwrite&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;If we do the &amp;ldquo;just go away and do it anyway&amp;rdquo; thing that it says and add &lt;code&gt;--force&lt;/code&gt; it will again show the previous output.&#xA;In this process, we&amp;rsquo;ve wiped all the secret tokens and certificates it generated before and cannot recover them.&#xA;For a first-time installation this is barely an inconvenience, we probably do not care.&#xA;When doing this for an existing cluster, we will also need to get a new kubeconfig since the secrets that are re-generated are also relevant for the certificate that is stored in the kubeconfig to access the cluster.&#xA;That&amp;rsquo;s one of the reasons that if you&amp;rsquo;ve had the cluster running for a couple months, this might be a bit more annoying.&lt;/p&gt;&#xA;&lt;h2 id=&#34;separate-secrets&#34;&gt;Separate secrets&lt;/h2&gt;&#xA;&lt;p&gt;The alternative is to take a more in-depth look at the documentation which will land us on a page with notes for production-level setups, specifically the section about &lt;a href=&#34;https://www.talos.dev/v1.9/introduction/prodnotes/#separating-out-secrets&#34;&gt;separating out secrets&lt;/a&gt;.&#xA;Following the examples in that page we can run something like &lt;code&gt;talosctl gen secrets -o secrets.yaml&lt;/code&gt; first and then &lt;code&gt;talosctl gen config --with-secrets secrets.yaml homecluster https://10.0.50.69:6443&lt;/code&gt;.&#xA;This way, whenever we run the command to generate the configuration files (&lt;code&gt;controlplane.yaml&lt;/code&gt;, &lt;code&gt;worker.yaml&lt;/code&gt;, &lt;code&gt;talosconfig&lt;/code&gt;) we will not also wipe the secrets.&#xA;Now, why is that process useful or even preferable?&lt;/p&gt;&#xA;&lt;p&gt;Using this approach, the secrets can be stored separately from the configuration itself, that&amp;rsquo;s the obvious part.&#xA;The less obvious part is that given the same &lt;code&gt;talosctl&lt;/code&gt;, the CLI tool, we can generate the same 3 files.&#xA;Additionally, the kubeconfig that we can receive by running &lt;code&gt;talosctl kubeconfig ~/.config/kube/config --nodes 10.0.50.72 --endpoints 10.0.50.72&lt;/code&gt; is not going to need to be updated even if we reinstall Talos.&#xA;You might then think, if we continually re-generate these 3 files, how can we ever permanently store configuration changes?&#xA;Putting them directly in &lt;code&gt;controlplane.yaml&lt;/code&gt; and &lt;code&gt;worker.yaml&lt;/code&gt; is a no-go since they&amp;rsquo;ll be overwritten by a &lt;code&gt;talosctl gen config&lt;/code&gt; command.&#xA;That&amp;rsquo;s where patches come in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;patches&#34;&gt;Patches&lt;/h2&gt;&#xA;&lt;p&gt;The &lt;code&gt;talosctl&lt;/code&gt; CLI tool has a couple helpful options for applying patches when generating configuration.&#xA;Similar to having one configuration file for control-plane nodes and one for workers, the CLI flags are the same way.&#xA;There are 3 flags: &lt;code&gt;--config-patch-control-plane&lt;/code&gt; which applies the patch only to control-plane nodes, &lt;code&gt;--config-patch-worker&lt;/code&gt; which applies the patch only to worker nodes and &lt;code&gt;--config-patch&lt;/code&gt; which applies it to both.&#xA;Using these, we can write patches and apply them as we wish to any and all of the nodes in our cluster.&#xA;All 3 of the flags accept either inline JSON patches or YAML files depending on the notation.&#xA;Now I&amp;rsquo;ll switch gears a bit and discuss my own specific setup as an example.&#xA;I have 3 patches at the moment.&#xA;First, is a baseline that configures network interfaces, defines the installation disk, sets up NTP, adds kernel parameters, enables workload scheduling on the control-plane nodes and certificate rotation for the kubelet.&#xA;The other two are specific for the openebs storage system and for the metallb bare-metal loadbalancer.&#xA;It&amp;rsquo;s important to note at this point that it merges the changes.&#xA;So if you want to remove something from the default configuration (such as the &lt;code&gt;node.kubernetes.io/exclude-from-external-load-balancers: &amp;quot;&amp;quot;&lt;/code&gt; node label) it&amp;rsquo;s not as easy as just having the key specified but being empty (for example &lt;code&gt;nodeLabels: {}&lt;/code&gt;).&#xA;To generate my configuration, I can run the following:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;talosctl gen config homecluster https://10.0.50.69:6443 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--with-examples&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--with-docs&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--with-secrets&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;secrets.yaml &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--config-patch&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;@patches/01_baseline-changes-patch.yaml &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--config-patch&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;@patches/02_openebs-mayastor-patch.yaml &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--config-patch&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;@patches/03_metallb-patch.yaml &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;--endpoints&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;10.0.50.71,10.0.50.72,10.0.50.73&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Here I&amp;rsquo;ve disabled documentation and examples just so the file isn&amp;rsquo;t as cluttered.&#xA;The important part though is that the sensitive information is only stored in only one file which could be encrypted and put into version control.&#xA;From there, I could use the same version of the CLI tool to generate the final configuration file.&#xA;The goal is to be able to have some sort of GitOPS setup where all or most of what&amp;rsquo;s needed to create the Talos configuration is stored in the same &lt;a href=&#34;https://gitlab.com/insanitywholesale/infra&#34;&gt;infra repository&lt;/a&gt; as everything else.&#xA;One tool that seems to fit this exact use-case is &lt;a href=&#34;https://github.com/budimanjojo/talhelper&#34;&gt;talhelper&lt;/a&gt; but I&amp;rsquo;ve not looked into it yet.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;I keep finding cool stuff about Talos and the homelab tinkering will continue until morale improves.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>PXE setup for Talos Linux with Matchbox</title>
				<link>https://inherently.xyz/blog/pxe-setup-for-talos-using-matchbox/</link>
				<pubDate>Sat, 01 Mar 2025 19:00:33 +0200</pubDate>
				<guid>https://inherently.xyz/blog/pxe-setup-for-talos-using-matchbox/</guid>
				<description>&lt;p&gt;Join my campaign of hate against installing operating systems interactively.&#xA;I usually wipe my homelab virtualization hosts every week or two.&#xA;This might sound insane but I&amp;rsquo;ve been working on automating their setup.&#xA;As explained in the previous post, friendship ended with ProxMox and kubernetes will take its place.&#xA;Specifically Talos Linux, a linux distro you can&amp;rsquo;t even SSH into.&#xA;ProxMox kind of notoriously doesn&amp;rsquo;t have a way to be sanely installed through PXE but Talos is kind of made for it.&#xA;However, PXE (and iPXE, we&amp;rsquo;ll discuss this later) is not perfectly documented and can be even harder to debug.&#xA;So in this post I&amp;rsquo;ll document what worked for me and talk about some pretty helpful resources.&lt;/p&gt;&#xA;&lt;h2 id=&#34;plan&#34;&gt;Plan&lt;/h2&gt;&#xA;&lt;h3 id=&#34;pxe&#34;&gt;PXE&lt;/h3&gt;&#xA;&lt;p&gt;So let&amp;rsquo;s start with a bit of background, then lay out what I wanted to achieve, why and what I considered &amp;ldquo;good enough&amp;rdquo;.&#xA;First off, PXE.&#xA;It stands for pre-boot execution environment and is mostly reliant on motherboards and network cards to be implemented on the client side.&#xA;It&amp;rsquo;s a stripped down environment before the computer is booted into an operating system.&#xA;Inside it, there are standards for getting information about what to execute, where to get it and what configuration to use.&#xA;PXE is the name of the general concept and the first version of the technology.&#xA;It allows booting a computer from the network by loading files from a TFTP server.&#xA;Later on, &lt;a href=&#34;https://ipxe.org/&#34;&gt;iPXE&lt;/a&gt; came around to fix some of its limitations.&#xA;One thing it&amp;rsquo;s useful for having a computer and being able to boot it from the network and install an operating system on it without having to have a USB stick on you.&#xA;With something like &lt;a href=&#34;https://syslinux.org/&#34;&gt;syslinux&lt;/a&gt; you can even create menus to be able to choose what to install and have a bunch of different options with different settings.&#xA;As computer installations grow larger, it&amp;rsquo;s easy to see how this becomes kind of essential as you can&amp;rsquo;t run around multiple datacenters any time something needs to be re-imaged.&#xA;A counter-point to that could be that servers have remote management features allowing us to load ISOs as if they&amp;rsquo;re DVDs but even then, iPXE has an advantage because you can fully automate the process.&#xA;Also my poor version of servers (read: used office PCs) do not have IPMI.&#xA;At any rate, that&amp;rsquo;s the general idea of PXE.&lt;/p&gt;&#xA;&lt;h3 id=&#34;talos&#34;&gt;Talos&lt;/h3&gt;&#xA;&lt;p&gt;How does that apply to my case then?&#xA;I want to be able to completely wipe all three systems and then effortlessly restore them.&#xA;As I plan to run kubernetes on it, the installation of applications to the cluster is taken care of using &lt;a href=&#34;https://fluxcd.io/&#34;&gt;FluxCD&lt;/a&gt; so I only really need to solve the installation part.&#xA;That&amp;rsquo;s where &lt;a href=&#34;https://www.talos.dev/&#34;&gt;Talos&lt;/a&gt; comes in.&#xA;Talos is an incredibly minimal linux distribution that is designed with the sole purpose of running kubernetes.&#xA;No SSH, no TTY, no nothing.&#xA;Sitting in front of the system only allows you to change kernel boot parameters and the network configuration.&#xA;Everyhing is done using the API which is accessible interactively through the &lt;code&gt;talosctl&lt;/code&gt; CLI utility.&#xA;This means that we can have our operating system and kubernetes configuration as code for the price of one config file.&#xA;Sign me up!&lt;/p&gt;&#xA;&lt;h3 id=&#34;matchbox&#34;&gt;Matchbox&lt;/h3&gt;&#xA;&lt;p&gt;Those are the ingredients but it can hardly be called a meal.&#xA;We need to get some kitchen utensils in this analogy to get the desired result.&#xA;Our PXE setup will need to have a little bit of logic in it so it knows what to install with what configuration.&#xA;See, Talos can be told to fetch a configuration file from an HTTP server using a kernel parameter.&#xA;A conditionally-rendered file would allow us to alter the response depending on who&amp;rsquo;s requesting it.&#xA;This is where &lt;a href=&#34;https://matchbox.psdn.io/&#34;&gt;matchbox&lt;/a&gt; slots in.&#xA;When matchbox gets a request it can see some information about the host requesting it and therefore make a determination about what to reply with.&#xA;We can then serve different options according to which system is asking such as what Talos configuration file to use.&#xA;This way the control-plane kubernetes nodes can receive the Talos &lt;code&gt;controlplane.yaml&lt;/code&gt; while worker nodes get the &lt;code&gt;worker.yaml&lt;/code&gt;.&#xA;So a brand-new host with an empty disk drives would boot up, skip the disks since they don&amp;rsquo;t have an operating system and then try booting using PXE.&#xA;Then the host would get its configuration, install the operating system, install kubernetes and become part of a cluster.&lt;/p&gt;&#xA;&lt;h3 id=&#34;definition-of-done&#34;&gt;Definition of Done&lt;/h3&gt;&#xA;&lt;p&gt;The ideal process when getting adding a host should look like:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;note down the MAC address and corresponding IP somewhere&lt;/li&gt;&#xA;&lt;li&gt;plug in the cables&lt;/li&gt;&#xA;&lt;li&gt;configure the boot device order&lt;/li&gt;&#xA;&lt;li&gt;save settings and exit&lt;/li&gt;&#xA;&lt;li&gt;play minecraft while waiting&lt;/li&gt;&#xA;&lt;li&gt;run one or zero commands&lt;/li&gt;&#xA;&lt;li&gt;host shows up in &lt;code&gt;kubectl get nodes&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;recreating it from scratch should be just as easy&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t know if I can get exactly to that point but I&amp;rsquo;m willing to put in some effort into the setup so in the future I can avoid it to a greater extent.&#xA;Some compromise is acceptable since I don&amp;rsquo;t have any IPAM infrastructure in place already so this isn&amp;rsquo;t the full and proper way to go about it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;h3 id=&#34;how-do-i-do-x-in-y-minutes&#34;&gt;How do I do X in Y minutes&lt;/h3&gt;&#xA;&lt;p&gt;Meat and potatoes first, for quick reference here is what I did (5-6 hours of suffering omitted for brevity):&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Installed &lt;code&gt;tftp-hpa&lt;/code&gt; on Arch&lt;/li&gt;&#xA;&lt;li&gt;Downloaded &lt;a href=&#34;http://boot.ipxe.org/undionly.kpxe&#34;&gt;undionly.kpxe&lt;/a&gt; and &lt;a href=&#34;http://boot.ipxe.org/ipxe.efi&#34;&gt;ipxe.efi&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Put them in &lt;code&gt;/srv/tftp&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Created &lt;code&gt;matchbox.ipxe&lt;/code&gt; with the following contents:&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;#!ipxe&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chain http://10.0.20.50:8080/boot.ipxe&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;Installed &lt;code&gt;matchbox&lt;/code&gt; using Docker by running the following command:&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;docker&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;net&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rm&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;matchbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;matchbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Z&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;etc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;matchbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;etc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;matchbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ro&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;quay&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;poseidon&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;matchbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10.0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8080&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;Downloaded &lt;a href=&#34;https://github.com/siderolabs/talos/releases/download/v1.9.4/vmlinuz-amd64&#34;&gt;vmlinuz-amd64&lt;/a&gt; and &lt;a href=&#34;https://github.com/siderolabs/talos/releases/download/v1.9.4/initramfs-amd64.xz&#34;&gt;initramfs-amd64.xz&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Put them in &lt;code&gt;/var/lib/matchbox/assets&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Download &lt;code&gt;talosctl&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Run &lt;code&gt;talosctl gen config homecluster https://10.0.50.69&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Edit &lt;code&gt;controlplane.yaml&lt;/code&gt; until it looks good&lt;/li&gt;&#xA;&lt;li&gt;Put &lt;code&gt;controlplane.yaml&lt;/code&gt; in &lt;code&gt;/var/lib/matchbox/assets&lt;/code&gt; as well&lt;/li&gt;&#xA;&lt;li&gt;Create &lt;code&gt;/var/lib/matchbox/profiles/control-plane.json&lt;/code&gt;:&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;control-plane&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;control-plane&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;boot&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;kernel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/assets/vmlinuz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;initrd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/assets/initramfs.xz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;initrd=initramfs.xz&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;init_on_alloc=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;slab_nomerge&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;pti=on&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;console=tty0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;printk.devkmsg=on&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;talos.platform=metal&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;talos.config=http://10.0.20.50:8080/assets/controlplane.yaml&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;Create &lt;code&gt;/var/lib/matchbox/groups/control-plane.json&lt;/code&gt;:&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;kube01&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;kube01&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;profile&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;control-plane&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;selector&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;mac&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;18:03:73:2a:d8:a2&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;In &lt;a href=&#34;https://opnsense.home.inherently.xyz/services_dhcp.php?if=opt2&#34;&gt;OPNSense (link to my router)&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Under &lt;code&gt;DHCP Static Mappings for this interface.&lt;/code&gt; add the hosts&lt;/li&gt;&#xA;&lt;li&gt;Under &lt;code&gt;TFTP server&lt;/code&gt;:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Set TFTP hostname: 10.0.20.50&lt;/li&gt;&#xA;&lt;li&gt;Set Bootfile: undionly.kpxe&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Under &lt;code&gt;Network booting&lt;/code&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Set next-server IP: 10.0.20.50&lt;/li&gt;&#xA;&lt;li&gt;Set default bios filename: undionly.kpxe&lt;/li&gt;&#xA;&lt;li&gt;Set iPXE boot filename: matchbox.ipxe&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Boot Optiplex&lt;/li&gt;&#xA;&lt;li&gt;Wait&lt;/li&gt;&#xA;&lt;li&gt;Watch text scroll on screen&lt;/li&gt;&#xA;&lt;li&gt;???&lt;/li&gt;&#xA;&lt;li&gt;No profit, I spent my whole weekend on this&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;explanation&#34;&gt;Explanation&lt;/h3&gt;&#xA;&lt;p&gt;PXE is an under-documented part of the common network services one can set up.&#xA;An amusing yet educational thing I found was a redditor&amp;rsquo;s 3-part descent into madness and consequently enlightenment:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/homelab/comments/1ahhhkh/why_does_pxe_feel_like_a_horribly_documented_mess/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&#34;&gt;part 1&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/homelab/comments/1b1qc05/a_followup_to_my_pxe_rant_standing_up_baremetal/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&#34;&gt;part 2&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/homelab/comments/1b3wgvm/uefipxeagents_conclusion_to_my_pxe_rant_with_a/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&#34;&gt;part 3&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The matchbox documentation was also very good at explaining both the general process and giving some specific recommendations:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://matchbox.psdn.io/network-booting/&#34;&gt;Network boot environments&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://matchbox.psdn.io/network-setup/&#34;&gt;Network setup&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;With those out of the way I&amp;rsquo;ll make an attemt at explaining it myself.&#xA;When a PXE client starts, it does the DHCP dance which tells it where the TFTP server is and what the name of the file it should execute is.&#xA;That file is a network boot program which can optionally load some configuration (also stored on the TFTP server).&#xA;So after all of that is figured out, the PXE client will pull the kernel and initramfs, again from the TFTP server.&#xA;In contrast, iPXE uses scripts stored on the TFTP server instead of plain configuration files so we can do fancier things with it.&#xA;However, my old desktop PCs do not have iPXE so I had to use an in-between thingy, undionly.kpxe.&#xA;What that does is load iPXE firmware (ipxe.efi) so we can access the cool new features without having to replace any hardware.&#xA;When that loads, it talks to the DHCP server as an iPXE client this time and gets told to grab the matchbox.ipxe file from the TFTP server.&#xA;That file is an iPXE script which tells the client to check the matchbox server.&#xA;When matchbox gets the request, it checks the groups it has registered and if there are any matches according to the &lt;code&gt;selector&lt;/code&gt; field, it uses the corresponding profile.&#xA;In this case, the profile is for control-plane Talos Linux nodes.&#xA;The kernel and initramfs listed in the profile are used alongside some specific kernel parameters.&#xA;The most important parameter is &lt;code&gt;talos.config=http://10.0.20.50:8080/assets/controlplane.yaml&lt;/code&gt; which tells the machine that is booting the operating system to fetch the configuration file listed there.&#xA;Of course, you will need to have generated the configuration (using &lt;code&gt;talosctl gen config homecluster https://10.0.50.69:6443&lt;/code&gt;) and moved it in the matchbox &lt;code&gt;assets&lt;/code&gt; directory (or in another HTTP server, matchbox is just convenient in this setup).&#xA;That configuration has some basic things like which disk and network settings to use.&#xA;When the machine gets this configuration, it installs Talos and then waits.&#xA;At this point the system is booted normally, no PXE involved.&lt;/p&gt;&#xA;&lt;p&gt;Following that, all we need to do is run &lt;code&gt;talosctl bootstrap --nodes 10.0.50.71 --endpoints 10.0.50.71&lt;/code&gt; and we get a kubernetes cluster.&#xA;To get the kubeconfig required to access the cluster, run &lt;code&gt;talosctl kubeconfig my-talos-kubeconfig --nodes 10.0.50.71 --endpoints 10.0.50.71&lt;/code&gt; and then check that it works by running &lt;code&gt;kubectl --kubeconfig my-talos-kubeconfig get nodes&lt;/code&gt;.&#xA;I&amp;rsquo;ve tested the whole process end-to-end twice now to ensure that nodes with blank disks and correct boot order will behave correctly and it&amp;rsquo;s almost magic.&#xA;True enough, after pressing the power button on all three systems, making some coffee, and then running the commands mentioned previously, I got this output:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ kubectl get nodes -o wide&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;NAME     STATUS   ROLES           AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION   CONTAINER-RUNTIME&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube01   Ready    control-plane   3h20m   v1.32.2   10.0.50.71    &amp;lt;none&amp;gt;        Talos (v1.9.4)   6.12.13-talos    containerd://2.0.2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube02   Ready    control-plane   3h20m   v1.32.2   10.0.50.72    &amp;lt;none&amp;gt;        Talos (v1.9.4)   6.12.13-talos    containerd://2.0.2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kube03   Ready    control-plane   3h20m   v1.32.2   10.0.50.73    &amp;lt;none&amp;gt;        Talos (v1.9.4)   6.12.13-talos    containerd://2.0.2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And I guess that&amp;rsquo;s it.&#xA;It needed some effort and research and the approach should be adjusted according to the network situation (the matchbox docs saved the day here).&#xA;In the end though, I really like what I got working and it was a fun way to spend the weekend.&#xA;I can go from basically brand new computer with nothing on it to full cluster with a high availability control-plane using patience and a single command.&#xA;Two commands and I can install fluxcd on the cluster which will install all my applications.&#xA;Looking back at the definition of done I set in the beginning, I consider this a success.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;As the proud owner of a Talos Linux kubernetes cluster installed in a fully automated way, I am quite happy.&#xA;I can get back into running services at home and live through the pain of using kubernetes daily again.&#xA;I have a couple of ideas in mind for how to use my new container running platform but that&amp;rsquo;s for another post.&#xA;Hopefully you got a better idea of what PXE is, how it works and how I used it in this instance.&#xA;If you weren&amp;rsquo;t familiar with any of this, maybe it&amp;rsquo;s time to get your hands dirty and prepare to throw away your USB drives.&#xA;Either way, that&amp;rsquo;s all for now.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Homelab 2025 Plans</title>
				<link>https://inherently.xyz/blog/homelab-2025-plans/</link>
				<pubDate>Fri, 28 Feb 2025 22:51:33 +0200</pubDate>
				<guid>https://inherently.xyz/blog/homelab-2025-plans/</guid>
				<description>&lt;h2 id=&#34;intro&#34;&gt;Intro&lt;/h2&gt;&#xA;&lt;p&gt;After recapping the state of my homelab and writing down how it was in the end of 2024, I think it&amp;rsquo;s time to look towards the future.&#xA;Having finally finished my thesis, I now have less constant stress to deal with and a bit more time than I&amp;rsquo;ve had in the last 2 and a half years.&#xA;The main goal of rebuilding my homelab is to make it an actual production environment.&#xA;This means that a few important problems need to be solved before it&amp;rsquo;s considered done.&#xA;Along with that, I&amp;rsquo;m willing to lose a bit of flexibility in exchange for having something that actually works which is a bit odd for me to write but alas.&lt;/p&gt;&#xA;&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;&#xA;&lt;p&gt;Over the past several years I&amp;rsquo;ve invested quite a bit into the hardware that already exists.&#xA;I won&amp;rsquo;t go into great depth about it, all the details are in the previous post.&#xA;My homelab is housed in a 27U rack, includes a managed switch, a DIY router, 3 virtualization hosts and at least one NAS.&#xA;That is more than enough to at least get started running several services.&#xA;I will try to avoid investing in hardware this year with two exceptions, a VGA KVM and a good NIC for the router.&#xA;Other than those two additions, I plan to focus on software choice and configuration.&lt;/p&gt;&#xA;&lt;h2 id=&#34;software&#34;&gt;Software&lt;/h2&gt;&#xA;&lt;h3 id=&#34;kubernetes&#34;&gt;Kubernetes&lt;/h3&gt;&#xA;&lt;p&gt;I&amp;rsquo;m going bare metal kubernetes.&#xA;This might seem counter-intuitive but it&amp;rsquo;s actually the easiest thing to get working.&#xA;I still like ProxMox, I&amp;rsquo;m happy with the terraform provider for working with ProxMox and there is now a healthy alternative one, I use ansible at work and it&amp;rsquo;s all nice but I&amp;rsquo;m looking for an even higher level of automation.&#xA;The integrations available for kubernetes are at a great point and have been for a couple of years now.&#xA;I can forego dealing with issues such as &amp;ldquo;how do I make DNS automatically update when I start running a new service&amp;rdquo; and focus more on running and using my self-hosted services.&#xA;Of course, kubernetes presents its own set of challenges and has its own quirks but I believe the tradeoff to be worth it for me.&lt;/p&gt;&#xA;&lt;p&gt;The plan right now is to go with &lt;a href=&#34;https://www.talos.dev/&#34;&gt;Talos Linux&lt;/a&gt; so my hosts are nice and lean.&#xA;The entire process of installation can be automated using the &lt;a href=&#34;https://matchbox.psdn.io/&#34;&gt;matchbox PXE server&lt;/a&gt; and a bit of configuration and the operating system has just enough to run kubernetes and that&amp;rsquo;s it.&#xA;I could of course regret this in which case I&amp;rsquo;ll go back to Debian my beloved but it remains to be seen.&#xA;Initially I&amp;rsquo;ll go with a simple ISO installation to get started and then I&amp;rsquo;ll see if I want to take it a step further.&#xA;The kubernetes-related stuff is mostly figured out, default CNI, nginx for ingress, metallb for external IPs, flux to deploy stuff and I&amp;rsquo;ll try adding renovate bot to help with maintenance.&#xA;What remains is to decide if I&amp;rsquo;m going to go with openebs or longhorn for storage but that shouldn&amp;rsquo;t be too difficult or time-consuming.&lt;/p&gt;&#xA;&lt;h3 id=&#34;router&#34;&gt;Router&lt;/h3&gt;&#xA;&lt;p&gt;The other interesting software choice is the router.&#xA;Having a dedicated machine for it seems wasteful and I&amp;rsquo;m bound to running whatever software is available for FreeBSD.&#xA;No, I&amp;rsquo;m not planning on moving away from OPNSense at the moment but I do want to start the vicious cycle again.&#xA;The plan is to have it in a VM, thus the vicious cycle, and then be able to run things like matchbox on the same machine, a different NTP server, a different DHCP or PXE server (mainly &lt;a href=&#34;https://tinkerbell.org/&#34;&gt;tinkerbell&lt;/a&gt; comes to mind), different DNS server (&lt;a href=&#34;https://github.com/hickory-dns/hickory-dns&#34;&gt;Hickory&lt;/a&gt; seems quite interesting) and so on.&#xA;Those could be containers inside other VMs or whatever else, I&amp;rsquo;m not bound to whatever is packaged for FreeBSD or even specifically for OPNSense.&#xA;This of course requires a hypervisor (ProxMox makes a comeback) and a NIC that can be passed through to a virtual machine in order to run the router.&#xA;This is a secondary concern since I do have an old machine from the core2duo days if I just want to runs some basic network infrastructure like the ones mentioned previously for experimentation purposes.&#xA;VyOS has also been on my mind but that&amp;rsquo;s a bigger jump and would require quite a bit of effort to adapt everything I have to it.&#xA;The router plans are unclear at the moment so it&amp;rsquo;s more of a backburner project.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;One must imagine Sisyphus, he rolls the rock and I rebuild my homelab.&#xA;Was there a point to writing this? I&amp;rsquo;m not sure.&#xA;These are my plans at the moment so I can get back into the hobby.&#xA;If I do go through with them, I&amp;rsquo;ll try to document the experience when I have something workable.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>State of Homelab 2024</title>
				<link>https://inherently.xyz/blog/homelab-2024/</link>
				<pubDate>Mon, 27 Jan 2025 22:38:48 +0200</pubDate>
				<guid>https://inherently.xyz/blog/homelab-2024/</guid>
				<description>&lt;p&gt;When operating a homelab there is always something new to do or something waiting to be fixed.&#xA;This post&amp;rsquo;s aim is to detail the state of my homelab at the end of 2024 and beginning of 2025.&lt;/p&gt;&#xA;&lt;h2 id=&#34;router&#34;&gt;Router&lt;/h2&gt;&#xA;&lt;p&gt;The previous post was about virtualizing pfSense inside ProxMox but this setup is no longer in use.&#xA;In its place, there is a new system running OPNSense on bare-metal.&#xA;This was done for a few reasons, the main one being that I wanted to move away from pfSense.&#xA;More than that, there was a circular dependency where the ProxMox host had to be up in order for the router to function but in order for the cluster nodes to talk to each other, the router needed to be online.&#xA;In practice this was not a huge issue but it bothered me since it made experimenting more difficult because recreating the cluster meant taking down the router as well.&#xA;I&amp;rsquo;ve lost a few things, mainly pfblocker-ng and native tailscale integration but they&amp;rsquo;re not as big of a loss as I had anticipated.&#xA;In the end I think it was worth it, over the course of the past few years the company making pfSense has acted against the best interest of pfSense users and I did not feel like using their software anymore.&lt;/p&gt;&#xA;&lt;h2 id=&#34;virtualization&#34;&gt;Virtualization&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;m still running ProxMox, although now it is a 3-node cluster.&#xA;I&amp;rsquo;ve spent a pretty significant amount of time tweaking the bootstrap process from a fresh install to having the entire homelab operational.&#xA;Somewhere along the line I tried making it so non-cluster operation of multiple hosts was supported but gave up on that eventually.&#xA;Each of the nodes has a 250GB SSD used as a boot drive and for node-local storage along with a 2TB HDD used as a Ceph OSD.&#xA;Since the last post about using ansible and terraform with ProxMox, I&amp;rsquo;ve figured out the process of adding tools to the debian image in the virtual machine template.&#xA;There is also the option to deploy using GitLab CI so just making committing and pushing to the repo is enough to create a new virtual machine.&#xA;The k3s virtual machine terraform configuration was improved significantly but I&amp;rsquo;ve not adopted modules yet which seems to be the next step for organization-related improvements.&#xA;I also run all software directly on top of debian virtual machines without containers to practice writing ansible.&#xA;At work, our team runs everything in Docker so it could be a good idea to start moving to something similar at home for the sake of practice.&lt;/p&gt;&#xA;&lt;h2 id=&#34;kubernetes&#34;&gt;Kubernetes&lt;/h2&gt;&#xA;&lt;p&gt;The kubernetes cluster got a significant update.&#xA;I&amp;rsquo;ve adopted FluxCD to a greater degree, figured out secrets storage and a pretty good structure for the YAML files.&#xA;The k3s cluster has 3 control plane nodes and 3 worker nodes, one per virtualization host.&#xA;I&amp;rsquo;m using longhorn for storage with plans to try and use the Ceph cluster as an additional storage class.&#xA;The networking setup consists of MetalLB to have an IP in the subnet and then run ingress-nginx as the ingress controller on that IP.&#xA;No plans for checking out Gateway API have been made at current but it is a good and necessary step forward in the ecosystem, I plan to move to it after things are a bit less in flux.&#xA;The DNS is manual right now due to the low amount of services but I&amp;rsquo;ve tested external-dns with PiHole and I&amp;rsquo;m aware of the OPNSense webhook option, it remains to be seen what I&amp;rsquo;ll end up using.&#xA;The setup needs a bit more tender love and care but it&amp;rsquo;s running well and doing what I need it to.&#xA;I have plans to move more stuff to the cluster after the foundation is solid and not just have my own demo applications in there.&#xA;The thought has crossed my mind to completely do away with ProxMox and then run Talos Linux bare metal on the systems but I&amp;rsquo;d be losing out on some flexibility which I don&amp;rsquo;t want to commit to right now.&#xA;All in all, kubernetes is still pretty fun and the 1.30 and later releases have made good quality of life improvements.&lt;/p&gt;&#xA;&lt;h2 id=&#34;nas&#34;&gt;NAS&lt;/h2&gt;&#xA;&lt;p&gt;Since I upgraded my desktop, the old one&amp;rsquo;s internals were transplanted to a different case are now a second NAS.&#xA;I&amp;rsquo;m saving up to get a big external drive so I can have an extra copy of the current main NAS so I can freely mess with them to have a solid backup solution.&#xA;The changes in TrueNAS Scale regarding applications has left me waiting for things to settle down before I commit to a final setup.&#xA;Overall nothing exciting on this front.&lt;/p&gt;&#xA;&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;&#xA;&lt;p&gt;I run mostly used office desktops and a basic managed switch.&#xA;I have 3 Dell Optiplex machines: 2nd gen, 3rd gen and 4th gen Intel i5 CPUs with RAM sizes ranging from 16 to 32GB each.&#xA;For storage they have a 250GB SSD and a 2TB HDD as mentioned earlier.&#xA;The router is a Fujitsu equivalent desktop with a 4th gen Intel Pentium and 8GB of RAM as well as a 500GB SSD.&#xA;My rackmount NAS is an i5 4570 with 16GB of RAM and 4x4TB HDDs in a 3-drive ZFS RAID-Z1 plus one hot spare.&#xA;My backup NAS is an i7 4770 with 32GB of RAM and 2x8TB HDDs in a 2-way ZFS mirror.&#xA;The main network switch is a Netgear GS724TV4, just a layer 2 managed gigabit switch.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;I wanted to write all of this down to have a reference for myself when I inevitably change something and it might help someone else as well.&#xA;Also the blog is back(?) after more than a 2 year silence, hopefully I will not neglect it for that long again.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>QEMU Guest Agent for Terraform on ProxMox</title>
				<link>https://inherently.xyz/blog/qemu-guest-agent-for-terraform-on-proxmox/</link>
				<pubDate>Wed, 27 Jul 2022 13:38:18 +0300</pubDate>
				<guid>https://inherently.xyz/blog/qemu-guest-agent-for-terraform-on-proxmox/</guid>
				<description>&lt;p&gt;In a &lt;a href=&#34;https://inherently.xyz/blog/ansible-terraform-and-proxmox/&#34;&gt;previous post&lt;/a&gt; I talked about how I set up proxmox in order to be able to provision virtual machines on it using terraform.&#xA;Since then, I&amp;rsquo;ve improved the setup by adding qemu-guest-agent to the template images without needing to create them myself from scratch and I&amp;rsquo;d like to share it here.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;&#xA;&lt;p&gt;A lot images intended for openstack or cloud use, be they debian or ubuntu or something else, do not include qemu-guest-agent by default.&#xA;This means that we either don&amp;rsquo;t get to enable that integration or have to do a complex dance of provisioning the VMs with the agent disabled, installing qemu-guest-agent, turning them off, applying a terraform plan with the agent enabled and booting them back up.&#xA;Obviously that&amp;rsquo;s very tedious, error-prone and time-consuming especially when creating and destroying potentially dozens of VMs for testing.&#xA;To figure out a solution, I went down a bit of a rabbit hole and considered a few solutions before settling on one so I&amp;rsquo;d like to take you through the selection process.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-solutions&#34;&gt;The Solutions&lt;/h2&gt;&#xA;&lt;p&gt;There are multiple ways to solve this problem and there isn&amp;rsquo;t really a standard go-to recommended one.&#xA;One of these might work better for your situation and that&amp;rsquo;s great however I will be detailing why I didn&amp;rsquo;t choose them.&lt;/p&gt;&#xA;&lt;h3 id=&#34;images-with-qemu-guest-agent-pre-installed&#34;&gt;Images with qemu-guest-agent pre-installed&lt;/h3&gt;&#xA;&lt;p&gt;This was my first instinct, just find images that have it already.&#xA;Unfortunately I couldn&amp;rsquo;t find a debian image that fit this criteria and overall it&amp;rsquo;s not a reliable solution, some distros might simply elect to not include it.&lt;/p&gt;&#xA;&lt;h3 id=&#34;terraform-remote-exec-provisioner&#34;&gt;Terraform remote-exec provisioner&lt;/h3&gt;&#xA;&lt;p&gt;I found &lt;a href=&#34;https://cloudalbania.com/posts/2022-01-homelab-with-proxmox-and-terraform/#considerations-when-creating-vms&#34;&gt;this great blog post&lt;/a&gt; by Besmir Zanaj which was really interesting and demonstrates how to use terraform to achieve post-provision VM customization.&#xA;It is worth checking out however for something so basic that all virtual machines need I decided it was better to bake it into the template rather than have the action run on each VM individually.&#xA;The example from the post about firewall rules is a great use-case for this functionality so it&amp;rsquo;s not to be discarded entirely.&lt;/p&gt;&#xA;&lt;h3 id=&#34;packer-proxmox-iso-builder&#34;&gt;Packer proxmox-iso Builder&lt;/h3&gt;&#xA;&lt;p&gt;Packer is another tool from Hashicorp, the same company behind terraform, that can create images to be used with proxmox and then make templates based on those images.&#xA;The functionality is offered by a plugin, specifically a builder, called &lt;a href=&#34;https://www.packer.io/plugins/builders/proxmox/iso&#34;&gt;proxmox-iso&lt;/a&gt;.&#xA;It didn&amp;rsquo;t appear to be a terrible choice but the &lt;a href=&#34;https://github.com/xcad2k/boilerplates/tree/main/packer/proxmox&#34;&gt;configuration examples that I found&lt;/a&gt; relied on launching ubuntu, waiting a certain amount of time then sending keystrokes to begin a no-cloud autoinstall.&#xA;This seemed to me to be very error-prone and distro-specific so I skipped it.&#xA;I don&amp;rsquo;t believe it to be a complete dead-end and it&amp;rsquo;s possible there is a better way to use it for what I want but I couldn&amp;rsquo;t figure out how.&lt;/p&gt;&#xA;&lt;h3 id=&#34;adding-qemu-guest-agent-using-guestfs-tools&#34;&gt;Adding qemu-guest-agent using guestfs-tools&lt;/h3&gt;&#xA;&lt;p&gt;The last thing I looked into was using guestfs-tools to modify the image before creating a proxmox template out of it.&#xA;Guest-fs tools is a set of tools for modifying virtual machine disk images that works on a lot of distros.&#xA;After lots of searching, I came across &lt;a href=&#34;https://austinsnerdythings.com/2021/08/30/how-to-create-a-proxmox-ubuntu-cloud-init-image/&#34;&gt;an awesome blog post&lt;/a&gt; by Austin Pivarnik which tackled basically the same problem.&#xA;As detailed in the post itself, on debian-based systems which luckily proxmox is, we can install &lt;code&gt;libguestfs-tools&lt;/code&gt; and then use the &lt;code&gt;virt-customize&lt;/code&gt; command to alter the contents of a virtual machine image.&#xA;How I added this to my setup:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;add &lt;code&gt;libguestfs-tools&lt;/code&gt; to the list of packages installed by my proxmox setup ansible playbook&lt;/li&gt;&#xA;&lt;li&gt;add a task (adapted for all VM images) to the same playbook after downloading the image but before creating the template&lt;/li&gt;&#xA;&lt;li&gt;run playbook&lt;/li&gt;&#xA;&lt;li&gt;ta-da!&#xA;You can see the changes I made &lt;a href=&#34;https://gitlab.com/insanitywholesale/infra/-/commit/831fe44f103c3650a41eca4722cce794e67ca741&#34;&gt;in this commit&lt;/a&gt; where I also adjusted my terraform configuration and a couple other small things.&#xA;I&amp;rsquo;ve been very happy with this so far and aside from showing the guest IP in the proxmox web interface as well as allowing smooth shutdown it has also improved provisioning times.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Having good templates for virtual machines on a virtualization platform is very important for automation.&#xA;While it took quite a long time for me to find a suitable solution I am quite happy with where I ended up and the improvement to my homelab.&#xA;Thank you for reading and I hope you learned something new.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Network Design Document</title>
				<link>https://inherently.xyz/blog/network-design-document/</link>
				<pubDate>Sat, 16 Jul 2022 18:45:44 +0300</pubDate>
				<guid>https://inherently.xyz/blog/network-design-document/</guid>
				<description>&lt;p&gt;I recently started remaking my network at home and decided to publish some of the design documentation here&lt;/p&gt;&#xA;&lt;h2 id=&#34;network-layout&#34;&gt;Network Layout&lt;/h2&gt;&#xA;&lt;p&gt;VDSL Internet comes in through an RJ11 port to a Vodafone H300s modem-router.&#xA;LAN port 2 of the H300s is plugged into port 2 (untagged VLAN 10) of the Netgear GS724Tv4 switch.&#xA;Switch port 23 (untagged VLAN 1, tagged in all other VLANs) is plugged into the gigabit ethernet port of the pfsense router.&#xA;All devices are plugged directly into the switch since they fit.&#xA;Inter-VLAN routing happens through pfsense and the switch operates as a managed L2 switch even though it has L3 capabilities.&lt;/p&gt;&#xA;&lt;h2 id=&#34;vlans&#34;&gt;VLANs&lt;/h2&gt;&#xA;&lt;p&gt;Probably overkill but certainly enough:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;VLAN&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Description&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Subnet&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;Gateway&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;DHCP range from pfsense&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;1&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Default&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;2&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Auto VoIP&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;3&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Auto-Video&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Border Router LAN&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.10.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.10.1&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;20&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;End Devices&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.20.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.20.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.20.10-245&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;22&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Trusted&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.20.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.22.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.22.22-222&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;30&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Monitoring&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.30.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.30.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;40&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Storage&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.40.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.40.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;50&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Servers&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.50.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.50.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;60&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Guest&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.60.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.60.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.60.2-252&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;65&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Media&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.65.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.65.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.65.2-252&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;66&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;IoT&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.66.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.66.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.66.2-252&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;67&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;DIY IoT&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.67.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.67.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.67.2-252&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;70&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Security&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.70.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.70.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;80&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;DMZ&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.80.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.80.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;90&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;APIs&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.90.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.90.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;99&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Management&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.99.0.0/16&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.99.0.1&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;111&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Kubernetes&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.111.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.111.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;113&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;MAAS&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.113.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.113.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;123&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Windows&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.123.0/24&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;10.0.123.254&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;150&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Test LAN&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;666&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Native&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;1022&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Unused Port&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;1337&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Danger&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;-&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;That&amp;rsquo;s my home LAN currently, I&amp;rsquo;ll try to keep this updated as I change stuff but no promises.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Ansible, Terraform and Proxmox</title>
				<link>https://inherently.xyz/blog/ansible-terraform-and-proxmox/</link>
				<pubDate>Fri, 24 Jun 2022 23:24:57 +0300</pubDate>
				<guid>https://inherently.xyz/blog/ansible-terraform-and-proxmox/</guid>
				<description>&lt;p&gt;In the continuing quest to improve my homelab I&amp;rsquo;ve written a few ansible playbooks as well as terraform configuration to automate a lot of tasks.&#xA;The initial setup of proxmox is handled by ansible, the provisioning of virtual machines is handled by terraform and the installation of k3s on the VMs is done by ansible.&lt;/p&gt;&#xA;&lt;h2 id=&#34;proxmox-setup-with-ansible&#34;&gt;Proxmox Setup with Ansible&lt;/h2&gt;&#xA;&lt;p&gt;Before getting to use all the shiny devops with a selfhosted solution, we need to do a bit of setup first.&#xA;This isn&amp;rsquo;t perfect since it&amp;rsquo;s just ansible running a bash script but it gets the job done.&#xA;The other issue,, is that a lot of cloud images don&amp;rsquo;t include qemu-guest-agent and other packages by default.&#xA;I have a few ideas how to solve that (check out this &lt;a href=&#34;https://github.com/insanitywholesale/home-infra/blob/master/TODO.md&#34;&gt;TODO.md&lt;/a&gt; for more info) but haven&amp;rsquo;t tested out anything yet.&#xA;Since qemu-guest-agent and things like nfs-common are required on most VMs, a lot of redundant package installation happens but such is life for now.&#xA;With that out of the way, let&amp;rsquo;s start with how I configure proxmox.&lt;/p&gt;&#xA;&lt;h3 id=&#34;host&#34;&gt;Host&lt;/h3&gt;&#xA;&lt;p&gt;While proxmox has a lot of things ready to go out of the box, a bit of configuration is always required and even more so in this case.&#xA;The goal of the following steps is to turn our hosts into capable, cloud-like, targets for provisioning resources using terraform.&lt;/p&gt;&#xA;&lt;h4 id=&#34;repository&#34;&gt;Repository&lt;/h4&gt;&#xA;&lt;p&gt;Initially the enterprise repository which we don&amp;rsquo;t have a license to access is enabled.&#xA;To fix this, I delete the file in &lt;code&gt;/etc/apt/sources.list.d&lt;/code&gt; that contains it and add a file with the no-subscription repository.&#xA;This might not be necessary since the &lt;a href=&#34;https://github.com/lae/ansible-role-proxmox&#34;&gt;lae.proxmox&lt;/a&gt; ansible role can do essentially the same thing and many more.&#xA;Here are the ansible tasks:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;remove enterprise repo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/etc/apt/sources.list.d/pve-enterprise.list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;absent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;add no-subscription repo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;pve-no-sub.list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/etc/apt/sources.list.d/pve-no-subscription.list&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0644&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;template-vm&#34;&gt;Template VM&lt;/h3&gt;&#xA;&lt;p&gt;The terraform provider for proxmox can work with cloud-init which is a great vendor-agnostic way of configuring the basics (username, password, IP addressing, DNS, SSH keys) in a virtualized environment.&#xA;This is achieved by having a virtual disk or virtual cd-rom that mounts inside the VM and provides this information to the guest.&lt;/p&gt;&#xA;&lt;h4 id=&#34;vm-image&#34;&gt;VM Image&lt;/h4&gt;&#xA;&lt;p&gt;Since software is not always compatible with the latest version of a linux distribution, in this case debian, I keep the last two versions around.&#xA;The first step is to download the images:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;get debian 10 cloud image&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;get_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://cloud.debian.org/images/cloud/buster/20211011-792/debian-10-generic-amd64-20211011-792.qcow2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/root/debian-10-openstack-amd64.qcow2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;checksum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sha512:f3dac13104b4e28eb62c46cbbb1e30fc9c792834500f9101d477c19c258c31ff04850933ee0b3e63236eca38c854447d95a0ab45163c4a3fccf05f9dd95601a5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0644&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;get debian 11 cloud image&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;get_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://cloud.debian.org/images/cloud/bullseye/20220121-894/debian-11-generic-amd64-20220121-894.qcow2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/root/debian-11-openstack-amd64.qcow2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;checksum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sha512:0948dc56b4834a7755e4eae7d5532e138b90484a949161ffe9fc6894c7a14b1bd32ebf96fa3f3d03d498fe7ee125f8014f31bfab5825915a93de9330df814f7b&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0644&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;template-script&#34;&gt;Template Script&lt;/h4&gt;&#xA;&lt;p&gt;As mentioned in the beginning I&amp;rsquo;d like to automate this with ansible but this is what I have for now:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -z &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9001&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -z &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;VMNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;debian-tmpl&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;VMNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;VMEXISTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;qm list &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;nv&#34;&gt;$VMID&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VMEXISTS&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;VM with &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already exists&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm create &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -name &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMNAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -memory &lt;span class=&#34;m&#34;&gt;1024&lt;/span&gt; -net0 virtio,bridge&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;vmbr0 -cores &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; -sockets &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; -cpu &lt;span class=&#34;nv&#34;&gt;cputype&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;kvm64 -description &lt;span class=&#34;s2&#34;&gt;&amp;#34;debbie image&amp;#34;&lt;/span&gt; -kvm &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; -numa &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm importdisk &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; debian-10-openstack-amd64.qcow2 local-zfs&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -scsihw virtio-scsi-pci -virtio0 local-zfs:vm-&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;-disk-0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -serial0 socket&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -boot c -bootdisk virtio0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#   qm set &amp;#34;${VMID}&amp;#34; -agent 1 #disabled since VM does not initially have qga installed&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -hotplug disk,network,usb,memory,cpu&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -vcpus &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -vga qxl&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -name &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMNAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -ide2 local-zfs:cloudinit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    qm template &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;VMID&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This works well enough for first-time setup and with a few additions could become idempotent.&#xA;The above script and its debian 11 equivalent are copied over to the proxmox hosts and executed by the following ansible tasks:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;get debian 10 template vm script&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;setup-debian-10-cloudinit.sh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/root/setup-debian-10-template.sh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0755&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;run debian 10 template vm script&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/root/setup-debian-10-template.sh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;get debian 11 template vm script&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;copy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;setup-debian-11-cloudinit.sh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/root/setup-debian-11-template.sh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0755&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;run debian 11 template vm script&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/root/setup-debian-11-template.sh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;terraform-setup&#34;&gt;Terraform Setup&lt;/h2&gt;&#xA;&lt;p&gt;With proxmox ready, let&amp;rsquo;s move on to the terraform setup.&#xA;If you haven&amp;rsquo;t used it before, terraform is a declarative way of describing our infrastructure.&#xA;It can manage virtual machines, DNS records, object storage buckets, kubernetes resources and many more things with the appropriate providers.&lt;/p&gt;&#xA;&lt;h3 id=&#34;provider&#34;&gt;Provider&lt;/h3&gt;&#xA;&lt;p&gt;Providers in terraform are plugins that enable terraform to manage resources that it doesn&amp;rsquo;t support out of the box.&#xA;In this case, we want to manage proxmox virtual machines and containers but it could be other things like a router running pfsense or vyos.&#xA;In previous versions, the provider would need to be installed manually but nowadays we only need to create a &lt;code&gt;main.tf&lt;/code&gt; with the provider listed and upon running &lt;code&gt;terraform init&lt;/code&gt;, the provider will be downloaded automatically.&lt;/p&gt;&#xA;&lt;h3 id=&#34;basic-maintf&#34;&gt;Basic &lt;code&gt;main.tf&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s create that file then.&#xA;Open your favorite editor, paste the following and replace the IP as well as the password with the ones applicable to your setup:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;terraform&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;required_providers&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;proxmox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;&#x9;source&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Telmate/proxmox&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;&#x9;version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt; &amp;#34;&amp;gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;provider&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;proxmox&amp;#34;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;alias&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pve&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_tls_insecure&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_api_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://192.168.70.1:8006/api2/json&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; #Replace IP&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_password&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;password123&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; #Replace password&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;root@pam&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Save the file and then run &lt;code&gt;terraform init&lt;/code&gt;.&#xA;You should see the following output (the version might be different):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Initializing the backend...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Initializing provider plugins...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Finding telmate/proxmox versions matching &amp;#34;&amp;gt;= 2.9.5&amp;#34;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Installing telmate/proxmox v2.9.10...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Installed telmate/proxmox v2.9.10 (self-signed, key ID A9EBBE091B35AFCE)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Partner and community providers are signed by their developers.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If you&amp;#39;d like to know more about provider signing, you can read about it here:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://www.terraform.io/docs/cli/plugins/signing.html&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Terraform has created a lock file .terraform.lock.hcl to record the provider&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;selections it made above. Include this file in your version control repository&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;so that Terraform can guarantee to make the same selections by default when&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;you run &amp;#34;terraform init&amp;#34; in the future.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Terraform has been successfully initialized!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;You may now begin working with Terraform. Try running &amp;#34;terraform plan&amp;#34; to see&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;any changes that are required for your infrastructure. All Terraform commands&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;should now work.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If you ever set or change modules or backend configuration for Terraform,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rerun this command to reinitialize your working directory. If you forget, other&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;commands will detect it and remind you to do so if necessary.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And ta-da! We&amp;rsquo;ve installed the provider and are ready to start creating resources.&lt;/p&gt;&#xA;&lt;h3 id=&#34;creating-a-test-vm&#34;&gt;Creating a test VM&lt;/h3&gt;&#xA;&lt;p&gt;The above file won&amp;rsquo;t do anything so we&amp;rsquo;ll declare a virtual machine and then tell terraform to create it.&#xA;The example below is specific to my setup so you probably want to modify it before using but here it is:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;terraform&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;required_providers&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;proxmox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;&#x9;source&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Telmate/proxmox&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;&#x9;version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt; &amp;#34;&amp;gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;provider&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;proxmox&amp;#34;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;alias&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pve&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_tls_insecure&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_api_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://192.168.70.1:8006/api2/json&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; #Replace IP&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_password&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;password123&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; #Replace password&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;pm_user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;root@pam&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;proxmox_vm_qemu&amp;#34; &amp;#34;proxmox_test_vm&amp;#34;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;provider&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;proxmox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;pve&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deb-10-test&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;target_node&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pve&amp;#34;&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;&#x9;/* change to debian-templ for 11 */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;clone&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;debian-tmpl&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;os_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cloud-init&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;cores&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;sockets&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;cpu&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;memory&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2048&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;scsihw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio-scsi-pci&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;bootdisk&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio0&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;agent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;disk&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;30G&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;storage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;local-zfs&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;network&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;model&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;bridge&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;vmbr0&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;ipconfig0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt; &amp;#34;ip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;192.168.50.25/16,gw&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;168&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;&#x9;/*workstation SSH key*/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;sshkeys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5jzKi37jm3517bqThbw+7LR/GXm3qC6Az5F+ZUa36vYM7Ygk2K5bWcFIL2YUCrkL5jfSsvoowONjCAxyuoyxtW4MJxnQLyq4u4yDsRC7YvBPAKZUYaHwnbkCfDs5a75dEFOoDxCA0DY2GrhqzBndaTcCfl0fZ4vN+9LcKOb1dSKiHeHvsh35YNtwntbL21meo+hiycUEgGwNe9/4kxKpdGTr7HvbeX2Fjm/UZBZIJKVcGop/3gCHXYnKH+OY5zc8cmt9Jg4CIwEqrSKeOX0bE8LSPRpVRXH4v8OcMaMei/HQejlH8NBwybEdJ4mhl8vHaFEjDbIWoOujmiRQF2263 angle@puddle&amp;#34;&lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;&#x9;/*required otherwise the state always appears modified*/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;lifecycle&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;ignore_changes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;k&#34;&gt;cipassword&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;k&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;k&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;After saving the file, we can run &lt;code&gt;terraform plan -out create-test-vm.plan&lt;/code&gt; to calculate the changes required and save them to a file.&#xA;Following that, we can run &lt;code&gt;terraform apply create-test-vm.plan&lt;/code&gt; to apply the changes to our infrastructure.&#xA;Some output will appear while the template is cloned, the VM settings are adjusted and the cloud-init configuration is put into the drive.&#xA;In the end, you should have a brand new VM created by terraform!&lt;/p&gt;&#xA;&lt;h3 id=&#34;creating-vms-for-k3s&#34;&gt;Creating VMs for k3s&lt;/h3&gt;&#xA;&lt;p&gt;The above example is realistic but what if we need 5 similar VMs that could be used as kubernetes nodes?&#xA;Conveniently, terraform provides a &lt;code&gt;count&lt;/code&gt; variable that we can use to slightly differ settings where needed.&#xA;Here is the resource that provisions the virtual machines that I run a k3s cluster on:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;proxmox_vm_qemu&amp;#34; &amp;#34;proxmox_vm_k3s&amp;#34;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;provider&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;proxmox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;pve&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deb-k3s-${count.index + 1}&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;target_node&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pve&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;clone&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;debian-tmpl&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;os_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cloud-init&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;cores&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;sockets&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;cpu&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;memory&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;3084&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;scsihw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio-scsi-pci&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;bootdisk&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio0&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;agent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;onboot&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;disk&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;30G&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;storage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;local-zfs&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;network&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;model&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtio&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;bridge&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;vmbr0&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;ipconfig0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt; &amp;#34;ip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;192.168.15.5${count.index + 1}/16,gw&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;168&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;sshkeys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5jzKi37jm3517bqThbw+7LR/GXm3qC6Az5F+ZUa36vYM7Ygk2K5bWcFIL2YUCrkL5jfSsvoowONjCAxyuoyxtW4MJxnQLyq4u4yDsRC7YvBPAKZUYaHwnbkCfDs5a75dEFOoDxCA0DY2GrhqzBndaTcCfl0fZ4vN+9LcKOb1dSKiHeHvsh35YNtwntbL21meo+hiycUEgGwNe9/4kxKpdGTr7HvbeX2Fjm/UZBZIJKVcGop/3gCHXYnKH+OY5zc8cmt9Jg4CIwEqrSKeOX0bE8LSPRpVRXH4v8OcMaMei/HQejlH8NBwybEdJ4mhl8vHaFEjDbIWoOujmiRQF2263 angle@puddle&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;lifecycle&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;&#x9;&#x9;ignore_changes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;k&#34;&gt;cipassword&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;k&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;k&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;There aren&amp;rsquo;t many changes from the previous example, the name and the IP address use the index in order to avoid 5 VMs having the same name and IP address and that&amp;rsquo;s it!&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Hopefully this gives you inspiration for some awesome things you can do to automate your infrastructure and make working in a virtualized environment easier.&#xA;Thank you for reading.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Cisco SR2024C Repair</title>
				<link>https://inherently.xyz/blog/cisco-sr2024c-repair/</link>
				<pubDate>Mon, 28 Mar 2022 18:03:46 +0300</pubDate>
				<guid>https://inherently.xyz/blog/cisco-sr2024c-repair/</guid>
				<description>&lt;p&gt;One of my friends at university gave me a broken switch that seemed broken and I decided to fix it.&#xA;Join me on a pretty entertaining troubleshooting path that was not entirely necessary.&lt;/p&gt;&#xA;&lt;h2 id=&#34;backstory&#34;&gt;Backstory&lt;/h2&gt;&#xA;&lt;p&gt;This semester in university I am taking a CCNA class.&#xA;The learning path is split across two semesters, next semester I&amp;rsquo;ll take CCNA 2 to be ready to get the certification.&#xA;A few of my friends are also there an one of them happened to have a supposedly broken Cisco switch.&#xA;Great opportunity to use it for hands-on learning, I thought.&#xA;He said it wasn&amp;rsquo;t fully broken, it could turn on fine but would turn off after 10-20 minutes.&#xA;Not that bad. A little fan was also missing from it but that would be no more than 5-10 euros to replace.&#xA;He gave it to me one day, I took it home and that was that.&#xA;After a bit of research I realized the switch wasn&amp;rsquo;t managed meaning it didn&amp;rsquo;t have Cisco iOS capabilities.&#xA;Nevertheless, I like tech necromancy and network gear seldom goes unused.&#xA;So that&amp;rsquo;s basically how I got a &lt;a href=&#34;https://www.cisco.com/c/en/us/obsolete/switches/cisco-sr2024c-compact-24-port-10-100-1000-gigabit-switch.html&#34;&gt;Cisco SR2024C&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;initial-findings&#34;&gt;Initial Findings&lt;/h2&gt;&#xA;&lt;p&gt;After checking that the power plug looked fine and the ports didn&amp;rsquo;t look damaged, I decided to turn it on.&#xA;Indeed, after roughly 20 minutes it started boot-looping so the behavior was as described.&#xA;The switch wouldn&amp;rsquo;t completely shut off, instead it followed a little pattern:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;lights flash for a second the way they do when first plugged in&lt;/li&gt;&#xA;&lt;li&gt;lights go out same as when normally booting&lt;/li&gt;&#xA;&lt;li&gt;goto step 1&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This meant that eventually anything plugged into it would drop off the network which is not good.&#xA;At this point I&amp;rsquo;m suspecting the power supply since the device is pretty old, about 7 years past its End-Of-Life date.&lt;/p&gt;&#xA;&lt;h2 id=&#34;open-wide&#34;&gt;Open Wide&lt;/h2&gt;&#xA;&lt;p&gt;Behavior confirmed and reproducible, we have a place to start from.&#xA;The device would need to be opened anyway in order to replace the fan and I&amp;rsquo;d like to inspect the inside too.&#xA;This specific switch is considered compact as noted by the ending &lt;code&gt;C&lt;/code&gt; in its model number (SR2024C).&#xA;Its width is a bit more than the width of the ports, 24 RJ45 gigabit ethernet ports and two miniGBIC.&#xA;It has holes to attach rackmount ears if desired but I wasn&amp;rsquo;t provided those.&#xA;On the front there is a plastic cover that fits over the 4 sets of ports (3 sets of 8xRJ45 and one set of the 2 miniGBIC) and also clips on to the top and bottom metal pieces.&#xA;I dinged the plastic since I used a pair of scissors to pry it off but that&amp;rsquo;s alright, we&amp;rsquo;re going for functional not pretty.&#xA;Following that, I had to carefully unhook some little metal tabs that held the top half of the metal case to the bottom half.&#xA;Push a little here, pull a little there and ta-da! We&amp;rsquo;re in.&#xA;The metal tabs were annoying to hook and unhook so I used a pair of pliers to twist them off.&#xA;On the left side there is a mesh cutout big enough for a 40mm fan and on the right side it&amp;rsquo;s almost entirely mesh.&#xA;Weird for a rackmountable device to have side-to-side airflow but what do I know.&#xA;The bottom is entirely bare and so is the top with the exception of a Cisco logo.&lt;/p&gt;&#xA;&lt;h2 id=&#34;guts&#34;&gt;Guts&lt;/h2&gt;&#xA;&lt;p&gt;There are two PCBs/boards inside, the main board and an open-frame power supply.&#xA;They are connected by a weird cable I&amp;rsquo;ve never seen before and have connectors I&amp;rsquo;ve never seen before.&#xA;On the PSU side it&amp;rsquo;s a 6-pin and a smaller 2-pin that merge into an 8-pin on the main board side.&#xA;The power plug is attached to the PSU through a 2-pin cable with a similar connector as well as a chassis ground point.&#xA;One good thing is that they all look removable and fairly easy to probe with a multimeter.&#xA;Overall The internals appear understandable so I&amp;rsquo;m fairly confident I can at least identify the issue.&lt;/p&gt;&#xA;&lt;h2 id=&#34;power&#34;&gt;Power&lt;/h2&gt;&#xA;&lt;p&gt;Even though I commented about the ease of probing with a multimeter, I&amp;rsquo;m sad to say that I didn&amp;rsquo;t have one previous to this experience.&#xA;Since I mostly work with software, either configuring or writing it, there was never a real need to own a multimeter.&#xA;I hopped on to one of the local electronic hardware supply stores&amp;rsquo; website and found one for around 15 euros, the &lt;a href=&#34;https://www.uni-trend.com/meters/html/product/General_Meters/DigitalMultimeters/UT131_Series/UT131C.html&#34;&gt;UNI-T UT131C&lt;/a&gt;.&#xA;It arrived the next morning so I got to work and confirmed what repair videos from similar switches said, the main board uses 5V power.&#xA;The thing is, in those other videos the voltage was lower and that was what was causing issues.&#xA;In my case it was nice and steady at 4,98V which is within margin of error meaning nowhere near enough to cause a malfunction.&#xA;You can never be certain though so I had ordered some alligator clips which I used for powering the main board from an ATX PSU&amp;rsquo;s molex connector.&#xA;It didn&amp;rsquo;t result in a normal boot but I at least got a power light.&#xA;This ruled out my main hypothesis this far which was that the switch&amp;rsquo;s power supply was going bad.&lt;/p&gt;&#xA;&lt;h2 id=&#34;accidental-solution&#34;&gt;Accidental Solution&lt;/h2&gt;&#xA;&lt;p&gt;In the process of hooking the switch up to the ATX power supply, I had it open for troubleshooting.&#xA;Perhaps accidentally, just to confirm that the problem was still there I reconnected the built-in power supply again.&#xA;After leaving for an hour or so to do something else, I came back and saw it wasn&amp;rsquo;t boot looping.&lt;/p&gt;&#xA;&lt;p&gt;What?&lt;/p&gt;&#xA;&lt;p&gt;Peculiar, I thought. Sure enough, plugging in my laptop to it showed a link light and the laptop got an IP address.&#xA;What the&amp;hellip; WAIT! By hovering over it I could feel the power supply putting out some heat.&#xA;No way it could be this simple, right? Could it be overheating?&#xA;I turned it off, closed the case and put a 120mm fan right up against the right side to pull air out of the switch.&#xA;To my surprise that was adequate to keep it cool enough even while closed.&#xA;This was so embarassingly simple that I had to test again.&#xA;I turned the switch on, let it get to the point where it starts constantly resetting and then put the fan next to it.&#xA;After about 5 minutes it started operating completely fine, I was in awe of how simply the problem was.&lt;/p&gt;&#xA;&lt;h2 id=&#34;fan-replacement&#34;&gt;Fan Replacement&lt;/h2&gt;&#xA;&lt;p&gt;Moving on to a permanent solution, I needed a fan to replace then one that was missing.&#xA;Looking things up online, I realized I need a 5V 1W fan that is 40mm wide and 20mm thick.&#xA;However, th only thing I found was a 0.75W fan for 8,23 euros.&#xA;Good enough I guess I&amp;rsquo;ll just get two of those, one for intake and one for exhaust.&#xA;Funny thing about plans, the store had only one of the 0.75W version and then one that was 0.54W.&#xA;Sigh&amp;hellip; Fine, I&amp;rsquo;ll see how I&amp;rsquo;ll arrange them.&#xA;A day later they came in, I tested them both out to see that they worked and put in the 0.75W fan just to be sure the internals get enough airflow.&#xA;After a 24-hour testing period, I think it&amp;rsquo;s safe to say that the problem is solved.&lt;/p&gt;&#xA;&lt;h2 id=&#34;use-case&#34;&gt;Use Case&lt;/h2&gt;&#xA;&lt;p&gt;The current plan is to use the switch for a VLAN so I don&amp;rsquo;t have to waste multiple ports from my main 24-port switch and be reconfiguring them.&#xA;Yes, port-based VLANs aren&amp;rsquo;t ideal but I need a place to test my next network remake without bothering everything else.&#xA;Even with the new fan it&amp;rsquo;s not very quiet probably due to the whine that small fans make but I have plenty of noisy things in my room.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;It was a long and weird journey but it ended well and I now have a new switch.&#xA;The troubleshooting was fun, as it always is, the new tools are fun to have and I got a lesson about assuming the problem is more complicated than it is.&#xA;Thank you for reading, I hope you enjoyed the journey cause I sure did.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Flux Update</title>
				<link>https://inherently.xyz/blog/flux-update/</link>
				<pubDate>Wed, 25 Aug 2021 00:44:34 +0300</pubDate>
				<guid>https://inherently.xyz/blog/flux-update/</guid>
				<description>&lt;p&gt;I wrote about my journey of choosing a continuous deployment tool and why I ultimately ended up using &lt;a href=&#34;https://toolkit.fluxcd.io/&#34;&gt;flux&lt;/a&gt; for my homelab &lt;a href=&#34;https://inherently.xyz/blog/fluxing-my-cluster/&#34;&gt;in this post&lt;/a&gt;.&#xA;It took quite a bit of reasearch and if you&amp;rsquo;re in a similar position as I was it might prove to be helpful.&lt;/p&gt;&#xA;&lt;h2 id=&#34;longish-term-experience&#34;&gt;Long(ish)-term experience&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been using it for about 5 months now, the first post was written about one month of use.&#xA;At that point I had been tinkering with it and attempting to get all the stuff I wanted to be deployed by it.&#xA;Some things were simple, others not so straight-forward.&lt;/p&gt;&#xA;&lt;h3 id=&#34;successes&#34;&gt;Successes&lt;/h3&gt;&#xA;&lt;h4 id=&#34;deploying-raw-manifest-applications&#34;&gt;Deploying raw manifest applications&lt;/h4&gt;&#xA;&lt;p&gt;Deploying raw kubernetes manifests was really easy.&#xA;Since I&amp;rsquo;m somewhat on the fence about Helm, I prefer using normal kubernetes manifests where possible.&#xA;This meant that for my use case mostly everything was smooth sailing after figuring out how to generate a kustomization yaml using the command-line tool.&lt;/p&gt;&#xA;&lt;h4 id=&#34;command-line-tool&#34;&gt;Command-line tool&lt;/h4&gt;&#xA;&lt;p&gt;Speaking of that, flux has a command-line tool to interact with the controllers running inside the cluster.&#xA;It&amp;rsquo;s also the way you can initialize a repository to be used as the place for flux files to be stored.&#xA;It can also be used to install flux to the cluster if the repository already exists.&lt;/p&gt;&#xA;&lt;h4 id=&#34;upgrading&#34;&gt;Upgrading&lt;/h4&gt;&#xA;&lt;p&gt;When a new version of flux comes out, you can upgrade and it will carry over to the cluster.&#xA;It&amp;rsquo;s really easy, it just upgrades its own files so when those are committed it will pull in the new version of the controllers.&lt;/p&gt;&#xA;&lt;h3 id=&#34;trouble&#34;&gt;Trouble&lt;/h3&gt;&#xA;&lt;h4 id=&#34;aggregation-yaml&#34;&gt;Aggregation yaml&lt;/h4&gt;&#xA;&lt;p&gt;For starters here is a minor one that took way too long to diagnose.&#xA;I forget exactly what this is called but essentially it is a yaml file says run deal with the listed resources.&#xA;Imagine the following directory contents:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;drwxrwxr-x 4 angle angle 4,0K Αυγ  25 01:23 .&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;drwxrwxr-x 5 angle angle 4,0K Ιουλ 21 03:42 ..&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;drwxrwxr-x 2 angle angle 4,0K Αυγ  13 15:55 helmrepos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-&lt;span class=&#34;l&#34;&gt;rw-rw-r-- 1 angle angle  219 Ιουλ 21 03:20 infra-source.yml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-&lt;span class=&#34;l&#34;&gt;rw-rw-r-- 1 angle angle  126 Αυγ  12 11:45 kustomization.yaml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;drwxrwxr-x 2 angle angle 4,0K Αυγ  13 15:56 storage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;kustomization.yaml&lt;/code&gt; file is as follows:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;kustomize.config.k8s.io/v1beta1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;kind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Kustomization&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;infra-source.yml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;helmrepos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;storage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;So it&amp;rsquo;s a way to more easily include stuff.&#xA;The issue I had is that I named the file &lt;code&gt;kustomization.yml&lt;/code&gt; instead of &lt;code&gt;kustomization.yaml&lt;/code&gt; which for some reason isn&amp;rsquo;t supported.&#xA;I believe this is a bug and not intended behavior but it was still frustrating to find and fix.&lt;/p&gt;&#xA;&lt;h4 id=&#34;logs&#34;&gt;Logs&lt;/h4&gt;&#xA;&lt;p&gt;Now on to more substantial issues.&#xA;While troubleshooting I got a bit frustrated with how flux displays errors.&#xA;The messages are fairly non-descript and there isn&amp;rsquo;t a lot of guidance for how to fix them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Despite a couple rough edges, flux has been working incredibly well.&#xA;Even before I got it fully functioning, it was amazing to be able to just install it to a newly creted cluster and have all my applications running just like that.&#xA;It&amp;rsquo;s almost magical and I&amp;rsquo;ve been enjoying it quite a lot.&#xA;If you aren&amp;rsquo;t using a continuous deployment tool, feel free to give &lt;a href=&#34;https://toolkit.fluxcd.io/&#34;&gt;flux&lt;/a&gt; a try or read the previous post to learn about some other options&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Droning On</title>
				<link>https://inherently.xyz/blog/droning-on/</link>
				<pubDate>Sat, 01 May 2021 18:54:59 +0300</pubDate>
				<guid>https://inherently.xyz/blog/droning-on/</guid>
				<description>&lt;p&gt;I described previously how the deployment of applications is automated in my homelab but didn&amp;rsquo;t touch upon how I test my own code.&#xA;The topic came up when I started trying to simulate a development pipeline who&amp;rsquo;s first step after committing code is to be run through the continuous integration system.&#xA;What should that system be though?&#xA;In this post, I&amp;rsquo;ll take you through the things I tried first and then why I went with &lt;a href=&#34;https://www.drone.io/&#34;&gt;drone&lt;/a&gt; in the end.&lt;/p&gt;&#xA;&lt;h2 id=&#34;choose-a-fighter&#34;&gt;Choose a Fighter&lt;/h2&gt;&#xA;&lt;p&gt;My quest is to ultimately end up with the skills to set up kubernetes so that it can be deployed to everything from a DIY NAS and a stack of NUCs to a warehouse full of servers backed by distributed storage.&#xA;I&amp;rsquo;m obviously more towards the first camp so that&amp;rsquo;s where my journey is at.&#xA;With that said, my goal is to have software small and lightweight enough that it can run on the former setup easily so that there can be multiple instances of it in the latter form.&#xA;The current mental model I have is developer organization with not much more than 3 NUCs + 1 NAS per team without losing the ability for continuous integration and continuous deployment.&#xA;Therefore the landscape needs to be explored and the obvious titan of the old world is &lt;a href=&#34;https://www.jenkins.io/&#34;&gt;jenkins&lt;/a&gt; with many newcomers eager to take its place.&#xA;The obvious caveats still apply, it must be open-source, able to be self-hosted, support for gitea is needed and being able to run well on kubernetes is a foregone conclusion.&lt;/p&gt;&#xA;&lt;h3 id=&#34;jenkins&#34;&gt;Jenkins&lt;/h3&gt;&#xA;&lt;p&gt;It should need no introduction, most developers are familiar with the trusty crusty old butler software.&#xA;&lt;a href=&#34;https://www.jenkins.io/&#34;&gt;Jenkins&lt;/a&gt; is probably one of the most prominent pieces of CI/CD software that was pushed to the forefront when the push for more automation and increased code quality really happened.&#xA;Sadly there are a few reasons that annoyed me from the get-go.&#xA;First, the unlocking procedure requires you to &lt;code&gt;kubectl logs &amp;lt;podname&amp;gt;&lt;/code&gt; in order to find the unlock key which I understand but nonetheless find annoying.&#xA;Second, the &lt;code&gt;Jenkinsfile&lt;/code&gt; has its own domain-specific language (DSL for short) that I find unappealing even though you won&amp;rsquo;t catch me praising YAML&amp;rsquo;s lack of curly braces.&#xA;I begrudgingly went though it and wrote a &lt;code&gt;Jenkinsfile&lt;/code&gt; to give it a fair chance but it wasn&amp;rsquo;t a nice experience.&#xA;Next, a single instance uses too much ram to the point that it can barely fit in my k3s VMs which use 2.5GB of ram each together with other software.&#xA;This is an issue because I like running at least 2 instances of most applications to be sure that everything works correctly when scaling up.&#xA;Last but not least, it&amp;rsquo;s a 2-in-1 solution which I don&amp;rsquo;t find appealing as far as architecture and since I was planning to find a standalone piece of software to do CI and another one to handle CD, it was a hard sell from the start.&#xA;As a redeeming quality it has an official kubernetes pipeline plugin which is nice so they&amp;rsquo;ve at least put thought into this use case.&#xA;Ultimately it wasn&amp;rsquo;t the right fit for me so it was time to move on.&lt;/p&gt;&#xA;&lt;h3 id=&#34;drone&#34;&gt;Drone&lt;/h3&gt;&#xA;&lt;p&gt;While pondering this I remembered an old post from one of the blogs I read, specifically &lt;a href=&#34;https://christine.website/blog/drone-kubernetes-cd-2020-07-10&#34;&gt;this one&lt;/a&gt;.&#xA;I said what the hell, why not and started looking its website.&#xA;&lt;a href=&#34;https://www.drone.io/&#34;&gt;Drone&lt;/a&gt; is a very nice and simple continuous integration tool.&#xA;From the start it seemed like it would be a good pick but you never know until you try.&#xA;I wrote some kubernetes manifests, got angry until I got them to work and a half hour later it was hooked up to my local gitea instance and ready to use.&#xA;I added a &lt;code&gt;.drone.yml&lt;/code&gt; to one of my repos, pushed the change, activated the repo from the drone dashboard, made another change to the source code, pushed it and waited to see what happened.&#xA;Instantly drone received the webhook event and got to work.&#xA;The dashboard is pretty simple (and sadly lacks a dark mode) so you just hit the thing you want to look at, click on the build and see it happen.&#xA;It supports different things running at the same time like databases if you want your tests to include that which can be run either as what drone calls &lt;code&gt;services&lt;/code&gt; aka run in the background from the beginning or if you want an ordered dependency you can use detached steps which is especially useful in microservices.&#xA;My only real complaint aside from the lack of dark mode is the inability to trigger a build manually without pushing but that&amp;rsquo;s only an issue when you first activate a repository inside drone&amp;rsquo;s dashboard.&#xA;All in all, it has been a joy to use, most of the projects I am currently developing have a &lt;code&gt;.drone.yml&lt;/code&gt; and get built at least 3 times a day when gitea mirrors the gitlab or github repo they&amp;rsquo;re mainly hosted at.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;This wasn&amp;rsquo;t as big of a journey as finding a continuous development tool because really I only found the two aforementioned options that had the basics I was looking for and one of them didn&amp;rsquo;t really fit the bill.&#xA;I&amp;rsquo;m not huge into software development, it&amp;rsquo;s mostly a hobby for me as might be obvious by now, since my main concern is infrastructure-related stuff.&#xA;With that said it&amp;rsquo;s useful to have the skills to build an application that can communicate with the kubernets api to automate something or write an ansible module and most of all it allows me to see the developer perspective.&#xA;I haven&amp;rsquo;t started looking into &lt;a href=&#34;https://github.com/mozilla/sops&#34;&gt;SOPS&lt;/a&gt; or &lt;a href=&#34;https://renovatebot.com/&#34;&gt;renovate bot&lt;/a&gt; or the &lt;a href=&#34;https://github.com/rancher/system-upgrade-controller&#34;&gt;k3s upgrade controller&lt;/a&gt; or &lt;a href=&#34;https://velero.io&#34;&gt;velero&lt;/a&gt; but I hope to get the chance to do so in the future.&#xA;Thank you for reading, I hope you enjoyed it and maybe learned something.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Fluxing My Cluster</title>
				<link>https://inherently.xyz/blog/fluxing-my-cluster/</link>
				<pubDate>Sat, 17 Apr 2021 17:24:22 +0300</pubDate>
				<guid>https://inherently.xyz/blog/fluxing-my-cluster/</guid>
				<description>&lt;p&gt;It&amp;rsquo;s no secret that I&amp;rsquo;m a fan of automation and making life easier (even if I made it harder in the first place).&#xA;One of the issues I&amp;rsquo;ve been having in my homelab is dealing with deploying stuff to kubernetes.&#xA;Initially I wanted to just add a plugin to &lt;a href=&#34;https://www.drone.io/&#34;&gt;drone&lt;/a&gt; and be done with it.&#xA;However, that didn&amp;rsquo;t really pan out which ended up being to my benefit since I discovered &lt;a href=&#34;https://toolkit.fluxcd.io/&#34;&gt;flux&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;/h2&gt;&#xA;&lt;p&gt;The cluster in its current state is a little sad because I end up doing too many things manually.&#xA;Whenever something changes it&amp;rsquo;s time to bring out ye old &lt;code&gt;kubectl apply -f&lt;/code&gt; in a local clone of the repo and that doesn&amp;rsquo;t spark joy.&#xA;This was obviously bad form and couldn&amp;rsquo;t continue.&#xA;What you also have to keep in mind is that I&amp;rsquo;ve chosen a 3rd-party storage plugin, &lt;a href=&#34;&#34;&gt;democratic-csi&lt;/a&gt; and assume it&amp;rsquo;s the default storageclass in the cluster.&#xA;This means that on a new cluster it&amp;rsquo;s required that before anything else, that one is added as a storageclass and set as default and &lt;code&gt;local-path&lt;/code&gt; is removed from being a default.&#xA;After that, the applications can be deployed which includes a mix of stuff I&amp;rsquo;ve written for the purposes of testing as well as 3rd-party software.&#xA;Now that the stage has been set, let&amp;rsquo;s see what I tried&lt;/p&gt;&#xA;&lt;h2 id=&#34;solutions&#34;&gt;Solutions&lt;/h2&gt;&#xA;&lt;h3 id=&#34;drone-ci-plugin&#34;&gt;Drone CI plugin&lt;/h3&gt;&#xA;&lt;p&gt;Initially the idea was that since I&amp;rsquo;ve alrady solved this for code using drone for CI (this will be discussed in a later post), I could just use a plugin and be done.&#xA;However, my experience with writing helm charts is limited and the only official plugin for deploying to kubernetes is for helm charts, not kubernetes manifests.&#xA;Furthermore, as I mentioned previously, not all software deployed on the cluster is something that I have written so even if there was an official kubernetes manifest plugin it wouldn&amp;rsquo;t cover 3rd-party software.&#xA;At this point, I was thinking of finding some all-inclusive CI/CD software that would cover everything I wanted to do.&#xA;It took no more than 10 seconds of thinking to realize that I was looking for non-modular software and discard that idea.&lt;/p&gt;&#xA;&lt;h3 id=&#34;standalone-continuous-delivery&#34;&gt;Standalone Continuous Delivery&lt;/h3&gt;&#xA;&lt;p&gt;This was the obvious choice but the software in this category is plentiful.&#xA;The main competitors were &lt;a href=&#34;https://toolkit.fluxcd.io/&#34;&gt;flux&lt;/a&gt;, &lt;a href=&#34;https://argoproj.github.io/projects/argo-cd/&#34;&gt;argo&lt;/a&gt; and &lt;a href=&#34;https://tekton.dev/&#34;&gt;tekton&lt;/a&gt;.&#xA;Their designs differ quite a bit so there is going to be quite a bit of opinion in the following analysis so just keep that in mind.&#xA;The few things they had in common were that they were all advertised as cloud-native with support for kubernetes, had a cli and were written in Go.&lt;/p&gt;&#xA;&lt;h4 id=&#34;argocd&#34;&gt;ArgoCD&lt;/h4&gt;&#xA;&lt;p&gt;I started with argo because one of the people that wrote a really good blog post on using kubernetes at home mentioned that they use it so I thought I&amp;rsquo;d try it first.&#xA;The installation process required a massive yaml file that you just &lt;code&gt;curl | kubectl apply -f&lt;/code&gt; which I wasn&amp;rsquo;t a big fan of but alright whatever.&#xA;It also had a weird unlock procedure like jenkins where you have to find a token generated at runtime to unlock it but that&amp;rsquo;s okay, just an one-time setup thing.&#xA;After spending a couple evenings with it, I wasn&amp;rsquo;t satisfied with the experience.&#xA;The docs weren&amp;rsquo;t really good at explaining all the argo custom resources and getting a basic single-pod application running took me more than 2 hours.&#xA;It was doable but this was going to be something I had to do for every application running on my cluster and the prospect didn&amp;rsquo;t seem appealing.&#xA;I&amp;rsquo;m sure with more time I could maybe become more familiar and eventually warm up to it however first impressions were bad so I decided to move on.&lt;/p&gt;&#xA;&lt;h4 id=&#34;tekton&#34;&gt;Tekton&lt;/h4&gt;&#xA;&lt;p&gt;Tekton&amp;rsquo;s marketing was interesting so I took a look at it next.&#xA;It seemed to be easier to set up and a couple random blog posts seemed to praise it so I downloaded another massive installation yaml which the guide told me to just &lt;code&gt;kubectl apply -f&lt;/code&gt; which is okay I guess.&#xA;I spent a few hours with it and it became clear you basically had to use it both for CI and CD so I put it to the side and moved on.&lt;/p&gt;&#xA;&lt;h4 id=&#34;flux&#34;&gt;Flux&lt;/h4&gt;&#xA;&lt;p&gt;So why did I mention this one first but try it last?&#xA;A few reasons.&#xA;While researching, the v1 -&amp;gt; v2 development effort was going on and v2 didn&amp;rsquo;t have a lot of features but v1 was being phased out so I didn&amp;rsquo;t know if I should spend time learning v1 while v2 was coming along or if it&amp;rsquo;s worth jumping into alpha/beta stage software to avoid using legacy versions.&#xA;By the time I did get around to it though v2 was clearly the way forward.&#xA;Not only was it officially endorsed but among people that self-host, it was already the way to go 6-12 months ago.&#xA;The docs were pretty clear, the cli was cross-platform and could be installed on a Raspberry Pi (something that argo at the time didn&amp;rsquo;t have available) and the examples worked.&#xA;In an evening I had learned basically everything I needed to in order to just drop it in, generate the flux CRDs for my existing kubernetes manifests as well as helm charts and be up and running.&#xA;The only issue I had, probably just a pet peeve of mine, was that the repo it creates on github is private by default and my goal is to have everything public and also secure (not there yet) but whatever.&#xA;Flux v2 also mentioned as the gitops toolkit is made up of several different parts that have a specific purpose which is something I certainly appreciate.&#xA;All in all, I think I&amp;rsquo;m going to stick with flux but you never know how homelab things will end up.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Flux is a really great project and I&amp;rsquo;ve enjoyed using it so far.&#xA;The problem of continuous delivery has been solved for me and I recommend checking out if you&amp;rsquo;re in a similar position.&#xA;Next up, I&amp;rsquo;m going to look at &lt;a href=&#34;https://renovatebot.com/&#34;&gt;renovate bot&lt;/a&gt; for automating image updates, &lt;a href=&#34;https://github.com/mozilla/sops&#34;&gt;SOPS&lt;/a&gt; for secret management (which &lt;a href=&#34;https://toolkit.fluxcd.io/guides/mozilla-sops/&#34;&gt;flux supports&lt;/a&gt; and &lt;a href=&#34;https://github.com/rancher/system-upgrade-controller&#34;&gt;an upgrade controller&lt;/a&gt;) to further help automate operations.&#xA;Thank you for reading, I hope you enjoyed it and maybe learned something.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Homelab Current Form</title>
				<link>https://inherently.xyz/blog/homelab-current-form/</link>
				<pubDate>Sun, 07 Feb 2021 14:35:32 +0200</pubDate>
				<guid>https://inherently.xyz/blog/homelab-current-form/</guid>
				<description>&lt;p&gt;The first part of the software changes I made was covered &lt;a href=&#34;https://inherently.xyz/blog/homelab-evolved/&#34;&gt;in the first part&lt;/a&gt; where I explained how and why I started going down this path.&lt;/p&gt;&#xA;&lt;h2 id=&#34;software-choices&#34;&gt;Software choices&lt;/h2&gt;&#xA;&lt;p&gt;This whole journey was about making my home infrastructure better.&#xA;Part of that was about having a way to more easily create the foundation on which kubernetes would run on, as well as describing my setup as code.&#xA;Proxmox is a beast in its own right. Features include being able to manage kvm virtual machines and lxc containers, an API that can be used to interact with it programmatically and most importantly being open source.&#xA;While researching what automation tools could interact with proxmox, I found a community-made terraform provider as well as a set of two ansible community modules (kvm and lxc).&#xA;After thinking about it a little bit, I wanted to use terraform in a non-cloud environment but also gather some knowledge about it so that’s what I decided to use.&#xA;I can have my provisioning requirements in a file that terraform understands and store it in git which is exactly what I was going for.&#xA;Ansible is still in the picture since it is used to set up and configure the debian environment inside the virtual machines.&#xA;Now that the hypervisor part is covered, let&amp;rsquo;s move on to running services.&lt;/p&gt;&#xA;&lt;h2 id=&#34;making-it-store-is-harder-than-making-it-run&#34;&gt;Making it store is harder than making it run&lt;/h2&gt;&#xA;&lt;p&gt;As mentioned &lt;a href=&#34;https://inherently.xyz/blog/homelab-evolved/&#34;&gt;in the first part about software changes&lt;/a&gt;, I was learning kubernetes and now I could not only wipe and recreate the cluster itself but also the entire virtual machines that it was running on.&#xA;Some time after starting to use proxmox with terraform I attempted to use rancher to manage kubernetes but ended up ditching it due to various problems with running even basic stuff on it (very likely that it’s a case of PEBCAK, I don’t think rancher is terrible or anything like that).&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-problem&#34;&gt;The problem&lt;/h3&gt;&#xA;&lt;p&gt;However the problem of shared storage continued to taunt me for the following months.&#xA;There was seemingly nothing that a simple fella could do to use a nice and simple NAS running truenas core as storage that is able to be dynamically provisioned for use by kubernetes.&#xA;Now, I hear you, &amp;ldquo;what about nfs-client-provisioner&amp;rdquo;, someone less familiar with this pile of madness might exclaim.&#xA;Indeed it does exist and barely work except the helm chart for it is deprecated and it does not work with kubernetes version 1.20 and later since it does not seem to be using CSI drivers.&lt;/p&gt;&#xA;&lt;h3 id=&#34;i-really-tried&#34;&gt;I really tried&lt;/h3&gt;&#xA;&lt;p&gt;Months of furious and frustrating testing ensued.&#xA;Not only was I trying to get applications running on kubernetes, I was also fighting with the unexpectedly complex tast of using the storage server I had available.&lt;/p&gt;&#xA;&lt;h4 id=&#34;glusterfs&#34;&gt;glusterfs&lt;/h4&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve gone through basically any and all commonly suggested options for dynamically provisioned storage.&#xA;Prette early on I tried glusterfs with heketi by making 3 LXC containers and mounting an nfs share to each one that would serve as the brick in the gluster volume.&#xA;Suffice it to say that it didn&amp;rsquo;t work and things were getting out of hand.&lt;/p&gt;&#xA;&lt;h4 id=&#34;longhorn&#34;&gt;longhorn&lt;/h4&gt;&#xA;&lt;p&gt;After a bit more research and I found out that longhorn, another project by the authors of k3s, used iscsi to communicate with kubernetes.&#xA;That could work I thought, except there was no coherent example of how to use it without using targetd for iscsi.&#xA;Longhorn was starting to look more appealing, I could just put the virtual drives of the VMs on an nfs share, run longhorn inside the VMs to pool all their storage together and call it good enough.&#xA;No, I could not give up yet.&#xA;A sub-optimal solution would do if there was no other way but I was convinced something more was out there.&#xA;My patience and hope were running out but not empty yet.&lt;/p&gt;&#xA;&lt;h4 id=&#34;success&#34;&gt;success&lt;/h4&gt;&#xA;&lt;p&gt;That all changed in early January where during my nearly daily search for possible storage solutions I hadn’t tried, I found out about &lt;a href=&#34;https://github.com/democratic-csi/democratic-csi&#34;&gt;democratic-csi&lt;/a&gt;.&#xA;This was it. Made to be used with freenas, truenas as well as DIY ZFS setups.&#xA;The silver bullet was here.&#xA;Just a few minutes of reading about it and writing my configs, a short(read: long) helm command later and&amp;hellip;success!&#xA;The test pod was using the newly created storageclass that was backed by the nfs share on truenas.&#xA;After that I rushed to deploy my standard set of gitea, droneci and minecraft to test it out and it was working for real without a hitch.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;This was a long journey and it isn’t coming to a close any time soon.&#xA;The next step is to continuous deployment but that’s an issue for another time.&#xA;To conclude as briefly as possible, I’ve no put most of the critical pieces of my homelab in a single git repo that I can use to recreate almost all of it from scratch with minimal manual intervention (there are still a few quirks like not having dynamic inventory for ansible and having to manually copy IPs but I can put that aside for now).&#xA;Despite the imperfections like not having dynamic inventory for ansible or having secrets stored unencrypted in git, I&amp;rsquo;m very happy with the setup is working.&#xA;If you missed them, make sure to check out the &lt;a href=&#34;https://inherently.xyz/blog/hardware-updates-2020/&#34;&gt;hardware updates&lt;/a&gt; and &lt;a href=&#34;https://inherently.xyz/blog/homelab-evolved/&#34;&gt;the first part about software changes&lt;/a&gt; for a better of what I&amp;rsquo;ve been up to.&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Homelab Evolved</title>
				<link>https://inherently.xyz/blog/homelab-evolved/</link>
				<pubDate>Sun, 07 Feb 2021 13:53:10 +0200</pubDate>
				<guid>https://inherently.xyz/blog/homelab-evolved/</guid>
				<description>&lt;p&gt;The hardware side of the changes made to my homelab were covered &lt;a href=&#34;https://inherently.xyz/blog/hardware-updates-2020/&#34;&gt;in a previous post&lt;/a&gt; where I also alluded to some software changes.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-came-before&#34;&gt;What came before&lt;/h2&gt;&#xA;&lt;p&gt;This is the first part explaining more in-depth the issues that I had and how I dealt with them.&#xA;Let&amp;rsquo;s set the stage first, my homelab was working fine in many ways.&#xA;It was nice and stable debian install running kvm virtual machines using qemu and libvirt with virt-manager to perform the simpler start/stop tasks.&#xA;There was really nothing wrong with it, I was exploring different software, running some services on the local network and even hosting a public website on it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;good-enough-is-not-good-enough&#34;&gt;Good enough is not good enough&lt;/h2&gt;&#xA;&lt;p&gt;However as someone interested in infrastructure a few things were bothering me.&#xA;Sure, I was using docker-compose with traefik for my public website and services.&#xA;Yes, I was using ansible to manage the configuration of most virtual machines.&#xA;But &amp;ldquo;good enough&amp;rdquo; and &amp;ldquo;I guess it works&amp;rdquo; doesn&amp;rsquo;t cut it.&#xA;On the upside, I really liked having ZFS snapshots on a 2x2TB mirror.&#xA;The ability to go back to a point in time where things were not broken had saved me a couple times when I inevitably broke one thing or deleted a file that could be replaced but would take a while.&#xA;My backups were also on that ZFS mirror, on a different dataset of course, and that also very useful.&#xA;I knew I wanted ZFS and that there was much room for improvement in regards to handling how I was running services. The single docker-compose virtual machine for the public stuff and another one for local stuff were mostly adequate but the manual management was not.&#xA;Not to mention that and all my precious stuff was on one box which is well below ideal.&lt;/p&gt;&#xA;&lt;h2 id=&#34;taking-the-step&#34;&gt;Taking the step&lt;/h2&gt;&#xA;&lt;p&gt;One day I decided it was time to move up in the world.&#xA;Despite using docker and docker-compose for years I had never dived into kubernetes because it seemed difficult and complex.&#xA;New syntax, new system with its own architecture and internal structure, new workflow, new everything.&#xA;I decided to set up 3 VMs and played with default k8s as well as k3s on them.&#xA;Dipping my toes into it was pretty fun and since nothing depended on it I was free to wipe it and start over.&#xA;The same issue kept cropping up, having to manually install debian thrice and set up kubernetes just to delete all of it and redo it was again, less than ideal&#xA;Initially I started writing a playbook before finding out that someone smarter had already gone down this path.&#xA;Setting up &lt;a href=&#34;https://github.com/k3s-io/k3s-ansible&#34;&gt;k3s-ansible&lt;/a&gt; was easy so there was at least kubernetes setup automation but the whole thing was too thrown together there was no shared storage.&#xA;However, I was becoming more familiar with kubernetes and learning the concepts as well as how to write yaml manifests.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;At some point it became too bothersome, a lot of manual work was involved and basic stuff like copying over ssh keys was also done mostly manually so I had to move on.&#xA;While all of this was going on, I had started planning what hardware updates I would get which you can read about here: &lt;a href=&#34;https://inherently.xyz/blog/hardware-updates-2020/&#34;&gt;Hardware Updates 2020&lt;/a&gt;&lt;/p&gt;&#xA;</description>
			</item>
			<item>
				<title>Hardware Updates 2020</title>
				<link>https://inherently.xyz/blog/hardware-updates-2020/</link>
				<pubDate>Fri, 15 Jan 2021 21:10:38 +0200</pubDate>
				<guid>https://inherently.xyz/blog/hardware-updates-2020/</guid>
				<description>&lt;h2 id=&#34;getting-a-real-storage-server&#34;&gt;Getting a real storage server&lt;/h2&gt;&#xA;&lt;p&gt;During 2020 I got a few upgrades to my setup but I don’t remember the exact order of them.&#xA;The most exciting was a 4U rackmount case that I could use to put up to 6×3.5″ hard drives by default and up to 9 with a 2×5.25″ to 3×3.5″ hotswap bay.&#xA;Also I bought 3x4TB ironwolf hard drives to put in it initially because my 2x2TB mirror was regularly reaching 95% capacity meaning I had to prune the snapshots regularly and couldn’t use it to store more files on it.&#xA;This made me warm and fuzzy inside but the old mirror had to sit on the bench for this transition.&#xA;The power supply in my server had only 4 sata connections which would be enough for a boot SSD and one of the arrays but not everything at once.&#xA;Initially that wasn’t a problem, installed truenas core on the ssd, set up the 3 4TB hard drives in a raidz1 configuration and started creating datasets and shares.&lt;/p&gt;&#xA;&lt;h2 id=&#34;adding-some-extra-spice&#34;&gt;Adding some extra spice&lt;/h2&gt;&#xA;&lt;p&gt;After a while I wanted to access the data on the old miror which meant having to buy a new power supply so I got one.&#xA;Namely the Corsair CV550 which has 7 sata power connectors, more than enough to power the five hard drives and the one SSD.&#xA;Moving on to issue number two, data connections of which the motherboard only had 4 of.&#xA;Admittedly 50 euros for an extra 4 sata ports seemed excessive but I saved up and acquired a nice and simple pcie card that did the job, no raid controller of course.&#xA;Alright, we’re cooking with gas now, storage is taken care of.&lt;/p&gt;&#xA;&lt;h2 id=&#34;dealing-with-separation-of-concerns&#34;&gt;Dealing with separation of concerns&lt;/h2&gt;&#xA;&lt;p&gt;However, I used to have a multi-purpose server and now it is just a NAS so I can’t run all my services anymore.&#xA;Fear not because the trusty old and used Dell Optiplex came to the rescue.&#xA;A shop near my house had one with an i5 2400 and 4gb of ram as well as a 250gb hard drive with windows on it for just 130 euros so I jumped on it.&#xA;First things first, I can&amp;rsquo;t be using a mechanical hard drive for the operating system and proxmox doesn&amp;rsquo;t dual boot so the HDD has to be replaced.&#xA;Luckily the 240gb SSD from when I originally built my desktop is still alive and it&amp;rsquo;ll do more than fine for this purpose.&#xA;The hard drive will be put aside for now but rest assured I do plan to use it at some point.&lt;/p&gt;&#xA;&lt;h2 id=&#34;serially-accessing-memories-about-ram-upgrades&#34;&gt;Serially accessing memories about ram upgrades&lt;/h2&gt;&#xA;&lt;p&gt;More importantly, I got a handle on the ram situation of my NAS.&#xA;Upgraded that beast from 12 to 16 gigabytes of ram which left the 4gb stick as a spare.&#xA;Not being one to miss out on some extra ram, the spare got added to the optiplex.&#xA;Going from 4 to 8 is nice but I want to run more than 2 virtual machines.&#xA;With that in mind and a deal available, I added an 8gb to the optiplex.&#xA;So we&amp;rsquo;re up to 16(8+8) gigabytes for the NAS and 16(2+2+4+8) gigabytes for the server..&#xA;An odd configuration but ram is ram and you bet I’ll use it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;Perfect, we had storage and now we have compute as well.&#xA;How was this hardware used though? Check back later (or read the next post if it&amp;rsquo;s up) to find out.&lt;/p&gt;&#xA;</description>
			</item>
	</channel>
</rss>
