Foreman Ansible modules and multitenancy

I see a possible conflict between the design of the Foreman Ansible modules and Ansible best practices on the one hand, and user expectations relating to Foreman’s multitenancy on the other.

Background: We use the Foreman Ansible modules as part of the orcharhino installer to add post installation configuration. For example, users can select from a list of operating systems (e.g.: “Ubuntu 18.04”) which will then be fully configured for provisioning with Foreman by our Ansible role. So far so good. Now consider a user who does not select “Ubuntu 18.04” during the initial installation, but now wants it. Well they could just set the relevant Ansible variable and re-run the playbook, right? In principal yes, but here the conflict with multitenancy:

Suppose the Foreman installation has Organization A and Organization B, which are managed by separate teams/departments. The Organization A administrators don’t want to use the Foreman Ansible modules, so they add “Ubuntu 18.04” by hand, via the GUI. The Organization B administrators are more automation minded, and want to do everything using the Foreman Ansible Modules, but they have no idea what Organization A is getting up to. They now want to add “Ubuntu 18.04” to their Organization, so they re-run the playbook. Since Ansible is state descriptive, and the Organization B administrators only request their own organization, this will have the effect of kicking the existing “Ubuntu 18.04” entities (created by Organization A via the GUI) out of Organization A.

This will probably make Organization A very angry.

Diagnosis: It follows, that as soon as anyone wants to use the Foreman Ansible Modules to manage Foreman, everyone must use Foreman Ansible Modules for everything (or risk fighting each other). Surely, this clashes with basic user expectation of Foreman’s promise of multitenancy?

Possible Solutions:

  • Don’t pretend Organizations/Locations provide multitenancy since entities are shared across taxonomies and conflicts are inevitable?
  • Completely rework the way Organizations/Locations work?
  • Add a option to the Foreman Ansible modules to be additive (rather than state descriptive) with respect to Organizations/Locations (a mitigation at best, and totally counter to Ansible design principles).
  • Explain to me why the use case I described, and/or my whole understanding of Foreman’s multitenancy support is wrong/invalid?!
  • ?!

I am pretty sure @evgeni will have some opinions on this, but I would love to here from as many community members as possible!

P.S.: I don’t really have much skin in this particular debate myself. I am perfectly happy to have somebody explain to me why the use case I described/my understanding of multitenancy is nonsense. In that case I wonder if there is some documentation I missed (or still needs to be written).

2 Likes

IMHO this it the only viable solution. Sharing resources between taxonomies cause too much pain. We should make every resource taxable and avoid sharing completely. I know this will make some things that were easy to achieve harder, but that’s inevitable if we want to achieve the real multitenancy.

1 Like

I do indeed have strong opinions about this topic :wink:

But let’s step away from Ansible, Foreman and our modules for a bit, and look at the things more generally.

The common approach in configuration management is to describe a desired state of objects and then let the software figure out how to reach that state. And if the object has properties A, B and C, and the user only defined A and B, the software will usually don’t touch C (as the user didn’t express any desire what it should be).

This is quite orthogonal to what many users expect, as they think they describe steps that need to be executed (like in a shell script, or Makefile).

Now back to your actual problem at hand. Your users defined the OS object as Operatingsystem(name: Ubuntu 18.04, organizations:[OrgB]), and that’s exactly what the modules did, just not what the users expected.

One possible solution would be to introduce an “append” mode for such assignments (it’s more than just Taxonomies, also Templates can be assigned in a very confusing way). But that would mean that the state in the playbook doesn’t necessarily match the state in the system, which makes the system not reproducible (and that’s bad).
Another, related, would do introduce modules that can add such assignments, but then again you get “fights” between the original definition and the assignment, so you’d need to write something like Operatiingsystem(name: Ubuntu 18.04) without any organizations and then assign what’s desired.

I would, however, prefer if cross-org sharing of objects would just not exist in Foreman, and then you’d never have this problem. (so essentially, what Marek writes)

2 Likes

Full disclosure, we currently use the following mitigation workaround in our role:

- name: "Query medium"
  theforeman.foreman.resource_info:
    <<: *auth_params
    resource: "media"
    search: 'name = "{{ os_table[item].medium }}"'
    full_details: true
  register: query_result

- name: "Determine existing organizations for {{ item }}"
  ansible.builtin.set_fact:
    existing_organizations:
      "{{ query_result.resources[0].organizations | default([]) | map(attribute='name') | list }}"

- name: "Determine existing locations for {{ item }}"
  ansible.builtin.set_fact:
    existing_locations:
      "{{ query_result.resources[0].locations | default([]) | map(attribute='name') | list }}"

- name: "Add mirrors for OSes"
  theforeman.foreman.installation_medium:
    <<: *auth_params
    name: "{{ os_table[item].medium }}"
    path: "{{ or_operating_system_medium_paths[item] | default(os_table[item].medium_path) }}"
    os_family: "{{ os_table[item].os_family }}"
    state: present
    organizations: "{{ [or_organization] | union(existing_organizations) }}"
    locations: "{{ [or_location] | union(existing_locations) }}"

This works, but is horrible. :wink:

@evgeni @Marek_Hulan If the preferred long term solution is a pretty firm “Rework Foreman taxonomies”, I am wondering how high that is on anybody’s wish list? Is there already a story/issue for it? Or is it so far in the distance that we should seriously consider a “assignment” module (as evgeni suggested) as a stopgap measure?

As Marek wrote in another thread every now and then when someone complains or something is broken all agreed on it needs some rework, but there was no actual work done on it yet. But it sounded like it is now high on the wishlist as it would make sense when looking at the extraction of puppet.

Realisticly speaking, don’t expect taxonomies rewrite sooner than a year from now. The puppet extraction (IMHO slightly simpler thing) took as quite long.

I have been living with the current taxonomies for a long time, and I can continue to live with them.

I am happy so long as I know it won’t be completely forgotten a year from now. From the responses in this thread, I get the feeling I am not the first to identify the current taxonomies design as a pain point, so I now know others have this on their mental list as well.

I do still wonder if there is already a story or epic or similar, that I can occasionally check for movement?

I think we’d probably use https://projects.theforeman.org/issues/10022 as a tracker, I’m not aware of any epic for this but happy to be corrected.