Authenticate and authorize Grafana users from FreeIPA groups via Keycloak
Grafana is a common tool to visualize data from multiple datasources. Perhaps the most common datasource is Prometheus. If an organization has a Single-Sign On solution, it makes sense to authenticate users centrally with that solution That will make authentication easier and friendlier for end users (authenticate once and then access multiple services), and also enable stronger authentication by adding multifactor authentication.
In addition to authenticating user, it is also possible to authorize Grafana users based on their group membership.
Making sense of JBOSS/Wildfly interfaces in domain mode
In this blog we consider JBoss/Wildfly domain mode in the context of the wonderful Keycloak software. It is not necessarily trivial to understand how the interfaces should be configured, especially if you want to do something other than the defaults, for example to secure your Wildfly/JBOSS configuration, or if you are dealing with a more complex nodes with multiple network interfaces.
Assumptions:
-
We want to use Keycloak in domain mode. In this operating mode Keycloak application is clustered and also the caches, like user sessions are replicated in the cluster.
Limiting the scope of puppet-rspec tests
Some Puppet modules like puppet-module-keycloak have hundreds of unit tests. That is good for test coverage, but waiting for test results hurts your productivity when you’re developing tests for your new code. There are at least two ways to (temporarily) limit the scope of the tests that you run. First method is baked in into the Puppet Development Kit command-line:
$ pdk test unit --tests=spec/classes/init_spec.rb
This runs only the tests in the specified file.
RIP: Puppeteers Finnish website
Today was a special day. Our Finnish website went to greener pastures after having spent its golden months serving permanent HTTP redirects to our current website while having been taken our of our Terraform codebase. It is customary to speak a few words in occasions like this, so here we go.
“Beloved www.puppeteers.fi. You were a well-liked website that brought us our first customer. Occasionally you were down because MySQL innodb_buffer_pool_size was set too low. Or because overall system memory went too low and the OOM killer broke you. But we cannot blame you for that - it was just us trying to spare some €€€ that caused all that. You served us well, but it was time to finally move on.”
AWS to Azure resource translation table
We use Terraform for managing our Cloud infrastructure. Our customers typically use AWS and that’s what we’re most familiar with. Each public Cloud has its own terminology, so this page is a translation table between Terraform resource names in the AWS and Azure providers:
| AWS | Azure |
|---|---|
| aws_instance | azurerm_linux_virtual_machine |
| aws_network_interface | azurerm_network_interface |
| aws_security_group | azurerm_network_security_group |
| aws_security_group_rule | azurerm_network_security_rule |
| aws_vpc | azurerm_virtual_network |
| aws_subnet | azurerm_subnet |
| inapplicable | azurerm_resource_group |
| aws_s3_bucket | azurerm_storage_account |
| region | location |
Mapping of Terraform AWS resource names to Azure resource names
High-level and low-level tasks in Kanban
We use Kanban to coordinate our projects and tasks. Kanban is focused on visualizing and improving throughput, that is, making projects (high-level) and tasks (low-level) go through the system as fast as by limiting work in progress, which in turn minimizes waste (time and money).
Our field of work is IT operations and we’re generally quite busy with fulfilling requests from our internal and external stakeholders. Most of our tasks are quite small, about 1-4 hours each, and produce value immediately. We can generally get these done (“through the system”) quickly without having to stop in the middle and can then forget about them. However, we also have bigger tasks that tend to take a lot longer, maybe 8-24 hours of focused work and often involve multiple persons.
Querying DNS in Puppet code
I recently had to add access control rules to OpenVPN Access Server to permit certain groups to access certain IP addresses. As we manage our Access Server configurations with Puppet using puppet-openvpnas (by the author), we needed a way to parameterize the allowed IP addresses while keeping the Puppet code readable.
This is where puppet-dnsquery came really handy. It allows using data that’s already available in DNS and using it in Puppet code. A simplistic example:
Migrating from Puppet 5 to 6 with Puppet Bolt
The main annoyance with agent-based configuration management is the management of the agents themselves. They usually don’t require any handholding after the initial install, except when you need to migrate them to a new environment. For example, migrate from a Puppet 5-based server to Puppet 6.
The migration process is not overly difficult, but in order to scale to more than a handful of nodes you will need to orchestrate the process. Historically we would have used Ansible for this task, but nowadays we prefer Puppet Bolt, which is more powerful and flexible in our use-cases. The Bolt plans typically end up being ugly, but based on my experience with Ansible Playbooks that tends to be the case anyways. I guess this is the natural result of mixing state-based configuration management, ad hoc commands and orchestration together.
Sed spell to ease moving to Terraform 0.13
When moving from older versions of Terraform 0.12.x to latest 0.12.x (now: 0.12.29) you may notice the following warnings:
Warning: Interpolation-only expressions are deprecated
on backup.tf line 11, in resource "hcloud_server_network" "backup_example_org":
11: server_id = "${module.backup_example_org.id}"
These make sense, but may come as a surprise as earlier 0.12.x versions were perfectly fine with them.
You may have tons of these, so fixing them manually gets tiresome. The fix is not too difficult, but is quite unreadable due to escaping:
Creating custom facts programmatically
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:
Facter.add(:has_bootfs) do
setcode do
if Facter.value(:mountpoints)['/boot'].nil?
false
else
true
end
end
end
As you can see above the required information was already inside the “mountpoints” fact of Facter.
Using the fact is easy: