Mautic spam prevention
Mautic is a widely used open source email marketing automation application written in PHP. Email marketing is typically used in conjunction with inbound marketing done by asking people to give their email address in exchange for something, like a free ebook or a newsletter with good content. As you’re asking for the email address on a publicly facing webpage, spambots will find your form, and start misusing it to send your “Welcome” emails all over the place. This in turn may result in lots of bounces and/or complaints, which may get you locked out from your email service provider unless you pay attention. So, you need a way to block or fool those spam bots to prevent such issues, and to keep the Mautic database clean.
Conditional provisioner blocks in Terraform
I’ll start with a spoiler: what the title suggests is not possible. It is, however, possible to accomplish this with cloud-init and Terraform templates as described in the Multi-part cloud-init provisioning with Terraform blog post.
If you need to use SSH/WinRM provisioning, then there are various workarounds you can apply, and this article explains some of them and goes into depth into one in particular.
The first workaround is relatively clean, but is not usable in all cases, especially when working with complex modules. The idea is to have two resources, here of type aws_instance. Those resources are identical except for the provisioner blocks:
Dealing with multiple AWS accounts with one Keycloak client for Single-Sign On
This article assumes that the user backend for Keycloak is FreeIPA. Regardless of that the instructions will apply to any other setup with minor modifications. Here we use two different AWS accounts renamed to 123412341234 and 567856785678 to protect the personal information of the innocent. The Keycloak staging cluster on which this integration was done is called id-staging.example.org and the production cluster is called id.example.org. The Keycloak realm is EXAMPLE.ORG. Replace those with the values correct for your environment.
Allowing external email forwarding in Office 365
We use Zimbra as our main email server. We also have Office 365 subscription to make working with our clients a bit easier. The challenge is that when customers send us, say, Teams meeting invites, they typically use autofill and the email gets sent to our Office 365 mailboxes which nobody really looks at.
It is possible to fix this by configuring email forwarding. That is theoretically possible out of the box on a per-user basis in https://outlook.office.com/mail/options/mail/forwarding. However, when you actually try it out you will get an error message in your Office 365 inbox because forwarding is disabled on the organizational level by default:
Enabling AWS EC2 instance automatic recovery with Terraform
AWS EC2 instances are subject to two types of status checks (AWS docs):
- System status check (issues with the underlying hardware/networking: “the AWS side”)
- Instance status check (issues with the OS, e.g. OOM, file system corruption, broken networking, etc: “our side”)
The official AWS EC2 instance recovery documentation claims that automatically recovering from an EC2 instance failure is only possible for system status checks, but the AWS documentation is outdated: Cloudwatch metrics are available for both types of check failures and people have set up recovery for both types of failures using AWS CLI.
Extending snmpd with custom scripts
Traditional network monitoring systems tend to get their monitoring data via SNMP. In case of Linux snmpd is usually the system application that’s responsible for providing that data. The data consists mostly, but not entirely, of metrics. For example, the data contains strings such as operating system version, administrative contacts and network interface names.
It is possible to make snmpd run custom scripts and programs to gather more data from the system. The options are described in snmpd.conf man page, but here are the most important ones for this use-case:
Packer QEMU: Building Ubuntu 20.04/22.04/24.04 VM images

Introduction
Packer QEMU builder allows you to build virtual machine images from scratch. You need a Packerfile, an automatic installation configuration file (autoinstall, kickstart or preseed) and the operating system installer (e.g. ISO). The benefit of Packer QEMU in particular are that you can have fine-grained control over the virtual machine image content such as disk partitioning. Moreover you don’t need to rely on official base images produced by other people, such as the official Ubuntu Cloud images.
Making wpcal.io work with Zimbra calendars
Scheduling meetings with email is annoying. When everyone is on the same timezone that kind of works, but tends to be slow. When you factor in timezone differences the process becomes really error-prone and slows down even more, often to several days. For this reason we wanted to provide people - including our customers - a way to easily schedule meetings with us.
We’re special in the sense that we self-host almost everything we use. For email and calendars we use Zimbra and for our website we use Wordpress. Most people seem to use Calendly as a meeting scheduler, but we ended up choosing wpcal.io which is a native Wordpress plugin and seems to work quite nicely.
Testing Puppet feature environments with Puppet Bolt
Puppet feature environments are an excellent way to test code before deploying it, typically to production. They allow testing Puppet runs on no-operation mode across the whole node population managed by Puppet. There are sometimes cases where your code changes potentially impact many nodes and you’re not exactly sure of their scope or effect. In that case it helps to test your code on all Puppet-managed nodes. The challenge is that Puppet open source does not have any built-in mechanism to do that. This is where we can make good use of Puppet Bolt.
Puppet types and providers development part 5: self.instances
This blog post is a part of this blog post series:
The self.instances is a provider class method that is used to produce an array containing all resources found from the system. For example, a yum package provider might run “rpm -qa” in self.instances to get a list of packages installed on the system. This serves two main purposes:
- Allows using of “puppet resource type” to produce Puppet code for all resources of type found on the system.
- Data created by self.instances can be passed to self.prefetch to cache resource properties. The cached properties are then reused for every resource of that provider type. For example, a yum package provider might create a list of packages installed on a system when Puppet encounters the first “yum” package resource of “yum” type. That cache would then be reused, thus removing the need to individually check each package’s state.
As discussed in Puppet types and providers development part 4: caching resource properties to improve performance self.instances or self.prefetch are not really suitable for scenarios where you need to manage (multiple) remote systems using the same provider, because things like connection would be given in the Puppet resource definition are at the provider instance level, to which provider class level methods like self.instance and self.prefetch do not have access to.