<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Metal as a Service on Zwindler's Reflection</title><link>https://blog.zwindler.fr/en/tags/metal-as-a-service/</link><description>Recent content in Metal as a Service on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Sat, 04 Jan 2025 18:00:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/en/tags/metal-as-a-service/index.xml" rel="self" type="application/rss+xml"/><item><title>Sidero Omni - Talos Linux on Oracle Cloud (free tier)</title><link>https://blog.zwindler.fr/en/2025/01/04/sidero-omni-talos-linux-on-oracle-cloud-free-tier/</link><pubDate>Sat, 04 Jan 2025 18:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/en/2025/01/04/sidero-omni-talos-linux-on-oracle-cloud-free-tier/</guid><description>&lt;img src="https://blog.zwindler.fr/2025/01/omni-oracle.webp" alt="Featured image of post Sidero Omni - Talos Linux on Oracle Cloud (free tier)" /&gt;&lt;p&gt;Fun fact, on January 4th, 2024 (exactly one year ago), my first article of the year was about &lt;a class="link" href="https://blog.zwindler.fr/2024/01/04/un-peu-plus-loin-avec-maas-canonical" &gt;Maas&lt;/a&gt;. Starting 2025, on the same day, with another article about a solution that aims to automate infrastructure, especially bare metal, is funny :)&lt;/p&gt;
&lt;h2 id="context"&gt;Context
&lt;/h2&gt;&lt;p&gt;I won!!!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/sidero-win.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;I occasionally play games on social media (less often now) and I also sometimes enter contests at conferences.&lt;/p&gt;
&lt;p&gt;And there, I won a one-year subscription to Sidero Labs&amp;rsquo; SaaS (the creators of Talos Linux), &lt;strong&gt;Omni&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For those wondering, Omni is a Kubernetes cluster deployment solution that allows you to orchestrate servers running Talos, a minimalist and secure Linux operating system dedicated to Kubernetes. As for Talos, we&amp;rsquo;ll certainly talk about it in future articles.&lt;/p&gt;
&lt;h2 id="what-does-this-have-to-do-with-oracle-cloud"&gt;What Does This Have to Do with Oracle Cloud?
&lt;/h2&gt;&lt;p&gt;Winning is great, it&amp;rsquo;s always nice. But what do I do with this SaaS now?&lt;/p&gt;
&lt;p&gt;The first idea that comes to mind is to order a dedicated server somewhere and install Talos on it (with an ISO generated by Omni), or do the same thing but install a hypervisor, then create Talos Linux VMs (again, thanks to Omni).&lt;/p&gt;
&lt;p&gt;But I&amp;rsquo;m &lt;del&gt;cheap&lt;/del&gt; eternally frugal and I saw that Oracle Cloud Infrastructure (OCI) is supported by Talos Linux and Omni, so I wanted to try it.&lt;/p&gt;
&lt;p&gt;For those who don&amp;rsquo;t know OCI, I wrote a series of articles in 2023 explaining how to create a free cluster with &lt;code&gt;kubeadm&lt;/code&gt; on the (quite generous) free tier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2023/04/24/cluster-kubernetes-gratuit-part1/" &gt;A free Kubernetes cluster for your personal labs! - part 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2023/05/23/cluster-kubernetes-gratuit-part2/" &gt;A free Kubernetes cluster for your personal labs! - part 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;re going to reuse the free tier here, but to deploy and manage clusters with Omni.&lt;/p&gt;
&lt;p&gt;Note: you can reread them, but I&amp;rsquo;ve done better since then because I managed to integrate free tier machines INTO a managed Kubernetes cluster, which is much nicer to use. Stay tuned for the upcoming article ;).&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites
&lt;/h2&gt;&lt;p&gt;For Talos Linux on Oracle Cloud Infrastructure (OCI) and more specifically integrating machines with Omni, there are a few necessary configuration steps.&lt;/p&gt;
&lt;p&gt;Note: this tutorial is partially based on &lt;a class="link" href="https://www.talos.dev/v1.9/talos-guides/install/cloud-platforms/oracle/" target="_blank" rel="noopener"
&gt;the official Talos Linux documentation&lt;/a&gt;, adapted for Omni and with additional details on Oracle Cloud Infrastructure.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m assuming you already have an account on Oracle Cloud Infrastructure, as well as the &lt;code&gt;talosctl&lt;/code&gt; binaries and the &lt;code&gt;oci&lt;/code&gt; CLI. Otherwise, a quick:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew install oci-cli talosctl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Authenticate with the CLI tool:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;oci session authenticate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When authentication is requested, choose the region corresponding to your location (for example, eu-paris-1). Once done, you&amp;rsquo;ll see a confirmation message in the browser and you&amp;rsquo;ll need to give a cute name to the profile for &lt;code&gt;oci&lt;/code&gt; in the terminal and validate.&lt;/p&gt;
&lt;h2 id="retrieving-the-compartment-id"&gt;Retrieving the Compartment ID
&lt;/h2&gt;&lt;p&gt;One of the interesting concepts of Oracle Cloud Infrastructure (found in other cloud providers in one form or another) is the notion of &amp;ldquo;compartment&amp;rdquo;. Basically, resources are stored in &amp;ldquo;compartments&amp;rdquo; to organize resources.&lt;/p&gt;
&lt;p&gt;You can work in the &amp;ldquo;root&amp;rdquo; compartment, but it&amp;rsquo;s cleaner to create a specific one for the occasion.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/compartments.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Example OCID:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ocid1.compartment.oc1..aaaaaaaayrmiilkb5m2b7never345435gonna345give87978you12upu6ifoh6csihm4awsjq
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="preparing-the-oracle-cloud-environment"&gt;Preparing the Oracle Cloud Environment
&lt;/h2&gt;&lt;p&gt;Once we have that, we&amp;rsquo;ll use the CLI to create all the things we&amp;rsquo;ll need for our virtual machines to register on Omni&amp;rsquo;s SaaS.&lt;/p&gt;
&lt;p&gt;Creating a VCN (Virtual Cloud Network) and network configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;cidr_block&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10.0.0.0/16
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;subnet_block&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10.0.0.0/24
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;compartment_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your_ocid_compartment&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create the VCN and subnet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;vcn_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;oci network vcn create --cidr-block &lt;span class="nv"&gt;$cidr_block&lt;/span&gt; --display-name talos-example --compartment-id &lt;span class="nv"&gt;$compartment_id&lt;/span&gt; --query data.id --raw-output&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;rt_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;oci network subnet create --cidr-block &lt;span class="nv"&gt;$subnet_block&lt;/span&gt; --display-name kubernetes --compartment-id &lt;span class="nv"&gt;$compartment_id&lt;/span&gt; --vcn-id &lt;span class="nv"&gt;$vcn_id&lt;/span&gt; --query data.route-table-id --raw-output&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After the 2nd command, we retrieve not the OCID of the subnet (we don&amp;rsquo;t need it), but that of the &amp;ldquo;Route Table&amp;rdquo;, a subcomponent of the subnet, which allows defining the routing table of the subnet we just created.&lt;/p&gt;
&lt;p&gt;Configure a gateway (Internet Gateway):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ig_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;oci network internet-gateway create --compartment-id &lt;span class="nv"&gt;$compartment_id&lt;/span&gt; --is-enabled &lt;span class="nb"&gt;true&lt;/span&gt; --vcn-id &lt;span class="nv"&gt;$vcn_id&lt;/span&gt; --query data.id --raw-output&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add a routing rule (to our route table) to allow Internet access:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;oci network route-table update --rt-id &lt;span class="nv"&gt;$rt_id&lt;/span&gt; --route-rules &lt;span class="s2"&gt;&amp;#34;[{\&amp;#34;cidrBlock\&amp;#34;:\&amp;#34;0.0.0.0/0\&amp;#34;,\&amp;#34;networkEntityId\&amp;#34;:\&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$ig_id&lt;/span&gt;&lt;span class="s2"&gt;\&amp;#34;}]&amp;#34;&lt;/span&gt; --force
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Disable default firewall rules (YOLO):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;sl_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;oci network vcn list --compartment-id &lt;span class="nv"&gt;$compartment_id&lt;/span&gt; --query &lt;span class="s1"&gt;&amp;#39;data[0].&amp;#34;default-security-list-id&amp;#34;&amp;#39;&lt;/span&gt; --raw-output&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From there, we have the functional network part, ready to host our machines!&lt;/p&gt;
&lt;h2 id="but-its-not-over-yet--"&gt;But It&amp;rsquo;s Not Over Yet :-/
&lt;/h2&gt;&lt;p&gt;With Oracle Cloud Infrastructure, it&amp;rsquo;s possible to boot a list of predefined OSes, but in our case, Talos Linux is not on the list.&lt;/p&gt;
&lt;p&gt;Fortunately, Omni will generate a preconfigured virtual disk with our credentials, which will allow us to enroll Talos Linux servers to our Omni SaaS from the first boot. Classy 😎.&lt;/p&gt;
&lt;p&gt;So we connect to our Omni interface and download the appropriate Talos Linux image:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/omni_iso_generation.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Here, I chose version 1.9.1 (the very latest because we like danger), for amd64 architecture. I retrieve the image &lt;code&gt;oracle-amd64-omni-zwindler-v1.9.1.qcow2.xz&lt;/code&gt; which I decompress:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;xz --decompress ./oracle-amd64-omni-zwindler-v1.9.1.qcow2.xz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Reminder: OCI&amp;rsquo;s free tier consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 &lt;strong&gt;amd64&lt;/strong&gt; machines with 1 oCPU (= vCPU) and 1 GB of RAM each&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;flexible&lt;/em&gt; combination of &lt;strong&gt;arm64&lt;/strong&gt; instances having 1 x &lt;strong&gt;n&lt;/strong&gt; oCPU and 6 x &lt;strong&gt;n&lt;/strong&gt; GB, as long as the total doesn&amp;rsquo;t exceed 4 oCPU (and therefore 6x4 = 24 GB of RAM).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On OCI, there are several formats for importing disks. The simplest is to use OCI&amp;rsquo;s &amp;ldquo;homemade&amp;rdquo; format (the .oci, super original name), which consists of a metadata file and the QCOW2.&lt;/p&gt;
&lt;p&gt;Create the metadata file for import, with the &lt;strong&gt;VM.Standard.E2.1.Micro&lt;/strong&gt; shape since we have an amd64 image (otherwise it&amp;rsquo;s VM.Standard.A1.Flex):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; image_metadata.json &lt;span class="s"&gt;&amp;lt;&amp;lt; EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;version&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;externalLaunchOptions&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;firmware&amp;#34;: &amp;#34;UEFI_64&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;networkType&amp;#34;: &amp;#34;PARAVIRTUALIZED&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;bootVolumeType&amp;#34;: &amp;#34;PARAVIRTUALIZED&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;remoteDataVolumeType&amp;#34;: &amp;#34;PARAVIRTUALIZED&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;localDataVolumeType&amp;#34;: &amp;#34;PARAVIRTUALIZED&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;launchOptionsSource&amp;#34;: &amp;#34;PARAVIRTUALIZED&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;pvAttachmentVersion&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;pvEncryptionInTransitEnabled&amp;#34;: true,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;consistentVolumeNamingEnabled&amp;#34;: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;imageCapabilityData&amp;#34;: null,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;imageCapsFormatVersion&amp;#34;: null,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;operatingSystem&amp;#34;: &amp;#34;Talos&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;operatingSystemVersion&amp;#34;: &amp;#34;1.9.1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;additionalMetadata&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;shapeCompatibilities&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;internalShapeName&amp;#34;: &amp;#34;VM.Standard.E2.1.Micro&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;ocpuConstraints&amp;#34;: null,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;memoryConstraints&amp;#34;: null
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then create the image for import:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;qemu-img convert -f raw -O qcow2 oracle-amd64-omni-zwindler-v1.9.1.raw oracle-amd64-omni-zwindler-v1.9.1.qcow2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tar zcf oracle-amd64-omni-zwindler-v1.9.1.oci oracle-amd64-omni-zwindler-v1.9.1.qcow2 image_metadata.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="importing-the-image-to-oracle-cloud"&gt;Importing the Image to Oracle Cloud
&lt;/h2&gt;&lt;p&gt;We have the file ready to be uploaded&amp;hellip; but where do we upload it??&lt;/p&gt;
&lt;p&gt;Unfortunately, this step is done in 2 parts. First, you need to upload the .oci file to a bucket. It&amp;rsquo;s quite simple to do in the UI (we could also do it via CLI):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a bucket in the Storage section to upload the compressed image.&lt;/li&gt;
&lt;li&gt;Upload the image (oracle-amd64-omni-zwindler-v1.9.1.oci) to this bucket.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/bucket.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Second step, we transform the file into &amp;ldquo;Custom images&amp;rdquo; (in the &lt;strong&gt;Compute&lt;/strong&gt; section):&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/custom-images.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;This step is oddly quite long, the image which is only 100 MB took 10 minutes each time I tried so far.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/custom-images-2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="creating-the-vm"&gt;Creating the VM
&lt;/h2&gt;&lt;p&gt;Once the image is imported, we can now use our Omni-customized image to boot our free tier machines.&lt;/p&gt;
&lt;p&gt;I also did this through the OCI interface, but again, we could do it via CLI.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/vm1.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/vm2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;A few seconds after boot, it appears in Omni&amp;rsquo;s UI and can be added to a cluster.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2025/01/omni-oracle.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Have fun!!&lt;/p&gt;
&lt;h2 id="addendum-is-it-really-free"&gt;Addendum: Is It Really Free?
&lt;/h2&gt;&lt;p&gt;Yes&amp;hellip;-ish.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In theory&lt;/strong&gt;, the machines are free (forever free as they say). But beware, lots of little things can be paid.&lt;/p&gt;
&lt;p&gt;For example, the bucket where we uploaded the QCOW2/.oci is most likely paid. Same for the custom image, which is billed as 1 GB of storage (according to the UI, I don&amp;rsquo;t have the bill yet LOL).&lt;/p&gt;
&lt;p&gt;If you put the VMs behind a load balancer (there&amp;rsquo;s no reason you&amp;rsquo;d do that here), be careful, only the &amp;ldquo;non-flexible&amp;rdquo; LB capped at 10 Mbps is free (and only one).&lt;/p&gt;
&lt;p&gt;And if like me, you already have 4 x 50 GB disks, the OS storage is paid (€1.85 / month).&lt;/p&gt;
&lt;p&gt;In short, as you&amp;rsquo;ve understood, it&amp;rsquo;s like often in the cloud, nothing is really free and you have to read all the fine print.&lt;/p&gt;</description></item></channel></rss>