Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing defaults for nginx_main_template.* #4

Closed
alexsegura opened this issue Sep 7, 2019 · 15 comments · Fixed by #66
Closed

Missing defaults for nginx_main_template.* #4

alexsegura opened this issue Sep 7, 2019 · 15 comments · Fixed by #66
Assignees
Labels
bug Something isn't working
Milestone

Comments

@alexsegura
Copy link

If you want to change only the NGINX user, while keeping defaults for other vars, you still have to define all the vars under nginx_main_template dict.

With those vars:

nginx_main_template_enable: true
nginx_main_template:
  user: www-data

It causes the following error:

TASK [nginxinc.nginx : (Setup: All NGINX) Dynamically Generate NGINX Main Configuration File] ************************
fatal: [sandbox]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'worker_processes'"}

We should be allowed to define only some vars, and keep defaults for the other ones.

@alessfg alessfg self-assigned this Sep 10, 2019
@alessfg
Copy link
Collaborator

alessfg commented Sep 10, 2019

Totally agree @alexsegura. The option to define single parameters is on the backlog. Development on the role has been a little bit slower than I'd like lately but things should start to pick up again in the next couple months. That being said, feel free to submit a PR if you wish 😄

@alexsegura
Copy link
Author

Thank you for your message.
Yes, I can contribute a pull request 🙂

The problem I see here and there in this role, is that the defaults are hardcoded.
So if defaults change, you have to remember to change them both in defaults/main.yml, and in templates.

https://github.com/nginxinc/ansible-role-nginx/blob/a92d424bdb5dc51b143c702754bed761e919a576/tasks/conf/upload-config.yml#L8-L14

I suppose it's because when using dicts for defaults, they get replaced. There is a hash_behavior setting but it's global I think.

Do you know a way to retrieve the "untouched" default vars for a role?
Something like role_defaults['var_name']?

@alessfg
Copy link
Collaborator

alessfg commented Sep 19, 2019

@alexsegura I don't know of a great way to accomplish this behaviour. Ideally, you'd want a setup where the role can deploy a useful configuration without using any of the values in defaults/main.yml.

The main thought that pops to mind would be using vars/main.yml to hardcode some of the default values and then do something like | default(var_main_upload_src), but I am not sure that that's the best path forward.

@evilhamsterman
Copy link

Probably the only way to do it is in the template itself with the default filter.

@alessfg
Copy link
Collaborator

alessfg commented Oct 4, 2019

Right, that is a good solution for template related parameters (and if you look at the template files the default filter is already used in a couple places). And admittedly that would address the original issue. It would be a pretty time consuming task but it's doable.

However, the question remains about what's the best approach for non template related variables, and moreso, is there a best approach?

@alexsegura
Copy link
Author

From what I see here and there, the best approach for defaults is to avoid using dicts, e.g

nginx_main_template_user: www-data

instead of

nginx_main_template:
  user: www-data

@alessfg
Copy link
Collaborator

alessfg commented Oct 5, 2019

That would partially address the issue, and initially that was how the role was structured. But when I started to introduce more complex templating options (e.g. multiple location blocks), dictionaries and lists started to make more sense.

@cilq
Copy link

cilq commented Oct 17, 2019

Or you could use separate dictionaries for default and user configuration and merge them with the combine filter. I've been using a role to deploy airflow where this method is used:
airflow_config: "{{ airflow_defaults_config | combine(airflow_user_config, recursive=True) }}"
I guess this would also remove the need to have hardcoded defaults in the templates?

The role I am referring to can be checked out here.

@alessfg
Copy link
Collaborator

alessfg commented Oct 17, 2019

Hm, that is an interesting approach, and I can see it working. Maybe it'd be worth to create a small PoC with one of the smaller dictionaries (I'm thinking of the main or stream templates) to see how good it'd work in practice.

@cilq
Copy link

cilq commented Oct 17, 2019

I already tried this for the main template and it was working as expected. However, because I went the path of least effort I merged two dictionaries nginx_default_main_template from defaults and nginx_user_main_template from the users playbook into nginx_main_template.
This would introduce a breaking change so I will refactor the role to use the merged dictionary under a new name and submit a PR.

The http template is much more difficult because there are possibly multiple user dictionaries to merge. Anchors and aliases combined with the merge operator could be an alternative but then the user is responsible to do the merge.
I will spent some time an that front as well.

BTW: Is there a reason why you chose to use a dictionary instead of a list to define multiple http templates? From what I have found the key is never really used.

@alessfg
Copy link
Collaborator

alessfg commented Oct 17, 2019

BTW: Is there a reason why you chose to use a dictionary instead of a list to define multiple http templates? From what I have found the key is never really used.

No, not really. On hindsight I think it may improve readability to have a key for each HTTP template you define, but I am not opposed to changing it to a list if it makes things easier.

@deepbrook
Copy link

deepbrook commented Apr 27, 2020

I ran into a similar issue and subsequently into this issue. I would like to offer an alternative perspective:

Default values for a configuration should not be hard-coded at all, and be left to the software being installed.

As @alexsegura already pointed out, the problem is that you need to keep the values in sync, which by nature will not always be the case (humans are error-prone).

If you feel like you must provide a default configuration, I would suggest keeping the sub-sections in separate dirs, and combine them at the lowest level if the user specifies a value, and then merge them into the configuration.

But even that, imo, is not within the scope of a role - it should copy the configuration to the target, and not make sure that its values are ok; At most, i would give an error if the software could not start due to configuration error (or use the software's validation function, if available).

@alessfg
Copy link
Collaborator

alessfg commented Apr 27, 2020

Funnily enough, I'm currently working on ways to improve how templating works in the role. It's been a very slow process (I have rather limited bandwidth to dedicate to the role at the moment), but I think I've come up with an OK solution that'd address these issues. Hoping to have the changes live in a separate branch in a couple months max 😉

@StudioMaX
Copy link
Contributor

Any progress with this issue?

@alessfg
Copy link
Collaborator

alessfg commented Aug 10, 2020

Nope. There's still plans to go back to this in the "near" future, but a couple other tasks have taken priority.

@alessfg alessfg transferred this issue from nginxinc/ansible-role-nginx Aug 19, 2020
@alessfg alessfg added the enhancement Enhance an existing feature label Sep 2, 2020
@alessfg alessfg added this to To do in NGINX Configuration via automation Sep 2, 2020
@alessfg alessfg added this to the 0.3.3 milestone Jan 28, 2021
@alessfg alessfg added bug Something isn't working and removed enhancement Enhance an existing feature labels Jan 28, 2021
alessfg added a commit that referenced this issue Jan 28, 2021
NGINX Configuration automation moved this from To do to Done Jan 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Development

Successfully merging a pull request may close this issue.

6 participants