<div dir="ltr"><div><div>One more example how you may do it using yaql:<br><br>oleksii@oleksii:~$ cat example.yaml <br>heat_template_version: 2013-05-23<br><br>parameters:<br>  az_list:<br>    type: string<br></div><div>  count:<br></div><div>    type: number<br></div><div><br>resources:<br>  rg:<br>    type: OS::Heat::ResourceGroup<br>    properties:<br>      count: {get_param: count}<br>      resource_def:<br>        type: server.yaml<br>        properties:<br>          index: "%index%"<br>          availability_zones: {get_param: az_list}<br><br>oleksii@oleksii:~$ cat server.yaml <br>heat_template_version: 2013-05-23<br>parameters:<br>  availability_zones:<br>    type: comma_delimited_list<br>  index:<br>    type: string<br>resources:<br>  instance:<br>    type: OS::Nova::Server<br>    properties:<br>        availability_zone:<br>          yaql:<br>            expression: $.data.availability_zones[int($.data.index) mod $.data.availability_zones.len()]<br>            data:<br>              nova_flavors: {get_param: availability_zones}<br>              index: {get_param: index}<br>        flavor: m1.tiny<br>        image: cirros<br><br></div>For example, if count == 4 and az_list=[az1, az2] you will have instance1 in az1, instance2 in az2 and instance3 in az1, instance4 in az2.<br></div><br><div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 8, 2016 at 12:53 AM, Hongbin Lu <span dir="ltr"><<a href="mailto:hongbin.lu@huawei.com" target="_blank">hongbin.lu@huawei.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Heat team,<br>
<br>
A question inline.<br>
<br>
Best regards,<br>
Hongbin<br>
<div><div class="h5"><br>
> -----Original Message-----<br>
> From: Steven Hardy [mailto:<a href="mailto:shardy@redhat.com">shardy@redhat.com</a>]<br>
> Sent: March-03-16 3:57 AM<br>
> To: OpenStack Development Mailing List (not for usage questions)<br>
> Subject: Re: [openstack-dev] [magnum][heat] spawn a group of nodes on<br>
> different availability zones<br>
><br>
> On Wed, Mar 02, 2016 at 05:40:20PM -0500, Zane Bitter wrote:<br>
> > On 02/03/16 05:50, Mathieu Velten wrote:<br>
> > >Hi all,<br>
> > ><br>
> > >I am looking at a way to spawn nodes in different specified<br>
> > >availability zones when deploying a cluster with Magnum.<br>
> > ><br>
> > >Currently Magnum directly uses predefined Heat templates with Heat<br>
> > >parameters to handle configuration.<br>
> > >I tried to reach my goal by sticking to this model, however I<br>
> > >couldn't find a suitable Heat construct that would allow that.<br>
> > ><br>
> > >Here are the details of my investigation :<br>
> > >- OS::Heat::ResourceGroup doesn't allow to specify a list as a<br>
> > >variable that would be iterated over, so we would need one<br>
> > >ResourceGroup by AZ<br>
> > >- OS::Nova::ServerGroup only allows restriction at the hypervisor<br>
> > >level<br>
> > >- OS::Heat::InstanceGroup has an AZs parameter but it is marked<br>
> > >unimplemented , and is CFN specific.<br>
> > >- OS::Nova::HostAggregate only seems to allow adding some metadatas<br>
> > >to a group of hosts in a defined availability zone<br>
> > >- repeat function only works inside the properties section of a<br>
> > >resource and can't be used at the resource level itself, hence<br>
> > >something like that is not allowed :<br>
> > ><br>
> > >resources:<br>
> > >   repeat:<br>
> > >     for_each:<br>
> > >       <%az%>: { get_param: availability_zones }<br>
> > >     template:<br>
> > >       rg-<%az%>:<br>
> > >         type: OS::Heat::ResourceGroup<br>
> > >         properties:<br>
> > >           count: 2<br>
> > >           resource_def:<br>
> > >             type: hot_single_server.yaml<br>
> > >             properties:<br>
> > >               availability_zone: <%az%><br>
> > ><br>
> > ><br>
> > >The only possibility that I see is generating a ResourceGroup by AZ,<br>
> > >but it would induce some big changes in Magnum to handle<br>
> > >modification/generation of templates.<br>
> > ><br>
> > >Any ideas ?<br>
> ><br>
> > This is a long-standing missing feature in Heat. There are two<br>
> > blueprints for this (I'm not sure why):<br>
> ><br>
> > <a href="https://blueprints.launchpad.net/heat/+spec/autoscaling-" rel="noreferrer" target="_blank">https://blueprints.launchpad.net/heat/+spec/autoscaling-</a><br>
> availabilityzo<br>
> > nes-impl<br>
> > <a href="https://blueprints.launchpad.net/heat/+spec/implement-" rel="noreferrer" target="_blank">https://blueprints.launchpad.net/heat/+spec/implement-</a><br>
> autoscalinggroup<br>
> > -availabilityzones<br>
> ><br>
> > The latter had a spec with quite a lot of discussion:<br>
> ><br>
> > <a href="https://review.openstack.org/#/c/105907" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/105907</a><br>
> ><br>
> > And even an attempted implementation:<br>
> ><br>
> > <a href="https://review.openstack.org/#/c/116139/" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/116139/</a><br>
> ><br>
> > which was making some progress but is long out of date and would need<br>
> > serious work to rebase. The good news is that some of the changes I<br>
> > made in Liberty like <a href="https://review.openstack.org/#/c/213555/" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/213555/</a> should<br>
> > hopefully make it simpler.<br>
> ><br>
> > All of which is to say, if you want to help then I think it would be<br>
> > totally do-able to land support for this relatively early in Newton :)<br>
> ><br>
> ><br>
> > Failing that, the only think I can think to try is something I am<br>
> > pretty sure won't work: a ResourceGroup with something like:<br>
> ><br>
> >   availability_zone: {get_param: [AZ_map, "%i"]}<br>
> ><br>
> > where AZ_map looks something like {"0": "az-1", "1": "az-2", "2":<br>
> > "az-1", ...} and you're using the member index to pick out the AZ to<br>
> > use from the parameter. I don't think that works (if "%i" is resolved<br>
> > after get_param then it won't, and I suspect that's the case) but<br>
> it's<br>
> > worth a try if you need a solution in Mitaka.<br>
><br>
> Yeah, this won't work if you attempt to do the map/index lookup in the<br>
> top-level template where the ResourceGroup is defined, but it *does*<br>
> work if you pass both the map and the index into the nested stack, e.g<br>
> something like this (untested):<br>
><br>
> $ cat rg_az_map.yaml<br>
> heat_template_version: 2015-04-30<br>
><br>
> parameters:<br>
>   az_map:<br>
>     type: json<br>
>     default:<br>
>       '0': az1<br>
>       '1': az2<br>
><br>
> resources:<br>
>  AGroup:<br>
>     type: OS::Heat::ResourceGroup<br>
>     properties:<br>
>       count: 2<br>
>       resource_def:<br>
>         type: server_mapped_az.yaml<br>
>         properties:<br>
>           availability_zone_map: {get_param: az_map}<br>
>           index: '%index%'<br>
><br>
> $ cat server_mapped_az.yaml<br>
> heat_template_version: 2015-04-30<br>
><br>
> parameters:<br>
>   availability_zone_map:<br>
>     type: json<br>
>   index:<br>
>     type: string<br>
><br>
> resources:<br>
>  server:<br>
>     type: OS::Nova::Server<br>
>     properties:<br>
>       image: the_image<br>
>       flavor: m1.foo<br>
>       availability_zone: {get_param: [availability_zone_map, {get_param:<br>
> index}]}<br>
<br>
</div></div>This is nice. It seems to address our heterogeneity requirement at *deploy* time. However, I wonder what is the runtime behavior. For example, I deploy a stack by:<br>
$ heat stack-create -f rg_az_map.yaml -P az_map='{"0":"az1","1":"az2"}'<br>
<br>
Then, I want to remove a sever by:<br>
$ heat stack-update -f rg_az_map.yaml -P az_map='{"0":"az1"}'<br>
<br>
Will Heat remove resources in index "1" only (with resources in index "0" untouched)? Also, I wonder if we can dynamically add resources (with existing resources untouched). For example, add a server by:<br>
$ heat stack-update -f rg_az_map.yaml -P az_map='{"0":"az1","1":"az2","2":"az3"}'<br>
<br>
In addition, I want to point out that spreading the availability zones is not the only use case. Magnum has generic use cases to manage heterogeneous set of resources. For example:<br>
$ heat stack-create -f rg_az_map.yaml -P az_map='{"resource_gorup_1":{"availability_zone":"az1","count":"2","flavor":"m1.foo",...},"resource_gorup_2":{"availability_zone":"az2","count":"3","flavor":"m2.foo",...},...}"<br>
<br>
Is it a reasonable to expect Heat to support that?<br>
<span class="im HOEnZb"><br>
><br>
> FWIW we already use this technique in some TripleO templates, and it<br>
> works pretty well.<br>
><br>
</span><span class="im HOEnZb">> <a href="https://github.com/openstack/tripleo-heat-" rel="noreferrer" target="_blank">https://github.com/openstack/tripleo-heat-</a><br>
> templates/blob/master/network/ports/external_from_pool.yaml#L35<br>
><br>
> Steve<br>
><br>
> _______________________________________________________________________<br>
> ___<br>
</span><span class="im HOEnZb">> OpenStack Development Mailing List (not for usage questions)<br>
</span><span class="im HOEnZb">> Unsubscribe: OpenStack-dev-<br>
> <a href="http://request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">request@lists.openstack.org?subject:unsubscribe</a><br>
> <a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br>
</span><div class="HOEnZb"><div class="h5">__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</div></div></blockquote></div><br></div>