<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Introduction on Puppeteers Oy</title>
		<link>https://www.puppeteers.net/categories/introduction/</link>
		<description>Recent content in Introduction on Puppeteers Oy</description>
		<generator>Hugo</generator>
		<language>en-US</language>
		
		
		
		
			<lastBuildDate>Wed, 12 Jun 2024 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://www.puppeteers.net/categories/introduction/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Installing OpenBSD 7.5 with virt-install on Linux</title>
				<link>https://www.puppeteers.net/blog/installing-openbsd-7-5-with-virt-install-on-linux/</link>
				<pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/installing-openbsd-7-5-with-virt-install-on-linux/</guid>
				<description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.openbsd.org/&#34;&gt;OpenBSD&lt;/a&gt; 7.5 is a UNIX-like operating system. The project&amp;rsquo;s &amp;ldquo;efforts emphasize portability, standardization, correctness, proactive security and integrated cryptography&amp;rdquo;. Compared to modern Linux distributions OpenBSD is &lt;em&gt;very&lt;/em&gt; compact, but comes with the usual packages and ports tree you would expect from any *BSD operating system. This article shows the process of installing OpenBSD 7.5 with virt-install, making it a virtualization guest on Linux.&lt;/p&gt;&#xA;&lt;h2 id=&#34;downloading-the-iso-installer&#34;&gt;Downloading the ISO installer&lt;/h2&gt;&#xA;&lt;p&gt;First you need to download the OpenBSD 7.5 ISO installer on your Linux system. On most systems the amd64 &lt;a href=&#34;https://cdn.openbsd.org/pub/OpenBSD/7.5/amd64/install75.iso&#34;&gt;install75.iso&lt;/a&gt; is the correct choice. Check the OpenBSD &lt;a href=&#34;https://www.openbsd.org/faq/faq4.html#Download&#34;&gt;download page&lt;/a&gt; for other architectures.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Red Hat subscriptions quick start</title>
				<link>https://www.puppeteers.net/blog/red-hat-subscriptions-quick-start/</link>
				<pubDate>Mon, 15 Jan 2024 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/red-hat-subscriptions-quick-start/</guid>
				<description>&lt;p&gt;What follows is an minimalistic, bare-bones guide to get you started with Red Hat subscriptions quickly. No spoon-feeding, no introductions, just get your first RHEL* system into a blessed state quickly, while your attention can still keep up. &lt;/p&gt;&#xA;&lt;p&gt;We assume you are starting from scratch and generally have no glue. We also assume that your boss has punished you with this task, not your mom, and therefore you represent a company, not a Sapiens specimen that looks like you. If this is not the case, then it isn&amp;rsquo;t.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Options for building self-service infrastructure with Ansible and Terraform</title>
				<link>https://www.puppeteers.net/blog/options-for-building-self-service-infrastructure-with-ansible-and-terraform/</link>
				<pubDate>Wed, 22 Nov 2023 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/options-for-building-self-service-infrastructure-with-ansible-and-terraform/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/pexels-esranur-kalay-12259336-1-768x1024.jpg&#34; alt=&#34;It is possible to build self-service infrastructure with Ansible and Terraform&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;Being able to build IT infrastructure always having to involve an IT, operations or platform team seems be a big priority for many organizations. This is understandable because processes typically slow down to a crawl when they have to pass organizational boundaries. Also, teams responsible for infrastructure would not want to spend time on routine requests if possible. Provisioning infrastructure is no exception here. It is possible to create a custom solution to enable self-service infrastructure with Ansible and Terraform, but that takes a fair amount of effort. In this article we focus on open source and commercial open source offerings that make enabling self-service infrastructure provisioning easier.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Linux Azure AD authentication options</title>
				<link>https://www.puppeteers.net/blog/linux-azure-ad-authentication-options/</link>
				<pubDate>Wed, 26 Apr 2023 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/linux-azure-ad-authentication-options/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/bash-gb216ea79b_640.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;There are a myriad of ways to login to Linux systems using Azure AD credentials. &lt;a href=&#34;https://pixabay.com/vectors/bash-command-line-linux-shell-148836/&#34;&gt;Photo credit&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;There are several ways to do Linux Azure AD authentication. Note that Azure AD was renamed &amp;ldquo;Microsoft Entra ID&amp;rdquo; recently, but in this article we&amp;rsquo;ll use its old name, at least for now. In other words you can log in to your Linux hosts &lt;a href=&#34;https://azure.microsoft.com/en-ca/products/active-directory/&#34;&gt;Azure Active Directory&lt;/a&gt; (&amp;ldquo;Azure AD&amp;rdquo;) credentials in various ways. &lt;a href=&#34;https://azure.microsoft.com&#34;&gt;Azure&lt;/a&gt;, Microsoft&amp;rsquo;s public Cloud, builds on top of Azure AD. In fact, your Azure users, groups, roles and role assignments are stored in Azure AD.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Openshift versions: all you hopefully need to know</title>
				<link>https://www.puppeteers.net/blog/openshift-versions-all-you-hopefully-need-to-know/</link>
				<pubDate>Wed, 05 Apr 2023 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/openshift-versions-all-you-hopefully-need-to-know/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/pexels-cottonbro-studio-7569424.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;Red Hat Openshift is essentially an opinionated Kubernetes distribution that comes with a large number of features such as CI/CD and container registry built-in; for a full list of differences look at the &lt;a href=&#34;https://www.redhat.com/en/technologies/cloud-computing/openshift/red-hat-openshift-kubernetes&#34;&gt;Red Hat OpenShift vs. Kubernetes&lt;/a&gt;. Openshift comes in a number of versions, some commercial and some open source. The naming history of Openshift is &lt;em&gt;particularly&lt;/em&gt; confusing. That&amp;rsquo;s why I wrote this blog post where I attempt to list &lt;em&gt;most&lt;/em&gt; Openshift versions and variants and outline their main differences.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Automation use-cases in the Cloud: Red Hat Open Tour 2022 Tallinn</title>
				<link>https://www.puppeteers.net/blog/automation-use-cases-in-the-cloud-red-hat-open-tour-2022-tallinn/</link>
				<pubDate>Fri, 14 Oct 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/automation-use-cases-in-the-cloud-red-hat-open-tour-2022-tallinn/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/Red-Hat-Open-Tour-2022-Tallinn-badge-part.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;automation-use-cases-in-the-cloud&#34;&gt;Automation use-cases in the Cloud&lt;/h2&gt;&#xA;&lt;p&gt;Johan Wennerberg, a Solution Architect for Red Hat Nordics in Stockholm gave presentation in &lt;a href=&#34;https://www.redhat.com/en/events/open-tour-tallinn-2022&#34;&gt;Red Hat Open Tour 2022 Tallinn&lt;/a&gt;. In his presentation titled &amp;ldquo;Gain robust repeatability as selfservice, by automating your automation&amp;rdquo; he listed several automation use-cases in the Cloud. Each of these automation use-cases is made possible by automation stacks. The automation stacks are technology stacks that produce business value through automation. In practice you need to build your automation stacks on top of &lt;a href=&#34;https://www.puppeteers.net/blog/understanding-azure-backup-for-linux-vms/&#34;&gt;infrastructure as code&lt;/a&gt;.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Ansible variable validation with ansible.utils.assert</title>
				<link>https://www.puppeteers.net/blog/ansible-quality-assurance-part-1-ansible-variable-validation-with-assert/</link>
				<pubDate>Thu, 06 Oct 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/ansible-quality-assurance-part-1-ansible-variable-validation-with-assert/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/square-peg-in-round-hole.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview-of-ansible-quality-assurance&#34;&gt;Overview of Ansible quality assurance&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.ansible.com/overview/how-ansible-works&#34;&gt;Ansible&lt;/a&gt; is an IT automation engine which you can use for configuration management, orchestration and device management, among other things. While you can get started fast with Ansible, ensuring high-quality, bug-free code can be challenging. Moreover, there&amp;rsquo;s not that much official, high-quality or coherent documentation available on Ansible quality assurance best practices. While low hanging fruit like Ansible variable validation &lt;em&gt;are&lt;/em&gt; available, they are not emphasized in official documentation.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Azure function monitoring with Azure Monitor and Application Insights</title>
				<link>https://www.puppeteers.net/blog/azure-function-monitoring-wiht-azure-monitor-and-application-insights/</link>
				<pubDate>Mon, 26 Sep 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/azure-function-monitoring-wiht-azure-monitor-and-application-insights/</guid>
				<description>&lt;p&gt;Microsoft Azure provides a metrics and monitoring framework called &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/azure-monitor/&#34;&gt;Azure Monitor&lt;/a&gt;. With it you can monitor your Cloud infrastructure and services running there. You can view graphs of the metrics, alert on threshold and all that usual stuff, just like in &lt;a href=&#34;https://aws.amazon.com/cloudwatch&#34;&gt;AWS Cloudwatch&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Some Cloud resources like &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/azure-functions/functions-overview&#34;&gt;Azure Functions&lt;/a&gt; expose &amp;ldquo;a limited number of useful metrics&amp;rdquo; in Azure Monitor. This is a polite way of saying that the metrics are &amp;ldquo;completely useless&amp;rdquo; for most intents and purposes. For example, an Azure Function that gets triggered a few times a week on an irregular schedule by real people you don&amp;rsquo;t really have any useful metrics in Azure Monitor which you could alert on if something is off.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Hiera lookups in rspec-puppet</title>
				<link>https://www.puppeteers.net/blog/hiera-lookups-in-rspec-puppet/</link>
				<pubDate>Wed, 09 Feb 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/hiera-lookups-in-rspec-puppet/</guid>
				<description>&lt;p&gt;While &lt;a href=&#34;https://rspec-puppet.com/&#34;&gt;rspec-puppet documentation&lt;/a&gt; is quite decent, it does not really explain how to test classes that get their parameters via Hiera lookups, such as profiles in the &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-workflow-part-4-roles-and-profiles/&#34;&gt;roles and profiles pattern&lt;/a&gt;. Several parameters related to Hiera are listed in the &lt;a href=&#34;https://rspec-puppet.com/documentation/configuration/&#34;&gt;rspec-puppet configuration reference&lt;/a&gt;, but that&amp;rsquo;s all. The other documentation you find on the Internet is generally outdated and not applicable for modules converted with &lt;a href=&#34;https://puppet.com/try-puppet/puppet-development-kit/&#34;&gt;PDK&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In this article we show how to test an &amp;ldquo;ipa_client&amp;rdquo; class that uses lookups to get its parameter from Hiera. It used to be a profile that was later separated from the &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-puppet-workflow-part-1-the-control-repository/&#34;&gt;control-repo&lt;/a&gt; into a separate module, which means that rspec-puppet does not have access to the control-repo&amp;rsquo;s Hiera data.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Windows domain in Azure</title>
				<link>https://www.puppeteers.net/blog/windows-domain-in-azure/</link>
				<pubDate>Tue, 11 Jan 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/windows-domain-in-azure/</guid>
				<description>&lt;p&gt;I wrote this article to better understand all the pieces called &amp;ldquo;AD&amp;rdquo; or &amp;ldquo;Active Directory&amp;rdquo; in Microsoft Azure fit together. The pieces are as follows:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Active Directory (AD)&lt;/strong&gt;: The is the classic on-premise Active Directory with LDAP, Kerberos, group policies and all that. Traditionally Windows machines in larger environments have been domain-joined to on-premise AD.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.microsoft.com/en-us/windows-server/identity/active-directory-federation-services&#34;&gt;Active Directory Federation services (AD FS)&lt;/a&gt;&lt;/strong&gt;: adds support for modern web-SSO protocols (SAML, OAuth 2.0 and OIDC) to on-premise Active Directory.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Serverless Puppet with control repo, Hiera, roles and profiles and Puppet Bolt</title>
				<link>https://www.puppeteers.net/blog/serverless-puppet-with-control-repo-hiera-roles-and-profiles-and-puppet-bolt/</link>
				<pubDate>Tue, 28 Dec 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/serverless-puppet-with-control-repo-hiera-roles-and-profiles-and-puppet-bolt/</guid>
				<description>&lt;p&gt;The traditional way of managing systems with &lt;a href=&#34;https://www.puppeteers.net/learn/what-is-puppet-and-how-does-it-work/&#34;&gt;Puppet&lt;/a&gt; is to install Puppet agent on the nodes being managed and point those agents to a Puppet server (more details &lt;a href=&#34;https://www.puppeteers.net/learn/what-is-puppet-and-how-does-it-work/&#34;&gt;here&lt;/a&gt;). This approach works well for environments with tens or hundreds of nodes, but is an overkill for small environments with just a handful of nodes. Fortunately nowadays &lt;a href=&#34;https://puppet.com/docs/bolt/latest/bolt.html&#34;&gt;Puppet Bolt&lt;/a&gt; enables you to &lt;a href=&#34;https://www.puppeteers.net/learn/understanding-infrastructure-as-code-iac/&#34;&gt;push&lt;/a&gt; configurations to the managed nodes via SSH and WinRM. When using Bolt the &lt;a href=&#34;https://www.puppeteers.net/learn/what-is-puppet-and-how-does-it-work/&#34;&gt;catalog&lt;/a&gt; (desired state) is created on the computer running Puppet Bolt using facts from managed nodes and then sent to the managed nodes to be applied.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Short introduction to Packer and Vagrant</title>
				<link>https://www.puppeteers.net/blog/short-introduction-to-packer-and-vagrant/</link>
				<pubDate>Sun, 31 Oct 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/short-introduction-to-packer-and-vagrant/</guid>
				<description>&lt;p&gt;This article is a short introduction to Packer and Vagrant - tools that we often recommend to our customers but which may be a bit hard to understand if you have no previous expose to them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;packer&#34;&gt;Packer&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.packer.io/&#34;&gt;Packer&lt;/a&gt; is used to “create identical machine images for multiple platforms from a single source configuration”. Packer works in a very simple fashion:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;It reads its configuration file&lt;/li&gt;&#xA;&lt;li&gt;It launches a virtual machine based on the “base box” you’ve defined. The base box would be a “vanilla” Linux distribution such as Ubuntu 20.04.&lt;/li&gt;&#xA;&lt;li&gt;It runs the provisioning scripts you’ve written on the base box (via SSH)&lt;/li&gt;&#xA;&lt;li&gt;It removes deployment-specific things (e.g. SSH host keys)&lt;/li&gt;&#xA;&lt;li&gt;It shuts down the VM&lt;/li&gt;&#xA;&lt;li&gt;It creates a VM image out of base box + your changes&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;After this you can distribute the base box to people and they will have an identical system at their disposal. If you need to modify the image you can just change the provisioning scripts and/or the base image and rebuild. The configuration file can and should be stored in version control repository.&lt;/p&gt;</description>
			</item>
			<item>
				<title>OpenVPN server options in Azure</title>
				<link>https://www.puppeteers.net/blog/openvpn-server-options-in-azure/</link>
				<pubDate>Thu, 21 Oct 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/openvpn-server-options-in-azure/</guid>
				<description>&lt;p&gt;OpenVPN is among the best VPN solutions, especially when you need a cross-platform (Windows, Mac, Linux, Android, iOS) solution that just works. It is best suited for point to site (P2S) or &amp;ldquo;road warrior&amp;rdquo; setups where users access internal resources using a VPN client when on the road.&lt;/p&gt;&#xA;&lt;p&gt;When setting up OpenVPN server in Azure you have several options at your disposal:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Set up your own open source &lt;a href=&#34;https://github.com/OpenVPN/openvpn&#34;&gt;OpenVPN 2&lt;/a&gt; server&lt;/p&gt;</description>
			</item>
			<item>
				<title>What Vagrant plugins actually are?</title>
				<link>https://www.puppeteers.net/blog/what-vagrant-plugins-actually-are/</link>
				<pubDate>Tue, 01 Jun 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/what-vagrant-plugins-actually-are/</guid>
				<description>&lt;p&gt;This was a revelation that came to me &lt;a href=&#34;https://www.puppeteers.net/blog/making-vagrant-work-on-fedora-34/&#34;&gt;when fixing Vagrant on my Fedora 34 laptop&lt;/a&gt;: Vagrant plugins seem to be just Ruby gems installed into an isolated runtime environment, with &amp;ldquo;vagrant plugin&amp;rdquo; ensuring that the gems are installed in the correct place.&lt;/p&gt;&#xA;&lt;p&gt;The same gems that you can install with &amp;ldquo;vagrant plugiin install&amp;rdquo; can be found using vanilla gem command:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ vagrant plugin list&#xA;rexml (3.2.5, global)&#xA;vagrant-hostmanager (1.8.9, global)&#xA;vagrant-vbguest (0.29.0, global)&#xA;winrm (2.3.6, global)&#xA;winrm-elevated (1.2.3, global)&#xA;winrm-fs (1.3.5, global)&#xA;&#xA;$ gem info --remote rexml&#xA;&#xA;*** REMOTE GEMS ***&#xA;&#xA;rexml (3.2.5)&#xA;    Author: Kouhei Sutou&#xA;    Homepage: https://github.com/ruby/rexml&#xA;&#xA;    An XML toolkit for Ruby&#xA;&#xA;$ gem info --remote vagrant-vbguest&#xA;&#xA;*** REMOTE GEMS ***&#xA;&#xA;vagrant-vbguest (0.29.0)&#xA;    Author: Robert Schulze&#xA;    Homepage: https://github.com/dotless-de/vagrant-vbguest&#xA;&#xA;    A Vagrant plugin to install the VirtualBoxAdditions into the guest&#xA;    VM&#xA;&#xA;$ gem list|grep vagrant&#xA;&amp;lt;no output&amp;gt;&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;On the remote side you can find all the familiar Vagrant plugins as gems, but vanilla gem won&amp;rsquo;t find them installed locally, because they&amp;rsquo;re in a different path.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Managing self-hosted GitLab with Terraform</title>
				<link>https://www.puppeteers.net/blog/managing-self-hosted-gitlab-with-terraform/</link>
				<pubDate>Sun, 16 May 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/managing-self-hosted-gitlab-with-terraform/</guid>
				<description>&lt;p&gt;GitLab has an &lt;a href=&#34;https://docs.gitlab.com/ee/api/&#34;&gt;extensive API&lt;/a&gt; which allows managing its internal configuration such as users, groups and projects. The official &lt;a href=&#34;https://registry.terraform.io/providers/gitlabhq/gitlab/latest&#34;&gt;GitLab Terraform provider&lt;/a&gt; builds on top of this API.&lt;/p&gt;&#xA;&lt;p&gt;It assumed here that the Terraform controller (e.g. your laptop) is able to reach your GitLab instance&amp;rsquo;s TCP port 443 - if it can&amp;rsquo;t there&amp;rsquo;s no way Terraform&amp;rsquo;s API calls will work. The same approach should work with gitlab.com - you can probably (=untested) skip the base_url parameter in that case.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The four ways to install Puppet modules</title>
				<link>https://www.puppeteers.net/blog/the-four-ways-to-install-puppet-modules/</link>
				<pubDate>Tue, 13 Apr 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/the-four-ways-to-install-puppet-modules/</guid>
				<description>&lt;p&gt;When working with Puppet and Puppet modules in particular you quickly notice that there are several ways to manage module dependencies. Today I learned about a &lt;em&gt;new&lt;/em&gt; way introduced in Puppet Bolt 3.x, so I thought I&amp;rsquo;d compile a list that celebrates this diversity:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://puppet.com/docs/puppet/7.5/modules_metadata.html&#34;&gt;metadata.json&lt;/a&gt;: used primarily to dependency metadata to &lt;a href=&#34;https://forge.puppet.com/&#34;&gt;Puppet Forge&lt;/a&gt;. Some tools like &lt;a href=&#34;https://github.com/voxpupuli/librarian-puppet&#34;&gt;librarian-puppet&lt;/a&gt; and &lt;a href=&#34;https://www.puppeteers.net/blog/tag/puppet-litmus/&#34;&gt;puppet-litmus&lt;/a&gt; use / can use this file to download dependency modules. The downside is that you can&amp;rsquo;t define the location of the modules, so you&amp;rsquo;re limited to Forge modules.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Notes about puppet-litmus testing</title>
				<link>https://www.puppeteers.net/blog/notes-about-puppet-litmus-testing/</link>
				<pubDate>Sun, 07 Mar 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/notes-about-puppet-litmus-testing/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://puppetlabs.github.io/litmus/&#34;&gt;Puppet Litmus&lt;/a&gt; is a Puppet acceptance test harness that &lt;a href=&#34;https://puppetlabs.github.io/litmus/litmus-concepts.html&#34;&gt;leverages&lt;/a&gt; on many existing, proven technologies. In the long run Litmus aims to replace &lt;a href=&#34;https://github.com/voxpupuli/beaker&#34;&gt;Beaker&lt;/a&gt;. However, the latter is currently still the only way to run multi-machine (e.g. cluster) acceptance tests in a standardized way. For example we use Beaker for our Keycloak domain mode cluster tests &lt;a href=&#34;https://github.com/treydock/puppet-module-keycloak/blob/master/spec/acceptance/1_domain_mode_cluster_spec.rb&#34;&gt;in puppet-module-keycloak&lt;/a&gt;. On a high-level the test process is the same as with Beaker:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Provision the SUT (&amp;ldquo;System Under Test&amp;rdquo;)&lt;/p&gt;</description>
			</item>
			<item>
				<title>Configuring ejabberd multi-user chatrooms</title>
				<link>https://www.puppeteers.net/blog/configuring-ejabberd-multi-user-chatrooms/</link>
				<pubDate>Fri, 12 Feb 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/configuring-ejabberd-multi-user-chatrooms/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://www.ejabberd.im/&#34;&gt;Ejabberd&lt;/a&gt; is a very flexible and scalable XMPP server. We use it because it can be configured using a simple yaml configuration file and managed via &lt;em&gt;ejabberdctl&lt;/em&gt; commands. This makes it a good fit for our infrastructure as code approach. That said, ejabberd does require one to understand the XMPP protocol/jargon as it does not abstract away any of it. So simple things like creating chatrooms, limiting access to them and playing history backlog to users who connected them can be an effort if you&amp;rsquo;ve never done it.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Ejabberd message archiving and history playback</title>
				<link>https://www.puppeteers.net/blog/ejabberd-message-archiving-and-history-playback/</link>
				<pubDate>Fri, 12 Feb 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/ejabberd-message-archiving-and-history-playback/</guid>
				<description>&lt;p&gt;When using &lt;a href=&#34;https://www.ejabberd.im/&#34;&gt;ejabberd&lt;/a&gt; in a company for multi-user chat (see &lt;a href=&#34;https://www.puppeteers.net/blog/configuring-ejabberd-multi-user-chatrooms/&#34;&gt;my earlier blog post&lt;/a&gt;) people will quickly start complaining that they missed discussions because they had been offline. Ejabberd &lt;em&gt;does&lt;/em&gt; play back last 20 messages when user joins a room, but that is too little for an active chatroom. The simplistic approach is to set &lt;em&gt;history_size&lt;/em&gt; in &lt;a href=&#34;https://docs.ejabberd.im/archive/20_04/modules/#mod-muc&#34;&gt;mod_muc settings&lt;/a&gt; in ejabberd.yml to a higher value:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mod_muc:&#xA;  history_size: 200&#xA;  --- snip ---&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;This simplistic approach should work with any XMPP clients.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Creating custom facts programmatically</title>
				<link>https://www.puppeteers.net/blog/creating-custom-facts-programmatically/</link>
				<pubDate>Fri, 18 Dec 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/creating-custom-facts-programmatically/</guid>
				<description>&lt;p&gt;Writing static facts is fairly easy even with a low level of Ruby skills. Below is an example of a fact that returns true or false depending on whether the node has a /boot partition:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Facter.add(:has_bootfs) do&#xA;  setcode do&#xA;    if Facter.value(:mountpoints)[&amp;#39;/boot&amp;#39;].nil?&#xA;      false&#xA;    else&#xA;      true&#xA;    end&#xA;  end&#xA;end&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;As you can see above the required information was already inside the &amp;ldquo;mountpoints&amp;rdquo; fact of Facter.&lt;/p&gt;&#xA;&lt;p&gt;Using the fact is easy:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Fattening the workflow, part 5: Hiera and content encryption</title>
				<link>https://www.puppeteers.net/blog/fattening-the-workflow-part-5-hiera-and-content-encryption/</link>
				<pubDate>Thu, 03 Dec 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/fattening-the-workflow-part-5-hiera-and-content-encryption/</guid>
				<description>&lt;p&gt;Separating data from code in Puppet modules is advisable as it improves reusability of code. The separation can be accomplished with Hiera by having separate levels based on facts, organizational units, locations, etc.&lt;/p&gt;&#xA;&lt;p&gt;Hiera can also be used for storing private data that needs to be protected and must not be readable by outsiders. Typically the data, like all other code, is stored in a version control system that may be located outside the organisation. In such a case Hiera encryption is a must.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Fattening the workflow, part 4: Roles and profiles</title>
				<link>https://www.puppeteers.net/blog/fattening-the-workflow-part-4-roles-and-profiles/</link>
				<pubDate>Wed, 02 Dec 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/fattening-the-workflow-part-4-roles-and-profiles/</guid>
				<description>&lt;p&gt;If the workflow that includes the &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-puppet-workflow-part-1-the-control-repository/&#34;&gt;control repository&lt;/a&gt;, &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-workflow-part-2-r10k/&#34;&gt;r10k&lt;/a&gt; and &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-workflow-part-3-gitlab-and-similar/&#34;&gt;GitLab&lt;/a&gt; still feels too light, there are yet more ways to make the workflow heavier by adding more abstraction to the Puppet modules themselves. This is done by adopting the &amp;ldquo;Roles and Profiles pattern&amp;rdquo; that was &lt;a href=&#34;http://craigdunn.org/2012/05/239/&#34;&gt;developed by Craig Dunn&lt;/a&gt; and popularized in the blog posts by &lt;a href=&#34;http://garylarizza.com/&#34;&gt;Gary Larizza&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Roles and profiles are just Puppet classes. Profiles are usually used for creating technology stacks. A good example is a web application whose installation requires a web server (nginx, apache), a database server (postgresql, mysql) and several other components. The configurations for such an application could of course be done with a &amp;ldquo;regular&amp;rdquo; Puppet module but the reusability of the module would be rather limited for two reasons:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Fattening the workflow, part 2: r10k</title>
				<link>https://www.puppeteers.net/blog/fattening-the-workflow-part-2-r10k/</link>
				<pubDate>Tue, 01 Dec 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/fattening-the-workflow-part-2-r10k/</guid>
				<description>&lt;p&gt;In the previous post I discussed the &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-puppet-workflow-part-1-the-control-repository/&#34;&gt;control repository structure&lt;/a&gt;. In this post I&amp;rsquo;ll talk about &lt;a href=&#34;https://github.com/puppetlabs/r10k&#34;&gt;r10k&lt;/a&gt;. That tool is used for deploying control repository branches into matching Puppet environments on the Puppet server. Installing r10k is very straightforward with the bundled gem:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ /opt/puppetlabs/puppet/bin/gem install r10k&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;After this you&amp;rsquo;ll need a settings file for r10k, &lt;em&gt;/etc/puppetlabs/r10k/r10k.yaml:&lt;/em&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;--- &#xA; :cachedir: /opt/puppetlabs/puppet/cache/r10k &#xA; :sources: &#xA; control: &#xA; basedir: /etc/puppetlabs/code/environments &#xA; prefix: false &#xA; remote: git@gitlab.com:myorg/control-repo.git&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;Several requirements must be met before the configuration above will work:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Fattening the workflow, part 3: GitLab and similar</title>
				<link>https://www.puppeteers.net/blog/fattening-the-workflow-part-3-gitlab-and-similar/</link>
				<pubDate>Tue, 01 Dec 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/fattening-the-workflow-part-3-gitlab-and-similar/</guid>
				<description>&lt;p&gt;In the previous posts of this series I discussed &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-puppet-workflow-part-1-the-control-repository/&#34;&gt;the control repository&lt;/a&gt; and &lt;a href=&#34;https://www.puppeteers.net/blog/fattening-the-workflow-part-2-r10k/&#34;&gt;r10k&lt;/a&gt;. The last component in fattening the workflow is Git provider such as GitLab, GitHub or Bitbucket. Nowadays all of them are reasonable choices for storing private Git modules, which Puppet control repositories and site-specific modules tend to be. One of the biggest advantages of GitLab over its competition is that it is open source and can be installed locally.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Fattening the Puppet workflow, part 1: The control repository</title>
				<link>https://www.puppeteers.net/blog/fattening-the-puppet-workflow-part-1-the-control-repository/</link>
				<pubDate>Thu, 26 Nov 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/fattening-the-puppet-workflow-part-1-the-control-repository/</guid>
				<description>&lt;p&gt;If editing Puppet code and Hiera directly with puppetmaster feels too easy, you can complicate the Puppet workflow as much you like by adding more components to the palette. Adding the so called &lt;a href=&#34;https://puppet.com/docs/pe/2017.3/code_management/control_repo.html&#34;&gt;control repository&lt;/a&gt; and &lt;a href=&#34;https://puppet.com/docs/puppet/5.3/environments_about.html&#34;&gt;r10k&lt;/a&gt; to Puppet environment maintenance instantly adds several phases to your initially simple workflow. There are also benefits that I&amp;rsquo;ll discuss later on.&lt;/p&gt;&#xA;&lt;p&gt;The control repository (control repo for short) is a Git repository that is used to create dynamic Puppet environments on the Puppet master. Each Git branch can be turned into a matching Puppet environment. The name of the default branch, production, is the same as the environment the Puppet agents use by default. The content of the control repo branches look like this:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Using Puppet Bolt to apply roles to nodes, part 1</title>
				<link>https://www.puppeteers.net/blog/using-puppet-bolt-to-apply-roles-to-nodes-part-1/</link>
				<pubDate>Sat, 17 Oct 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/using-puppet-bolt-to-apply-roles-to-nodes-part-1/</guid>
				<description>&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; this article is somewhat outdated. Please refer to &lt;a href=&#34;https://www.puppeteers.net/blog/serverless-puppet-with-control-repo-hiera-roles-and-profiles-and-puppet-bolt/&#34;&gt;Serverless Puppet with control repo, Hiera, roles and profiles and Puppet Bolt&lt;/a&gt; instead.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://puppet.com/docs/bolt/latest/bolt.html&#34;&gt;Puppet Bolt&lt;/a&gt; is a designed to be an orchestration tool, but it can be used for configuration management as well. For example you may have a small environment of handful of nodes where having a dedicated Puppet server would be an overkill, or you have some nodes in the infrastructure where you can&amp;rsquo;t or don&amp;rsquo;t want to install a Puppet Agent.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Debugging Packer provisioning</title>
				<link>https://www.puppeteers.net/blog/debugging-packer-provisioning/</link>
				<pubDate>Wed, 05 Aug 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/debugging-packer-provisioning/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://www.packer.io/&#34;&gt;Packer&lt;/a&gt; is an excellent tool for automating creation of machine images such as AWS AMIs or Docker container images. This is particularly useful when you need to scale up by spinning up instances on-demand or if you want to package software that is challenging to manage with a configuration management system. It is also extremely useful when creating actual packaged product for AWS Marketplace, for example.&lt;/p&gt;&#xA;&lt;p&gt;In Packer you take a &amp;ldquo;base box&amp;rdquo; such as Ubuntu 18.04 base image and modify its contents with provisioning, for example to install and configure software on the image. Several different types of provisioners are supported, including but not limited to shell scripts, Puppet manifests and Ansible playbooks. The concept of provisioners is the same as in &lt;a href=&#34;https://www.vagrantup.com/&#34;&gt;Vagrant&lt;/a&gt; and &lt;a href=&#34;https://www.terraform.io/&#34;&gt;Terraform&lt;/a&gt;.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Puppet Bolt with a Puppet control repository</title>
				<link>https://www.puppeteers.net/blog/puppet-bolt-with-a-puppet-control-repository/</link>
				<pubDate>Mon, 30 Mar 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/puppet-bolt-with-a-puppet-control-repository/</guid>
				<description>&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; this article is somewhat outdated. Please refer to &lt;a href=&#34;https://www.puppeteers.net/blog/serverless-puppet-with-control-repo-hiera-roles-and-profiles-and-puppet-bolt/&#34;&gt;Serverless Puppet with control repo, Hiera, roles and profiles and Puppet Bolt&lt;/a&gt; instead.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://puppet.com/docs/bolt/latest/bolt.html&#34;&gt;Puppet Bolt&lt;/a&gt; is an orchestration tool similar to &lt;a href=&#34;https://www.ansible.com/&#34;&gt;Ansible&lt;/a&gt;. It is suitable for multiple use-cases:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Running ad hoc commands on target nodes. We use this approach for testing Puppet feature branches before approving and merging them.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;One-off configurations written in the Puppet language&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Masterless Puppet environments (look &lt;a href=&#34;https://puppet.com/blog/introducing-masterless-puppet-bolt/&#34;&gt;here&lt;/a&gt;). You may not always have enough privileges, trust or will to manage a complete Puppet infrastructure including Puppetserver, PuppetDB and Puppet Agents.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Simple orchestration with Puppet Bolt</title>
				<link>https://www.puppeteers.net/blog/simple-orchestration-with-puppet-bolt/</link>
				<pubDate>Mon, 30 Mar 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/simple-orchestration-with-puppet-bolt/</guid>
				<description>&lt;p&gt;As discussed in the introductory post &lt;a href=&#34;https://www.puppeteers.net/blog/puppet-bolt-with-a-puppet-control-repository/&#34;&gt;one of the use-cases for Puppet Bolt is orchestration&lt;/a&gt; - running actions on multiple targets in a certain order, possibly using results of actions or data from some targets on other targets. Orchestration with Bolt plans is quite easy: you just create a plan with multiple TargetSpec parameters, each representing a target or a type of target. A classic example is &lt;a href=&#34;https://puppet.com/blog/introducing-masterless-puppet-bolt/&#34;&gt;two or more web servers behind a load balancer&lt;/a&gt;. In this case we do something even simpler and just take a fact from a node called &amp;ldquo;first&amp;rdquo; and create a file on node &amp;ldquo;second&amp;rdquo; that uses the value of that fact in a file.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Managing Jenkins with Puppet, part 1: Basic installation</title>
				<link>https://www.puppeteers.net/blog/managing-jenkins-with-puppet-part-1/</link>
				<pubDate>Fri, 31 Jan 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/managing-jenkins-with-puppet-part-1/</guid>
				<description>&lt;p&gt;It seems every other organization is using Jenkins these days. Jenkins is a continuous integration and continuous delivery server that can be used to automate building, testing, and delivering or deploying software. &lt;/p&gt;&#xA;&lt;p&gt;Many organizations also use Puppet for their configuration management needs. Puppet is, if not the de facto configuration management solution, at least one of the most mature and field tested ones. It consists of several server components, agents, a declarative programming language, amongst others. Puppet can be used to install, set up and manage large number of all kinds of resources.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Using Augeas to manage resources in Puppet</title>
				<link>https://www.puppeteers.net/blog/using-augeas-to-manage-resources-in-puppet/</link>
				<pubDate>Fri, 31 Jan 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/using-augeas-to-manage-resources-in-puppet/</guid>
				<description>&lt;p&gt;This translated from the original Finnish article that is available &lt;a href=&#34;https://www.puppeteers.net/blog/augeas-resurssien-luonnista-ja-debuggaamisesta/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The Augeas resource in Puppet allows one to manage parts of a complex configuration file instead of managing the whole file using a template or a static file. For trivial cases stdlib&amp;rsquo;s &lt;a href=&#34;https://github.com/puppetlabs/puppetlabs-stdlib/blob/master/REFERENCE.md#file_line&#34;&gt;file_line resource&lt;/a&gt; may be sufficient. While use of templates or static files is in general more reliable and easier than use of Augeas, the latter is quite useful in many cases. As using Puppet Augeas resource directly is quite challenging, a useful practice is to first make the changes manually with &amp;ldquo;augtool&amp;rdquo; and only then convert the results into Puppet Augeas resources. We use PostgreSQL&amp;rsquo;s pg_hba.conf file here as an example.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Puppet rspec testing: understanding describe and context</title>
				<link>https://www.puppeteers.net/blog/puppet-rspec-testing-understanding-describe-and-context/</link>
				<pubDate>Fri, 06 Dec 2019 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/puppet-rspec-testing-understanding-describe-and-context/</guid>
				<description>&lt;p&gt;In the &lt;a href=&#34;https://www.puppeteers.net/blog/puppet-module-rspec-testing-with-pdk/&#34;&gt;Puppet module rspec testing with PDK&lt;/a&gt; blog post I covered the procedure of creating and running puppet-rspec tests with PDK. This blog post will go more in-depth to that topic, in particular &lt;em&gt;describe&lt;/em&gt; and &lt;em&gt;context&lt;/em&gt; which you see in all puppet-rspec tests.&lt;/p&gt;&#xA;&lt;p&gt;When looking at the puppet-rspec test syntax the first time it looks very &amp;ldquo;rubyesque&amp;rdquo;. Somebody used to staring at Python code, for example, could call the syntax &amp;ldquo;odd&amp;rdquo; or &amp;ldquo;1337&amp;rdquo;. Fortunately reading the &lt;a href=&#34;https://relishapp.com/rspec&#34;&gt;Ruby rspec documentation&lt;/a&gt; helps understand what is going on under the hood and thus making the spec files look less magical. In my case rspec documentation helped understand how contexts work. In the &lt;a href=&#34;https://www.puppeteers.net/blog/puppet-module-rspec-testing-with-pdk/&#34;&gt;previous blog post&lt;/a&gt; a context was created for every supported operating system listed in metadata, and rspec tests were run for each of them by using facts from facterdb.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Migrating from Fabric 1 to Fabric 2</title>
				<link>https://www.puppeteers.net/blog/migrating-from-fabric-1-to-fabric-2/</link>
				<pubDate>Thu, 10 Oct 2019 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/migrating-from-fabric-1-to-fabric-2/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://www.fabfile.org/&#34;&gt;Fabric&lt;/a&gt; is a Python library for executing shell commands remotely over SSH in serial or parallel mode. I used Fabric 1 for years and it was - and still is - an excellent tool. While Fabric&amp;rsquo;s use-cases overlap somewhat with those of &lt;a href=&#34;https://www.ansible.com/&#34;&gt;Ansible&lt;/a&gt;, the difference is that Fabric &lt;em&gt;is not&lt;/em&gt; state-based. In other words, in Fabric you don&amp;rsquo;t tell that &amp;ldquo;file a should have contents n and mode m&amp;rdquo;. Instead, you just run commands on the target host which hopefully result in the end state you&amp;rsquo;re looking for. Or maybe you&amp;rsquo;re not even interested in end-state per se, but just need to run some commands. Both approaches have their use-cases. Fabric and Ansible are quite powerful as orchestration tools: they allow running task a on server x, then task b on server y. For enforcing infrastructure to be in a certain state we prefer &lt;a href=&#34;https://puppet.com/download-open-source-puppet&#34;&gt;Puppet&lt;/a&gt; and &lt;a href=&#34;https://www.terraform.io/&#34;&gt;Terraform&lt;/a&gt; over Ansible.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Puppet module rspec testing with PDK</title>
				<link>https://www.puppeteers.net/blog/puppet-module-rspec-testing-with-pdk/</link>
				<pubDate>Thu, 05 Sep 2019 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/puppet-module-rspec-testing-with-pdk/</guid>
				<description>&lt;p&gt;If you&amp;rsquo;ve searched for instructions on how to write unit tests for Puppet code you&amp;rsquo;ve probably stumbled upon tutorials such as &lt;a href=&#34;https://puppet.com/blog/next-generation-of-puppet-module-testing&#34;&gt;this&lt;/a&gt; that are of good quality, but suggest installing and using tools such as puppetlabs_rspec_helper directly. Or you may encounter references to &lt;a href=&#34;https://github.com/ruby/rake&#34;&gt;rake&lt;/a&gt;, &lt;a href=&#34;https://bundler.io/&#34;&gt;bundler&lt;/a&gt;, &lt;a href=&#34;https://rvm.io/&#34;&gt;rvm&lt;/a&gt; and &lt;a href=&#34;https://rspec.info/&#34;&gt;rspec&lt;/a&gt;. Then you start experimenting these tools, some of which (rvm and bundler) are aimed at managing the dependency hell that arises when you, or your team, works simultaneously on multiple projects with different dependency requirements. In the end you are maybe able to run spec tests on your Puppet module, but after all installations of gems and experiments you&amp;rsquo;re unsure what you did to make everything work. You also don&amp;rsquo;t want to become a hard-core Ruby developer who actually understands all these tools well - you just want to test your Puppet code.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
