<div dir="ltr">Hi Angus,<div><br></div><div>Regarding this:</div><div><br></div><div>> <span style="font-size:12.8000001907349px">As Zane suggested, you should think of autoscaling as been in a different service.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">It's not that I can't see your point of view. </span><span style="font-size:12.8000001907349px">I can imagine an autoscaling service. I agree with you guys that if we had that, then none of this would be Heat's concern.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">When I think of this separate autoscaling service that can be used without Heat, I imagine that it provides a mechanism to update interested entities, such as (but not exclusively) load balancers when there is a scaling event, or actually any event of interest. So if we had autoscaling as a service running outside of Heat, we would not be talking about this problem. Heat would not refresh the ASG attributes and it would not know when the ASG resizes, but it wouldn't need to, because this imaginary service would have some way to talk to the load balancer or anybody else that wants to do stuff based on its state. I would probably not even create my load balancer as a heat resource in that situation, I would not need to.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">For such a service we would have a lightweight wrapper Heat resource that would take some inputs and invoke the service public APIs. This resource would not take a heat sub-resource or nested stack as the scaled entity, since that service runs outside of Heat and manages its own pool of scaled entities. The wrapper resource would probably not expose the pool size, or any properties of the scaled entities, because none of this would be in heat's domain. Even if you had that information, it would not be of much use within a stack. The ASG becomes sort of a black box, like other openstack native resources. This would be nice because it moves the notification problem to a dedicated service where it can be best addressed.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">So I do get what you are saying. But looking at things that way does not help solve my problem. LBAAS isn't widely deployed, and the OS::Heat::ASG lacks a good notification mechanism, so I'm still left with the same choices, which are to either build my own notifications (using a custom resource or maybe polling the API from the lb instance), or else not use Heat's ASG and instead build my own autoscaler.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">I know you guys don't like the AWS autoscaling mechanism, I agree that it isn't a well thought out design, but I can't ignore its one good quality: it works.</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">Anyway, I ended up writing yet another long email. :)</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div>I'll let you guys know if I come up with any other ideas that don't disagree with the original design you envisioned for the ASG. Thanks for spending the time discussing this, it was a really useful discussion.</div><div><br></div><div>Regards,</div><div><br></div><div>Miguel</div><div><span style="font-size:12.8000001907349px"><br></span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 8, 2015 at 6:21 PM, Angus Salkeld <span dir="ltr"><<a href="mailto:asalkeld@mirantis.com" target="_blank">asalkeld@mirantis.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Thu, Apr 9, 2015 at 8:03 AM, Miguel Grinberg <span dir="ltr"><<a href="mailto:miguel.s.grinberg@gmail.com" target="_blank">miguel.s.grinberg@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Zane, replies inline.<div><div class="gmail_extra"><br><div class="gmail_quote"><span>On Wed, Apr 8, 2015 at 3:46 PM, Zane Bitter <span dir="ltr"><<a href="mailto:zbitter@redhat.com" target="_blank">zbitter@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>On 07/04/15 22:02, Miguel Grinberg wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Hi,<br>
<br>
The OS::Heat::AutoScalingGroup resource is somewhat limited at this<br>
time, because when a scaling even occurs it does not notify dependent<br>
resources, such as a load balancer, that the pool of instances has changed.<br>
</blockquote>
<br></span>
As Thomas mentioned, the 'approved' way to solve this is to make your scaled unit a stack, and include a Neutron PoolMember resource in it.</blockquote><div><br></div></span><div>LBAAS is an optional, now even external component, not part of the Neutron API. Many installations don't have it. Allowing the use of custom load balancers is a desirable option, in my opinion, more so while LBAAS is not core neutron functionality.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
The AWS::AutoScaling::<u></u>AutoScalingGroup resource, on the other side, has<br>
a LoadBalancerNames property that takes a list of<br>
AWS::ElasticLoadBalancing::<u></u>LoadBalancer resources that get updated<br>
anytime the size of the ASG changes.<br>
</blockquote>
<br></span>
Which is an appalling hack.<br>
<br></blockquote></span><div>Yes. This is hacky, but it seems it models the AWS load balancing APIs, so there isn't much that can be done here, right?</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
(If it called the Neutron LBaaS API, like the equivalent in CloudFormation does with ELB, it would be OK. But in reality, as you know, it's a hack that makes calls directly to another resource plugin within Heat.)<span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I'm trying to implement this notification mechanism for HOT templates,<br>
but there are a few aspects that I hope to do better.<br>
<br>
1. A HOT template can have get_attr function calls that invoke<br>
attributes of the ASG. None of these update when the ASG resizes at this<br>
time, a scaling even does a partial update that only affects the ASG<br>
resource. I would like to address this.<br>
</blockquote>
<br></span>
In the medium-term I think this is something that I believe Convergence will be able to solve for us. I'm not sure that it's worth putting in a short-term work-around for.</blockquote><div><br></div></span><div>Here is where we disagree. In my opinion this is broken functionality. After a scaling event there are resources that go stale because they are never told that the ASG resized. This to me is clearly a bug that deserves fixing, even if in the future a better/nicer fix can be crafted.</div></div></div></div></div></blockquote><div><br></div></div></div><div>So the problem is the result of get_attr is dynamic and we do not support triggering stack updates on changes to their results.</div><div><br></div><div>As Zane suggested, you should think of autoscaling as been in a different service.</div><div><br></div><div>A possible solution:</div><div>You have a top level template that has an StackUpdatePolicy (a new thing), and it gets triggered by a Ceilometer Alarm based</div><div>on the following notification:</div><div><a href="https://github.com/openstack/heat/blob/master/heat/engine/resources/aws/autoscaling/autoscaling_group.py#L338-L344" target="_blank">https://github.com/openstack/heat/blob/master/heat/engine/resources/aws/autoscaling/autoscaling_group.py#L338-L344</a><br></div><div><br></div><div>This then runs an update to refresh the stack.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-Angus</div></font></span><div><div class="h5"><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div class="gmail_extra"><div class="gmail_quote"><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
2. The AWS solution relies on the well known LoadBalancer resource, but<br>
often load balancers are just regular instances that get loaded with a<br>
load balancer such as haproxy in a custom way. I'd like custom load<br>
balancers to also update when the ASG resizes.<br>
</blockquote>
<br></span>
TBH the correct answer for load balancers specifically is use the Neutron LBaaS API, end of story.</blockquote><div><br></div></span><div>This does not help me, as I don't have LBAAS. But as a said above, even if I had it, I may want to use my own load balancer, why not let me use my own if that is what I need for my project? Or what if I had another resource type that is not a load balancer, maybe a custom resource from a plugin that wants to be notified when the ASG resizes? If this can be done for regular stack updates, my opinion is that it should also work for these special signal-triggered updates to the ASG.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> But you're right that there are many uses for a more generic notification mechanism. (For example, in OpenShift we need to notify the controller when we add or remove nodes.) The design goal for ASG was always that we would have an arbitrary scaled unit (defined by a template) and an arbitrary non-scaled unit that could receive notifications about changes to the scaling group. So far we have delivered on only the first part of that promise.<br>
<br>
My vision for the second part has always been that we'd use hooks, the initial implementation of which Tomas has landed in Kilo. We'll need to implement some more hook types to do it - post-create, post-update and pre-delete at a minimum. We also need some way of notifying the user asynchronously about when the hooks are triggered, so that they can take whatever action (e.g. add to load balancer) before calling the API to clear the hook. (At the moment the only way to find out when your hook should run is by polling the Heat API.)<br></blockquote><div><br></div></span><div>I'm not really sure I understand how this would work. If I have a resource that sets one of its properties to { get_attr: [my_asg, size] }, then on a stack-update I don't need a hook to update my resource, it automatically updates. On an alarm triggered resize it will not, only because the update is partial in that case. If I add a post-update hook to that, then I may be able to get the resource to update on a resize event, but on a regular stack-update now the update will happen twice, once due to the normal update process, then again with the hook.</div><div><br></div><div>To make this work I would have to not use get_attr, and somehow get this resource to obtain whatever attribute it needs from the ASG using some other way, like maybe the Heat API. Which is all fine, but get_attr is a valid option I have as a stack developer, and it is currently broken.</div><div><br></div><div>I know you disagree with my view, but in my opinion the problem, as I mentioned before, is that the resize event of the ASG does a partial update, which leaves the stack in an inconsistent state.</div><span><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
In my ideal world, the notification mechanism (or at least one of them) is a message to a Zaqar queue/topic (whatever you want to call it) specified by the user. So someone e.g. running their own HAProxy (don't do this ;) could put a little micro-daemon on the same box that listened to Zaqar for notifications and update the HAProxy config appropriately.<br>
<br>
Also in my ideal world, a Mistral workflow could be triggered (and seeded with parameter values) by the exact same message queue, so that the user can run any action that Mistral can support without having to have a server around to run it. And we'd use the same system for e.g. Ceilometer alarms talking to scaling policies, so that one could also insert a Mistral workflow into the process. Things are actually pretty awesome in my ideal world.</blockquote><div><br></div></span><div>I really have no objection to this, sounds pretty good and I would likely use it when it is available. But this is future looking, and I'm trying to address a very specific problem in current releases.</div><span><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
The ResourceGroup is an interesting resource. It is much simpler than<br>
the ASG. In particular, the only way to scale the ResourceGroup is by<br>
issuing a stack-update with a new size. This indirectly solves #1 and #2<br>
above, because when a full update is issued any references to the<br>
ResourceGroup get updated as well.<br>
</blockquote>
<br></span>
It doesn't really solve the problem, because you could still manually update the nested stack that the ResourceGroup manages. It just entirely lacks the feature that makes it easy to run in to the problem. And not in a good way.<span><br>
<br></span></blockquote><div><br></div></span><div>Not sure I understand this. You have a list of nested stacks, as many as the size property of the resource group dictates. You can update them and that's fine. I guess you can delete one and that is probably not fine, in the same way you can delete instances from the ASG pool without the ASG resource knowing, or actually modify or delete any native entities without the heat resource that owns it knowing. That still does not cancel the fact that if you play by the rules, the ResourceGroup is much more reliable than the ASG because it can only be updated in a stack-update operation.</div><span><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
In my opinion, the best way to address #1 and #2 above so that they work<br>
for the ASG as they work for the RG, is to change what happens when<br>
there is a scaling event. When the ScalingPolicy resource gets a signal,<br>
it reaches directly to the ASG by calling asg.adjust() (or in the near<br>
future by sending a signal to it, when a currently proposed patch<br>
merges) with the new size. This bypasses the update mechanism, so only a<br>
partial update occurs, just the ASG resource itself is updated. I would<br>
like this to be a full stack update, so that all references get updated<br>
with the new ASG size. This will address #1 and #2.<br>
</blockquote>
<br></span>
-1<br></blockquote><div><br></div></span><div>This I disagree with. The partial update leaves the stack in an inconsistent state. It's a bug that should be straightforward to fix, without altering any plans for the future that can make the use of load balancers more friendly to users.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
The way to think about autoscaling is as a separate service that delegates the creation and deletion of its members to and maintains its state in a Heat stack. It *isn't* of course, but nor will it ever be if people continue to think about it as a resource plugin that is free to reach in to its parent stack and start messing with other things.<br>
<br>
Apart from being a layering violation, anything that relies on updating the parent stack *after* a scaling operation is complete simply doesn't work. When scaling down, you want the changes to be made *before* updating the scaling group. In the general case - a batched rolling update - there are multiple changes that need to be made mostly *during* the scaling group update.<span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
But there is an alternative to this. I guess we could copy the update<br>
mechanism used on the AWS side, which is also partial, but at least<br>
</blockquote>
<br></span>
-2! This is what we most wanted to avoid in the native resources.</blockquote><div><br></div></span><div>I'm fine with this, I don't really like the solution myself that much.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
covers the load balancers, given in the LoadBalancerNames property. We<br>
can have a "load_balancer_names" equivalent property for the<br>
OS::Heat::ASG resource, and we can then trigger the updates of the load<br>
balancer(s) exactly like the AWS side does it. For this option, I would<br>
like to extend the load balancer update mechanism to work on custom load<br>
balancers, as it currently works with the well known load balancer<br>
resources. I have implemented this approach and is currently up for<br>
review: <a href="https://review.openstack.org/#/c/170634/" target="_blank">https://review.openstack.org/#<u></u>/c/170634/</a>. I honestly prefer the<br>
full update, seems cleaner to me.<br>
<br>
Anyway, sorry for the long email. If you can provide guidance on which<br>
of the approaches are preferred, or if you have other ideas, I would<br>
appreciate it.<br>
</blockquote>
<br></span>
Long emails are good, thanks for writing this up :)<br>
<br>
cheers,<br>
Zane.<div><div><br>
<br>
______________________________<u></u>______________________________<u></u>______________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.<u></u>openstack.org?subject:<u></u>unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/<u></u>cgi-bin/mailman/listinfo/<u></u>openstack-dev</a><br>
</div></div></blockquote></span></div><br></div></div></div>
<br>__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br></blockquote></div></div></div><br></div></div>
<br>__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
<br></blockquote></div><br></div>