Intelligent cloud scaling with Cloudify
using nested scaling groups and policiesThere are times when scaling an application or service is not as simple as “spin up more instances” and Cloudify has some great features built into its engine to handle complex scaling cases.
The Microsoft Azure cloud presents customers wishing to scale services a few monkey wrenches. There’s performance limitations on how many instances / VMs can, or should, be run on a given storage account. No one wants to exhaust disk IOPS, right? So, let’s take a hypothetical scenario where a customer would only want, say, 50 instances per storage account in order to avoid IOPS exhaustion. Then, to layer on to this type of issue, let’s assume that customer only wants 5 storage accounts per resource group (for either tracking purposes or maybe some other Azure performance limitation unbeknownst to myself).
So, the problem of scaling is now a layered problem of scaling where some components must scale based on the scaling policy of another group. Cloudify nested scaling policies to the rescue!
Simple Scaling
Take the following example on the right of a classic scaling policy. This says “scale the group vms_and_ips up or down based on input”. All dependencies will be managed and new connections will be made automatically, which is why we’re all using Cloudify, right? So, if you set the delta to +1, you will get another VM and another IP address for it. Easy peasy. But, in the case of Azure, this would mean that scaling by a delta of +100 would place 100 new VMs into a single resource group connected to a single storage account. That’s not cool, man. So, we need a slightly more complicated scheme to handle our slightly more complex scaling ideas. See the next row.
groups: vms_and_ips: members: [host, host_nic, host_nic_ip_cfg] policies: scale_policy1: type: cloudify.policies.scaling properties: default_instances: 1 targets: [vms_and_ips]
groups: vms_and_ips: members: [host, host_nic, host_nic_ip_cfg] inner: members: [inner, storage_account] outer: members: [outer, resource_group] policies: vms_and_ips_scale: type: cloudify.policies.scaling properties: default_instances: { get_input: scale_vm_per_sa } targets: [vms_and_ips] inner_scale: type: cloudify.policies.scaling properties: default_instances: { get_input: scale_sa_per_rg } targets: [inner] outer_scale: type: cloudify.policies.scaling properties: default_instances: { get_input: scale_total_rg } targets: [outer]
Intelligent Scaling
Here, we have a set of nested scaling groups and scaling policies that achieve the desired effect. For some perspective, the “outer_scale” policy is the highest-level, most powerful scaling policy here and it is what controls the Azure resource groups. Scaling using this policy affects the other two policies inherently. The “inner_scale” policy controls the Azure storage accounts and other lower-level resources. The “vms_and_ips” policy is just like the previous example and is unaware of its higher-level policies that are going to control it.
So, we have our inputs setting the default instance counts. Let’s say we wanted that 1,000 count of VMs using our earlier model (4x resource groups, 5x storage accounts per resource group, 50x instance per storage account). We could set it up just like that using our inputs. Setting scale_vm_per_sa: 50, scale_sa_per_rg: 5, and scale_total_rg: 4 will get our result.