<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Libvirt &#8211; Johnny Morano&#039;s Tech Articles</title>
	<atom:link href="https://jmorano.moretrix.com/tag/libvirt/feed/" rel="self" type="application/rss+xml" />
	<link>https://jmorano.moretrix.com</link>
	<description>Ramblings of an old-fashioned space cowboy</description>
	<lastBuildDate>Thu, 18 Aug 2022 11:04:06 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>

<image>
	<url>https://jmorano.moretrix.com/wp-content/uploads/2022/04/cropped-jmorano_emblem-32x32.png</url>
	<title>Libvirt &#8211; Johnny Morano&#039;s Tech Articles</title>
	<link>https://jmorano.moretrix.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Jenkins to manage a libvirt infrastructure with Terraform</title>
		<link>https://jmorano.moretrix.com/2022/08/jenkins-to-manage-azure-infrastructure-with-terraform/</link>
					<comments>https://jmorano.moretrix.com/2022/08/jenkins-to-manage-azure-infrastructure-with-terraform/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Thu, 18 Aug 2022 10:53:59 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Terraform]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[Libvirt]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1546</guid>

					<description><![CDATA[Jenkins is an open source automation server which provides hundreds of plugins to build, deploy and automate projects.&#8230;]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.jenkins.io/" data-type="URL" data-id="https://www.jenkins.io/" target="_blank" rel="noreferrer noopener">Jenkins</a> is an open source automation server which provides hundreds of plugins to build, deploy and automate projects.</p>



<p><a href="https://www.terraform.io/" data-type="URL" data-id="https://www.terraform.io/" target="_blank" rel="noreferrer noopener">Terraform</a> codifies cloud, virtualization and many other APIs into declarative configuration files, allowing to define the infrastructure as code.</p>



<p>The combination of both is an excellent platform to manage resources in the <a rel="noreferrer noopener" href="https://azure.microsoft.com/" data-type="URL" data-id="https://azure.microsoft.com/" target="_blank">Microsoft Azure</a> cloud in an automated or semi-automated way.</p>



<h2 class="wp-block-heading">Installation</h2>



<p>Let&#8217;s start by installing Jenkins and Terraform. The official documentation at <a rel="noreferrer noopener" href="https://www.jenkins.io/doc/book/installing/linux/#debianubuntu" target="_blank">https://www.jenkins.io/doc/book/installing/linux/#debianubuntu</a> describes how to install the Jenkins binaries on a Debian/ Ubuntu system, so we&#8217;ll not go further into details on that.</p>



<p>Once the required packages are installed as described above, go to <a rel="noreferrer noopener" href="http://localhost:8080/" target="_blank">http://localhost:8080/</a> to finalize the Jenkins setup. After installing the essential plugins required to run Jenkins, you should be directed to the following screen:</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="957" height="887" src="https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08.png" alt="" class="wp-image-1552" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08.png 957w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08-300x278.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08-768x712.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08-380x352.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08-550x510.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-30-11-52-08-800x741.png 800w" sizes="(max-width: 957px) 100vw, 957px" /><figcaption>Home screen</figcaption></figure>



<p>Next, install the required plugins.</p>



<p>Go the main dashboard and then click on &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Manage Jenkins</mark>&#8221; -&gt; &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Manage Plugins</mark>&#8220;. In the &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Available</mark>&#8221; tab, search for:</p>



<ul class="wp-block-list"><li>Azure Credentials</li><li>Terraform</li><li>AnsiColor</li><li>Git plugin</li></ul>



<p>Check the checkbox of the required plugins and install them. Jenkins will restart at the end of the installation.</p>



<h2 class="wp-block-heading">Pipeline Setup</h2>



<p>After all plugins have been installed, the next step will be to add a &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">New Item</mark>&#8221; (see the menu on the right side).</p>



<figure class="wp-block-image size-full"><img decoding="async" width="943" height="918" src="https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45.png" alt="" class="wp-image-1555" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45.png 943w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45-300x292.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45-768x748.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45-380x370.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45-550x535.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/07/Screenshot-from-2022-07-31-13-01-45-800x779.png 800w" sizes="(max-width: 943px) 100vw, 943px" /><figcaption>Add a new item</figcaption></figure>



<p>Start by entering a valid name for the job and choose the type &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Pipeline</mark>&#8220;. Hit &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">OK</mark>&#8221; to continue to the next screen.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="613" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-1024x613.png" alt="" class="wp-image-1558" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-1024x613.png 1024w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-300x179.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-768x459.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-380x227.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-550x329.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55-800x479.png 800w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-00-55.png 1110w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Enter a description for the pipeline and scroll down to the &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Pipeline</mark>&#8221; section and choose in the &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Definition</mark>&#8221; section the option &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Pipeline script from SCM</mark>&#8220;. Choose the SCM you want to use and fill in the repository URL of the code repository containing the <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Jenkinsfile pipeline file</mark>.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="790" height="775" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-01-37.png" alt="" class="wp-image-1560" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-01-37.png 790w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-01-37-300x294.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-01-37-768x753.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-01-37-380x373.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-01-37-550x540.png 550w" sizes="(max-width: 790px) 100vw, 790px" /></figure>



<p>A bit further down it is possible to configure the SCM branch name to work on and the actual filename of the Jenkinsfile, which in most cases will be called just &#8220;<code>Jenkinsfile</code>&#8220;.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="777" height="732" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-02-13.png" alt="" class="wp-image-1559" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-02-13.png 777w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-02-13-300x283.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-02-13-768x724.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-02-13-380x358.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-02-13-550x518.png 550w" sizes="(max-width: 777px) 100vw, 777px" /></figure>



<p>Once all options have been set, press &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Save</mark>&#8221; to save the configuration.</p>



<p>Depending on whether the pipeline was created with or without parameters, either click on &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Build</mark>&#8221; or &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Build with Parameters</mark>&#8221; to start the pipeline.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="557" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-1024x557.png" alt="" class="wp-image-1563" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-1024x557.png 1024w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-300x163.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-768x418.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-380x207.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-550x299.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-800x436.png 800w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837-1160x631.png 1160w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect837.png 1453w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Each build will appear in the &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Build History</mark>&#8221; and contains links to for instance the &#8220;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">Console Output</mark>&#8220;, which contains the text output of all stages, steps and plugins executed by the pipeline.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="366" height="268" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-33-57.png" alt="" class="wp-image-1565" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-33-57.png 366w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-33-57-300x220.png 300w" sizes="(max-width: 366px) 100vw, 366px" /></figure>



<p>Each build/ run contains information such as:</p>



<ul class="wp-block-list"><li>Who started the pipeline</li><li>The current SCM repository versions (git commit hash)</li><li>An SCM log of the changes since the last build (git commit messages)</li><li>Who approved the pipeline (if applicable)</li><li>The console output of the plugins/ commands executed</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="588" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-1024x588.png" alt="" class="wp-image-1567" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-1024x588.png 1024w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-300x172.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-768x441.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-1536x882.png 1536w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-2048x1175.png 2048w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-380x218.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-550x316.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-800x459.png 800w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838-1160x666.png 1160w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/rect838.png 2084w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The pipeline dashboard page, contains a stage view of pipeline runs, divided on the stages and their execution status.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="514" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-1024x514.png" alt="" class="wp-image-1561" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-1024x514.png 1024w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-300x150.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-768x385.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-380x191.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-550x276.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-800x401.png 800w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56-1160x582.png 1160w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-12-56.png 1212w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Pipeline definitions</h2>



<p>Finally, let&#8217;s have a look on how this pipeline file is actually built.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="880" height="606" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39.png" alt="" class="wp-image-1568" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39.png 880w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39-300x207.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39-768x529.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39-380x262.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39-550x379.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-49-39-800x551.png 800w" sizes="(max-width: 880px) 100vw, 880px" /><figcaption>Jenkinsfile</figcaption></figure>



<p>The above Jenkinsfile is divided in 4 sections:</p>



<ul class="wp-block-list"><li>the agent section</li><li>the tools section</li><li>the environment section</li><li>the stages section</li></ul>



<p>The first 3 sections basically set some build options like:</p>



<ul class="wp-block-list"><li>on which agent to run the pipeline (in this case, on &#8220;<code>any</code>&#8221; available node)</li><li>which tools are required to be present on the build node</li><li>which environment (shell) parameters should be set</li></ul>



<p>The <code>stages</code> section contains the different stages and steps the pipeline is supposed to run.</p>



<p>Each <code>stage</code>, contains several steps separated per line:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="905" height="387" src="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24.png" alt="" class="wp-image-1569" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24.png 905w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24-300x128.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24-768x328.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24-380x162.png 380w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24-550x235.png 550w, https://jmorano.moretrix.com/wp-content/uploads/2022/08/Screenshot-from-2022-08-17-09-56-24-800x342.png 800w" sizes="(max-width: 905px) 100vw, 905px" /></figure>



<p>In the above example, all steps are defined between the &#8216;steps { }&#8217; block. Steps can be wrapped (enclosed between curly brackets), like in the above example <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-red-color">line 15</mark> calls the<code> ansiColor()</code> plugin to display a colorized output of the steps contained by it.</p>



<p>Next, the plugin <code>dir()</code> wraps the rest of the steps, which means that all enclosed steps will be executed in a specific directory.</p>



<p>In that specific directory, 3 plugins will be executed:</p>



<ul class="wp-block-list"><li><code>git</code>: line 17 in the above example will <code>git clone</code> the <code>main</code> branch of the supplied Github URL</li><li><code>echo</code>: line 19 will output some text</li><li><code>sh</code>: line 20 &#8211; 23 defines the shell commands to be executed</li></ul>



<p>A complete example can be found at: <a href="https://github.com/insani4c/jenkins-terraform-datacenter-example/blob/main/JenkinsFile" target="_blank" rel="noreferrer noopener">https://github.com/insani4c/jenkins-terraform-datacenter-example/blob/main/JenkinsFile</a> </p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/08/jenkins-to-manage-azure-infrastructure-with-terraform/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Libvirt guest startup issue with AppArmor</title>
		<link>https://jmorano.moretrix.com/2022/04/libvirt-guest-startup-issue-with-apparmor/</link>
					<comments>https://jmorano.moretrix.com/2022/04/libvirt-guest-startup-issue-with-apparmor/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Sun, 10 Apr 2022 09:37:48 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[AppArmor]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Libvirt]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1487</guid>

					<description><![CDATA[With AppArmor enabled on Debian/ Ubuntu systems, starting up virtual machines with libvirt can cause startup failures if&#8230;]]></description>
										<content:encoded><![CDATA[
<p>With <a href="https://apparmor.net/" data-type="URL" data-id="https://apparmor.net/" target="_blank" rel="noreferrer noopener">AppArmor</a> enabled on Debian/ Ubuntu systems, starting up virtual machines with <a href="https://libvirt.org/" data-type="URL" data-id="https://libvirt.org/" target="_blank" rel="noreferrer noopener">libvirt</a> can cause startup failures if not AppArmor is not properly configured.</p>



<p>AppArmor will write messages to the kernel log (visible with either the <code>dmesg</code> command or in <code>kernel.log</code> if available) regarding its actions.</p>



<p>If your libvirt guests are not starting up or failing, have a look at <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">dmesg</mark></code>. Example:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="82" src="https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-1024x82.png" alt="" class="wp-image-1488" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-1024x82.png 1024w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-300x24.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-768x62.png 768w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15-850x68.png 850w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-10-11-09-15.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>In the above example AppArmor has <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">denied</mark> (<code>apparmor="DENIED"</code>) read access (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">requested_mask=r</mark></code>) to the file <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">/data/vms/cluster_storage/base-os-ubuntu-focal.qcow2</mark></code>. This blocks of course the startup guest machines we have previously created in the article: <a href="https://jmorano.moretrix.com/2022/03/terraform-and-libvirtd-nodes/" data-type="post" data-id="1302">Terraform and libvirtd nodes</a>.</p>



<p>To fix the issue, edit the file: <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">/etc/apparmor.d/libvirt/TEMPLATE.qemu</mark></code></p>



<p>By default it has the following content:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#
# This profile is for the domain whose UUID matches this file.
#

#include &lt;tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include &lt;abstractions/libvirt-qemu>
}
</pre>



<p>In order to allow <code>libvirt</code> to use the guest image files, change the content to (or add a similar line if your file path is different):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#
# This profile is for the domain whose UUID matches this file.
#

#include &lt;tunables/global>

profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
  #include &lt;abstractions/libvirt-qemu>
  /data/vms/cluster_storage/**.qcow2 rwk,
}
</pre>



<p>The added line (<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">line 9</mark>) will allow read (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">r</mark></code>), write (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">w</mark></code>) and lock (<code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">k</mark></code>) access to all <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">qcow2</mark></code> files in the directory <code><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">/data/vms/cluster_storage</mark></code>.</p>



<p>Once added, all libvirt guests will start up again without any (AppArmor) issues.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/04/libvirt-guest-startup-issue-with-apparmor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Terraform and libvirt nodes</title>
		<link>https://jmorano.moretrix.com/2022/03/terraform-and-libvirtd-nodes/</link>
					<comments>https://jmorano.moretrix.com/2022/03/terraform-and-libvirtd-nodes/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Wed, 30 Mar 2022 09:45:11 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Terraform]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Hashicorp]]></category>
		<category><![CDATA[Hetzner]]></category>
		<category><![CDATA[KVM]]></category>
		<category><![CDATA[Libvirt]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Qemu]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1302</guid>

					<description><![CDATA[Libvirt (libvirtd) nodes (based on KVM and Qemu) are a great and cheap (read: free) alternative of deploying&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Libvirt (<a href="https://libvirt.org/manpages/libvirtd.html" data-type="URL" data-id="https://libvirt.org/manpages/libvirtd.html" target="_blank" rel="noreferrer noopener">libvirtd</a>) nodes (based on KVM and Qemu) are a great and cheap (read: free) alternative of deploying virtual nodes in a cloud. Required is a server which will act as a hypervisor, in our article we chose to use a <a href="https://www.hetzner.com/" data-type="URL" data-id="https://www.hetzner.com/" target="_blank" rel="noreferrer noopener">Hetzner</a> server installed with <a href="https://ubuntu.com/" data-type="URL" data-id="https://ubuntu.com/" target="_blank" rel="noreferrer noopener">Ubuntu Linux </a>20.4-lts.</p>



<p>After the default installation of Ubuntu 20.4-lts, the following packages are required to get started as a hypervisor:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apt install qemu-kvm libvirt-daemon bridge-utils virtinst libvirt-daemon-system virt-top libguestfs-tools libosinfo-bin qemu-system virt-manager qemu pm-utils</pre>



<p>Once these are installed, the <code>vnet_hosts </code>module needs to be pre-loaded in <code>/etc/modules</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">echo vhost_net | tee -a /etc/modules
modprobe vhost_net</pre>



<p>The hypervisor is now ready to start creating and deploying virtual machines. </p>



<p>In this article, <a rel="noreferrer noopener" href="https://www.terraform.io/" data-type="URL" data-id="https://www.terraform.io/" target="_blank">Terraform</a> will be used to manage the virtual machines in libvirtd. All example code snippets are available on Github, under <a href="https://github.com/insani4c/terraform-libvirt" target="_blank" rel="noreferrer noopener">https://github.com/insani4c/terraform-libvirt</a></p>



<p>Terraform has an excellent provider (<a href="https://registry.terraform.io/providers/dmacvicar/libvirt/latest" data-type="URL" data-id="https://registry.terraform.io/providers/dmacvicar/libvirt/latest" target="_blank" rel="noreferrer noopener">dmacvicar/libvirtd</a>) to manage the libvirtd nodes, which needs to be loaded and initialized:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">terraform {
  required_providers {
    libvirt = {
      source = "dmacvicar/libvirt"
    }
  }
}

provider "libvirt" {
  uri = "qemu+ssh://root@192.168.1.1/system"
}</pre>



<p>In the above code snippet, Terraform will ensure the libvirt provider is loaded and it is configured to connect to the host with IP address <code>192.168.1.1</code> as the root user (this requires that a SSH public key is installed on the remote server, of the user who will be executing Terraform).</p>



<p>Next, the network will defined, where the virtual nodes will be deployed in.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">resource "libvirt_network" "my_network" {
  name = "my_net"

  mode = "nat"

  addresses = ["10.1.2.0/24"]
  domain    = var.dns_domain

  autostart = true

  dhcp {
    enabled = false
  }

  dns {
    enabled = true

    local_only = false
    forwarders { address = "127.0.0.53" }

    hosts  {
        hostname = "host01"
        ip = "10.1.2.10"
      }
    hosts {
        hostname = "host02"
        ip = "10.1.2.20"
      }
  }  
}</pre>



<p>The above code will ensure that a network of type <code>NAT</code> (to allow internal IPs, reachable from the hypervisor only) with network mask <code>10.1.2.0/24</code>, will be created. It will ensure that <code>DHCP</code> is disabled and it will enable a <code>DNS</code> setup (the package <code>dnsmasq</code> must be installed) with two predefined hosts, <code>host01</code> and <code>host02</code>.</p>



<p>Up next is the definition of the storage pools and volumes required for the virtual machines.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">resource "libvirt_pool" "default" {
  name = "default"
  type = "dir"
  path = "/data/vms/cluster_storage"
}

resource "libvirt_volume" "local_install_image" {
  name   = var.local_install_image
  pool   = libvirt_pool.default.name
  source = var.os_img_url
  format = "qcow2"
}</pre>



<p>The above defines the <code>libvirt_pool</code>, which basically configures the path on-disk for storing all sorts of volumes. Next it defines a volume called &#8220;<code>local_install_image</code>&#8220;, which will be used to set up the virtual machine as the volume will contain the &#8220;cloud image&#8221; for the installation. This volume requires two variables:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">variable "os_img_url" {
  description = "URL to the OS image"
  default     = "https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img"
}

variable "local_install_image" {
    description = "The name of the local install image"
    default     = "base-os-ubuntu-focal.qcow2"
}</pre>


]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/03/terraform-and-libvirtd-nodes/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
