[openstack-dev] 答复: [Heat] Re-evaluate conditions specification

Zane Bitter zbitter at redhat.com
Thu Mar 31 22:10:04 UTC 2016

On 31/03/16 10:10, Thomas Herve wrote:
> On Thu, Mar 31, 2016 at 2:25 PM, Huangtianhua <huangtianhua at huawei.com> wrote:
>> The conditions function has been requested for a long time, and there have been several previous discussions, which all ended up in debating the implementation, and no result.
>> https://review.openstack.org/#/c/84468/3/doc/source/template_guide/hot_spec.rst
>> https://review.openstack.org/#/c/153771/1/specs/kilo/resource-enabled-meta-property.rst

I wouldn't say no result, all of those discussions ended up moving in 
the direction of the variables thing that Thomas is suggesting here.

> And for a reason: this is a tricky issue, and introducing imperative
> constructs in a template can lead to bad practices.

Yes, the disagreement was largely over whether we should do it at all.

>> I think we should focus on the simplest possible way(same as AWS) to meet the user requirement, and follows the AWS, there is no doubt that we will get a very good compatibility.
>> And the patches are good in-progress. I don't want everything back to zero:)
>> https://review.openstack.org/#/q/status:open+project:openstack/heat+branch:master+topic:bp/support-conditions-function

I'm sympathetic to this. Happily, I don't think the change being 
proposed is even close to the level of 'back to zero' :)

> I don't say that you should scratch everything. I'm mostly OK with
> what has been done, with the exception of the top-level conditions
> section. Templates are our user interface, and we need to be very
> careful when we introduce new things. 3 years ago following AWS was
> the easy path because we didn't have much idea on what to do, but I
> believe we now have enough background to be more innovative.


I think looking at the cfn implementation has an unfortunate effect of 
making us look at a number of separate problems as if they were a 
single, monolithic one. The problems it solves are:

1) How to conditionally disable a resource
2) How to conditionally change data (e.g. properties) without requiring 
the user to input all of the data in a parameter
3) How to share the same condition in multiple resource without having 
to duplicate the condition logic
4) How to share the same condition for multiple pieces of data (or share 
between data and resources) without having to duplicate the condition logic

The solution cfn has is a "Conditions" section that contains the logic 
(3) & (4), a "Condition" on a resource that refers to an entry in the 
"Conditions" section (1) and a Fn::If intrinsic function that also 
refers to an entry in the "Conditions" section (2).

An obvious problem with (3)/(4) is that they eliminate the need for 
duplicating the condition logic in more than one place, but if you need 
the data that is selected by Fn::If in more than one place then you'll 
end up repeating _that_. Let's call this (5).

A solution using variables (I prefer "values" but I'm happy to bikeshed) 
instead of conditions would solve (2) and (5). (1) and (3) can obviously 
be solved by a "condition" in a resource that takes a value directly 
(instead of just a condition name).

Importantly, (4) can be achieved only if the get_variable function is 
allowed inside variable definitions, and that means we need to detect 
circular references. (That'd be a fun little programming problem for 
someone, but not a show-stopper.) You could argue that if you have (3) 
and (5) then (4) is not as important, since the condition in many cases 
might be just a parameter reference without any more complicated logic.

The reason (I speculate) that cfn went with the implementation they did, 
specifically having resource conditions contain the *name* of a 
condition variable rather than a value, is that they probably didn't 
want to have to parse the different parts of the resource definition 
differently. Specifically, the conditions must be resolved statically at 
therefore stuff like Fn::GetAtt are not valid. It's easy to explain a 
different section of the template where those are not valid, but much 
harder to explain that they're valid in some parts of the resource 
definition but not others.

We could get around this by calling the field condition_variable or 
something and having it contain a name of a variable rather than an 
explicit get_variable function, so that any conditions you want to write 
have to go into a variable, but not all variables would have to be 

I'm in favour of some sort of variable-based implementation for a few 
reasons. One is that (5) seems to come up fairly regularly in a complex 
deployment like TripleO. Another is that Fn::If feels awkward compared 
to get_variable.

But maybe the biggest one is that what we choose here is not only our 
public facing user-interface, as Thomas pointed out, but also the API 
interface against which people (including our future selves) can write 
their own template format plugins. The AWS solution can be trivially 
implemented in terms of the variable-based one; the reverse is not true.

This would make for a popcorn-worthy summit session ;)


More information about the OpenStack-dev mailing list