During AnsibleFest SF 2017 it was clear that the Declarative Intent functionality that was designed as part of needed ansible-network roadmap is flawed in a few areas.
This proposal does not question the merit of this needed functionality, but some design decisions require improvements before this is ready for wider consumption.
The implementation diffuses the configuration namespaces with the expectation declaration, which is going to be very confusing. Not just because some of these parameters are used elsewhere for configuration, but simply because everything is a top-level module parameter. This is bad user interface design. The remark that the documentation will make clear what parameters are part of the configuration declaration and what parameters are expectations does not make this acceptable.
So state here is an expected state of the interface, and tx_rate is the expected transmit rate, not and actual declarative configuration or even an intention as such. A better interface would be:
Declarative intent seems to indicate we are declaring our intentions. But that's not what it does, it declares expectations rather than intentions. If we look at the above examples the items listed are not (as documented) the "Intended state", but rather the "Expected state" an interface is in.
"Intended state" seems to imply it is something we can control, where "expected state" better describes what it is. An intention is something one contributes to, an expectation is something we consider getting back. So the functionality a misnomer in itself.
From the documentation:
Declarative intent modules also take a set of options that allow playbook designers to specify the desired or intended operational state of the resource. These options allow tasks to define the normalized operating state of the resource once the configuration has been completed. State options do not make configuration changes to the resource. They serve to validate that a given resource has normalized its operating environment to reflect the intended state. If the operating state does not reflect the intended (or desired) state of the resource as described in the playbook task, the module is considered failed and remediation actions can be taken in the playbook during the playbook execution.
There is another problem with doing both configuration and expectation checking in a single module. If one of both operations fail, how would we know if the configuration failed, or the expectations were not met. And should a failed expectation be a module failure or not ? I can see different use-cases for testing expectations and as such, it would be more versatile of expectations would be handle by special tasks rather than being part of the existing modules.
Or maybe the core Ansible product should understand the difference between config and expectation and could be told to either ignore/warn on expectation failures, or have a different failure path. Rather than diffuse the handling of the module intrinsically. Maybe you don't want to run expectation tests in some runs (e.g. production updates), but you want them in other runs (like integration tests, or compliance testing).
This functionality is useful in a wider context than just networking, so this should have been discussed with use-cases outside of networking only. And this maps with the existing assert module and registering the return values. If we agree that doing a validation check as part of the call, we could leave this up to Ansible core to do the test (and take the appropriate action):
This then would make writing integration tests easier, and ensures that other modules would automatically have this functionality without requiring any special modifications. This is a much stronger use-case than the original implementation.
Problems
What problems exist that this proposal will solve?
Releasing and documenting this as-is (with the known problems), will make a future implementation harder to get right and requires backward compatibility.
Solution proposal
Redesign this functionality with other use-cases in mind
Redesign this with all stakeholders involved
Redesign this with regard to good user interface design
Documentation (optional)
Hold off with documenting and promoting this as part of v2.4, so we don't have to support this going forward in light of a user-breaking redesign.
Anything else?
The above feedback was provided during the AnsibleFest SF 2017 Network Working Group and was largely unanimous by participants.
This proposal was made to collect feedback from other participants in order to design a better user interface for this functionality before it becomes a wider standard.
Proposal: Redesign Declarative Intent
Author: Dag Wieers <@dagwieers> IRC: dag
Date: 2017/09/15
Motivation
During AnsibleFest SF 2017 it was clear that the Declarative Intent functionality that was designed as part of needed ansible-network roadmap is flawed in a few areas.
This proposal does not question the merit of this needed functionality, but some design decisions require improvements before this is ready for wider consumption.
The implementation diffuses the configuration namespaces with the expectation declaration, which is going to be very confusing. Not just because some of these parameters are used elsewhere for configuration, but simply because everything is a top-level module parameter. This is bad user interface design. The remark that the documentation will make clear what parameters are part of the configuration declaration and what parameters are expectations does not make this acceptable.
The example from the documentation:
So state here is an expected state of the interface, and tx_rate is the expected transmit rate, not and actual declarative configuration or even an intention as such. A better interface would be:
Declarative intent seems to indicate we are declaring our intentions. But that's not what it does, it declares expectations rather than intentions. If we look at the above examples the items listed are not (as documented) the "Intended state", but rather the "Expected state" an interface is in.
"Intended state" seems to imply it is something we can control, where "expected state" better describes what it is. An intention is something one contributes to, an expectation is something we consider getting back. So the functionality a misnomer in itself.
From the documentation:
There is another problem with doing both configuration and expectation checking in a single module. If one of both operations fail, how would we know if the configuration failed, or the expectations were not met. And should a failed expectation be a module failure or not ? I can see different use-cases for testing expectations and as such, it would be more versatile of expectations would be handle by special tasks rather than being part of the existing modules.
Or maybe the core Ansible product should understand the difference between config and expectation and could be told to either ignore/warn on expectation failures, or have a different failure path. Rather than diffuse the handling of the module intrinsically. Maybe you don't want to run expectation tests in some runs (e.g. production updates), but you want them in other runs (like integration tests, or compliance testing).
This functionality is useful in a wider context than just networking, so this should have been discussed with use-cases outside of networking only. And this maps with the existing assert module and registering the return values. If we agree that doing a validation check as part of the call, we could leave this up to Ansible core to do the test (and take the appropriate action):
This then would make writing integration tests easier, and ensures that other modules would automatically have this functionality without requiring any special modifications. This is a much stronger use-case than the original implementation.
Problems
What problems exist that this proposal will solve?
Solution proposal
Documentation (optional)
Hold off with documenting and promoting this as part of v2.4, so we don't have to support this going forward in light of a user-breaking redesign.
Anything else?
The above feedback was provided during the AnsibleFest SF 2017 Network Working Group and was largely unanimous by participants.
This proposal was made to collect feedback from other participants in order to design a better user interface for this functionality before it becomes a wider standard.
Also collecting pros/cons for each solution in https://public.etherpad-mozilla.org/p/ansible-proposal-70 Please add your thoughts here and they will be rolled into this proposal doc by @gundalow