Hello!
I’m trying to green field a Puppet setup and compartmentalize some things so that we can implement a change management process through git. I’m running into a couple of roadblocks, and was hoping that the Foreman community could help with that, since Foreman is currently managing our bare metal provisioning and is hooked into our Puppet infrastructure.
A side note before the wall of text - I’m happy to be pointed towards a consultant or group that could do consulting on a complex problem such as this.
Goals
- Use each tool for where it is most effective
- Define a hierarchy of attributes such that each level inherits config from the previous level
Impetus
In my exploration of Hiera and Puppet, I have been able to break out my separation of concerns into the following:
- Puppet Modules define how a system gets to a certain state
- Hiera Data defines what state the system should be in
- Foreman provisions systems and pre-configures them for Puppet usage
With this model, if we want to change the configuration for a particular purpose, we would simply branch the hiera data repo, modify it, make a pull request, and merge it back in. It also means that the given state of a system is defined only through the combined Hiera data.
Example of Intent
Assume a hierarchy of configuration:
infrastructure_server
└── openstack
├── compute
│ └── dhcp_agent
└── controller
A server that needs to be an OpenStack controller node would inherit all of the configuration from the “OpenStack” configuration as well as the configuration from “infrastructure_server” (and potentially any additional common.yaml file that might exist).
Design
It seems like Foreman has the perfect solution for that - use Host Groups. However, we don't want to use the Class and Smart Parameter features of Foreman as I can't seem to find any information on auditing changes to those and I do not see a mechanism for storing that configuration in Git.As such, it seems like using Foreman to define Host Groups and manage what systems are part of which group, but then use Hiera for the data for what configuration those Host Groups have is appropriate.
But, Hiera seems to have no way to define an arbitrary hierarchy, only existing ones, and to further complicate matters, if you do use it programmatically, you’re expected to define facts that build your hierarchy for you. Since Foreman provides the host group as a single value with '/'s in it, there doesn’t seem to be a way to mesh the Hiera config and the Host Group hierarchy.
Possible Solutions
Flat folder structure
Since Foreman is providing the host group, we could generate files based on the host group name, which would leave us with a Hiera config that looks like this:hierarchy:
- name: "Host Group Data"
path: "nodes/host_group/%{hostgroup}.yaml"
And then the inside of the host_group folder would contain:
infrastructure_server.yaml
infrastructure_server_openstack.yaml
infrastructure_server_openstack_compute.yaml
infrastructure_server_openstack_compute_dhcp_agent.yaml
infrastructure_server_openstack_controller.yaml
However, this removes one of the main benefits of the host group hierarchy and we would need to then have some automation in place to copy changes from parents in the hierarchy to their children, and thus the far children of the host group tree would have long and unwieldy configs.
Custom Facts
Build an automation intermediary that, whenever host group information is changed, sets custom facts like "group_1", "group_2", and "group_3" so that the Hiera config looks like the following:hierarchy:
- "%{::group_1}/%{::group_2}/%{::group_3}/%{::group_4}.yaml"
- "%{::group_1}/%{::group_2}/%{::group_3}.yaml"
- "%{::group_1}/%{::group_2}.yaml"
- "%{::group_1}.yaml"
- "common.yaml"
which would lead to a folder structure like:
infrastructure_server/openstack/compute/dhcp_agent.yaml
infrastructure_server/openstack/compute.yaml
infrastructure_server/openstack.yaml
infrastructure_server.yaml
While this seems like it might work, it also feels extremely prone to breakage.
Conclusion
After searching the Internet, I can't seem to find anyone who has tried something like this. I'd be happy to know if there's a simple solution to this that handles the goals as laid out above (someone had mentioned profiles and roles still, but that doesn't really seem to effectively encompass the host group hierarchy problem).Any help or suggestions would be appreciated!