Clarifying Variable Import Behavior for Ansible Roles (defaults/ vs. vars/)

RFC: Clarifying Variable Import Behavior for Ansible Roles (defaults/ vs. vars/)

Context and Problem Statement

Currently, the Foreman Ansible plugin imports variables defined in an Ansible role’s defaults/main.yml, but it does not capture variables defined in vars/main.yml.

  • The Problem: In the standard Ansible role directory structure, both defaults/ and vars/ are used to define variables. While their precedence differs, both are essential parts of a role’s configuration. Currently, Foreman only recognizes defaults/, which I believe makes it difficult to see the full scope of a role’s available variables within the Foreman UI.
  • User/Developer Impact: This discrepancy can be confusing for users who expect Foreman to reflect the full scope of a role’s variables. It also seems to create a gap between “pure” Ansible execution and how a role is represented under Foreman.
  • Technical Objectives:
      1. Clarify if the exclusion of vars/ is a deliberate architectural decision based on Ansible variable precedence (where vars are typically not meant for user overriding).
      1. Determine if this is simply an implementation limitation in the current parser.
  • Non-goals: At this stage, this RFC does not aim to force a change in variable precedence logic within Foreman, but rather to start a dialogue on visibility and consistency.

Proposal

I propose to investigate the possibility of extending the Ansible role importer to include variables found in vars/main.yml.

  • Details: I am considering an update to the importer so that it parses the vars/ directory of a role, similar to how it currently handles defaults/.
  • Next Steps: If the community confirms that this exclusion is not an intentional design restriction, I am interested in exploring the codebase and contributing a patch or Pull Request to implement this feature.
  • Impacts: I expect this would provide better visibility for users and ensure that Foreman’s view of an Ansible role is more closely aligned with the official Ansible specification.

Alternative Designs

  • Status Quo: Keep the current behavior where only defaults/ are imported.
    • Why it is not preferred: It leaves a part of the role’s configuration invisible to the Foreman user, potentially requiring them to check the source code of the role manually to see all variables.

Decision Outcome

To be completed after community discussion.

Impacts

  • Architectural Changes: I think it will be necessary to extend the Ansible parser within the plugin to look into the vars/ directory.

Thank you in advance for your feedback and guidance. I appreciate your time and support.

I think it was a deliberate decision. If you override variables in foreman, they get passed to ansible as inventory host_vars, meaning they win over role defaults, but not over role vars. I think the goal was to avoid situations where you would import both defaults and vars and where you would then be able to override only some of them based on some key you can’t see.

That could be changed, but we’d have to do a couple more things that we’re currently not doing.

I don’t think so, the parser should be fine with whatever you point it at.

At the moment it does leave a part of the role’s configuration invisible, but that is the part that you currently could not change from foreman anyway.

2 Likes

Totally agree with @aruzicka. If someone would ask me about how to implement I would make the same decision. defaults are meant to be overridden by the user, vars are meant to be internal and overridden in code for specific cases like different operating systems.

1 Like

Thank you for the clear explanation, @aruzicka and @Dirk.

I completely understand the design choice now. Since variables in vars/ have higher precedence than the host_vars passed by Foreman, importing them as overridable fields would indeed lead to confusion if the user’s input is ignored.

That said, I feel this might create a bit of a burden for the user. In some cases, it seems they may need to manually “peek” into the vars/ files to understand the full configuration being applied. It feels like an extra step that could perhaps be simplified if the information were visible within the UI.

If this direction (Visibility without Overridability) seems like a reasonable compromise to you, I would be happy to look into it further. My thought is to have the importer recognize variables in vars/ but display them as “Read-only” or “Internal.” This way, users can see the whole picture directly in Foreman without breaking the Ansible precedence logic.

I’m glad to explore the codebase and see if this is feasible if you think it’s a path worth considering. What are your thoughts?

If you need to look into vars/ to understand a role, the role is not well documented in my opinion! So I would agree if you say an option to display the documentation should be added.

But I also know that the rules to do Ansible documentation right are - let’s say - complex and many do not follow them in the full extend. So the question would be for me do I want to have a workaround for this by showing the content of vars/? I would still say no, as the most variables inside this directory I really do not care. E.g. package name is not important for using the role as long as it is defined correctly, but if incorrect I can not override it without fixing the code.

Thank you for the feedback, @Dirk.

I think I may have missed a crucial point in my previous message.
It seems that variables defined in vars/ are not being correctly reflected on the target machines when the role is executed via Foreman.

While a “pure” Ansible execution (via CLI) correctly applies the values in vars/main.yml, they appear to be ignored when triggered through Foreman.
As a result, users currently have to manually redefine these same variables in the Foreman WebUI just to achieve the expected execution results.

I suspect the plugin’s execution environment might handle vars/ differently than a standard ansible-playbook run.
What are your thoughts on this?

Thank you in advance for your support and insights on this.

Can you go more into details of the environment and show the Ansible code? Because there should not be something like different handling of the vars, there could only be some variables like facts which are set differently when run from different environments.

This is by the way something Ansible’s execution environments want to solve which are currently not used by Foreman. If we see more issues like “works on my machine but not on Foreman” this could be the way to go and a future feature.

Thank you for your response and for offering to look into this.

I have thoroughly re-tested the setup and confirmed that when running Ansible from Foreman, the contents of vars/ are indeed correctly reflected on the target machines. The issue was entirely due to a configuration error on my side.

Since the original motivation for my proposal was based on the assumption that vars/ were being ignored, I now agree that there is no need to change the current behavior or UI at this time. As I have confirmed that the system is working exactly as intended, I’m happy to close this discussion.

Thank you again for the insightful discussion.

2 Likes