[openstack-dev] [Heat] [TripleO] Better handling of lists in Heat - a proposal to add a map function
Zane Bitter
zbitter at redhat.com
Fri Apr 4 18:56:29 UTC 2014
On 19/02/14 02:48, Clint Byrum wrote:
> Since picking up Heat and trying to think about how to express clusters
> of things, I've been troubled by how poorly the CFN language supports
> using lists. There has always been the Fn::Select function for
> dereferencing arrays and maps, and recently we added a nice enhancement
> to HOT to allow referencing these directly in get_attr and get_param.
>
> However, this does not help us when we want to do something with all of
> the members of a list.
>
> In many applications I suspect the template authors will want to do what
> we want to do now in TripleO. We have a list of identical servers and
> we'd like to fetch the same attribute from them all, join it with other
> attributes, and return that as a string.
>
> The specific case is that we need to have all of the hosts in a cluster
> of machines addressable in /etc/hosts (please, Designate, save us,
> eventually. ;). The way to do this if we had just explicit resources
> named NovaCompute0, NovaCompute1, would be:
>
> str_join:
> - "\n"
> - - str_join:
> - ' '
> - get_attr:
> - NovaCompute0
> - networks.ctlplane.0
> - get_attr:
> - NovaCompute0
> - name
> - str_join:
> - ' '
> - get_attr:
> - NovaCompute1
> - networks.ctplane.0
> - get_attr:
> - NovaCompute1
> - name
>
> Now, what I'd really like to do is this:
>
> map:
> - str_join:
> - "\n"
> - - str_join:
> - ' '
> - get_attr:
> - "$1"
> - networks.ctlplane.0
> - get_attr:
> - "$1"
> - name
> - - NovaCompute0
> - NovaCompute1
>
> This would be helpful for the instances of resource groups too, as we
> can make sure they return a list. The above then becomes:
>
>
> map:
> - str_join:
> - "\n"
> - - str_join:
> - ' '
> - get_attr:
> - "$1"
> - networks.ctlplane.0
> - get_attr:
> - "$1"
> - name
> - get_attr:
> - NovaComputeGroup
> - member_resources
>
> Thoughts on this idea? I will throw together an implementation soon but
> wanted to get this idea out there into the hive mind ASAP.
Apparently I read this at the time, but completely forgot about it.
Sorry about that! Since it has come up again in the context of the
"TripleO Heat templates and merge.py" thread, allow me to contribute my 2c.
Without expressing an opinion on this proposal specifically, consensus
within the Heat core team has been heavily -1 on any sort of for-each
functionality. I'm happy to have the debate again (and TBH I don't
really know what the right answer is), but I wouldn't consider the lack
of comment on this as a reliable indicator of lazy consensus in favour;
equivalent proposals have been considered and rejected on multiple
occasions.
Since it looks like TripleO will soon be able to move over to using
AutoscalingGroups (or ResourceGroups, or something) for groups of
similar servers, maybe we could consider baking this functionality into
Autoscaling groups instead of as an intrinsic function.
For example, when you do get_attr on an autoscaling resource it could
fetch the corresponding attribute from each member of the group and
return them as a list. (It might be wise to prepend "Output." or
something similar - maybe "Members." - to the attribute names, as
AWS::CloudFormation::Stack does, so that attributes of the autoscaling
group itself can remain in a separate namespace.)
Since members of your NovaComputeGroup will be nested stacks anyway
(using ResourceGroup or some equivalent feature - preferably autoscaling
with rolling updates), in the case above you'd define in the scaled
template:
outputs:
hosts_entry:
description: An /etc/hosts entry for the NovaComputeServer
value:
- str_join:
- ' '
- - get_attr:
- NovaComputeServer
- networks
- ctlplane
- 0
- get_attr:
- NovaComputeServer
- name
And then in the main template (containing the autoscaling group):
str_join:
- "\n"
- get_attr:
- NovaComputeGroup
- Members.hosts_entry
would give the same output as your example would.
IMHO we should do something like this regardless of whether it solves
your use case, because it's fairly easy, requires no changes to the
template format, and users have been asking for ways to access e.g. a
list of IP addresses from a scaling group. That said, it seems very
likely that making the other changes required for TripleO to get rid of
merge.py (i.e. switching to scaling groups of templates instead of by
multiplying resources in templates) will make this a viable solution for
TripleO's use case as well.
cheers,
Zane.
More information about the OpenStack-dev
mailing list