In the last chapter we saw how every virtual machine or instance provisioning request involves an approval process, and that requests for larger VMs would normally require administrative approval. Even with auto-approval thresholds set at their low defaults however, our users could still over time create a large number of small virtual machines, and consume our virtual infrastructure resources and increase cloud costs.
For this reason ManageIQ also allows us to establish quotas on tenants or user groups. Quotas can be set for number of virtual machines, number of CPUs, amount of memory, or quantity of storage 'owned' by the tenant or group. If a virtual machine provisioning request would result in the quota being exceeded, the request is rejected and the requesting user is emailed.
Quotas are not enabled by default with ManageIQ Capablanca, but they are simple to turn on and configure.
Quota management has been completely rewritten for ManageIQ Capablanca. Prior to this release, quota management for cloud instance, infrastructure virtual machine, and service provisioning was handled in different places under the respective /Cloud, /Infrastructure, and /Service namespaces. In Capablanca these have been consolidated these under /System/CommonMethods in the Automate Datastore. (see Quota classes, instances and methods).
The ManageIQ/System/CommonMethods/QuotaStateMachine/quota state machine instance has the field values shown in Schema of the quota state machine.
We can see that quota processing follows a simple workflow of:
-
Determine the quota source
-
Determine the quota limits assigned to that source
-
Determine the resources currently used by that source
-
Determine the new resources requested by the source
-
Validate whether the new requested amount would exceed quota
A new concept with the re-implemented quota management mechanism is that of quota source. This is the entity to which the quota is applied, and by default is a tenant. Tenant quotas can be edited in the WebUI under Configure → Configuration → Access Control → Tenants → tenant (see Setting quotas for a tenant).
The tenant object keeps track of allocated values in virtual columns:
--- virtual columns follow --- $evm.root['tenant'].allocated_memory = 48318382080 (type: Fixnum) $evm.root['tenant'].allocated_storage = 498216206336 (type: Fixnum) $evm.root['tenant'].allocated_vcpu = 23 (type: Fixnum) $evm.root['tenant'].provisioned_storage = 546534588416 (type: Fixnum)
If we wish to use an alternative quota source, we can copy the quota_source method to our own domain, and edit it to define $evm.root['quota_source'] and $evm.root['quota_source_type'] as required. This commented-out example shows how to define a group as the quota source, in which case quota handling is done in the pre-Capablanca way:
# Sample code to enable group as the default quota source.
$evm.root['quota_source'] = @miq_request.requester.current_group
$evm.root['quota_source_type'] = 'group’
When we use an alternative quota source, we can set quota in two ways.
We can set generic warn and max values for VM Count, Storage, CPU and Memory, by copying the ManageIQ/System/CommonMethods/QuotaStateMachine/quota instance into our Domain, and editing any of the eight schema attributes.
Quotas defined in the model in this way apply to all instances of the quota source (e.g. all groups)
We can override the default model attributes by applying tags from one or more of the following tag categories to individual quota source entities (e.g. individual groups):
Tag category name | Tag category display name | Pre-exists |
---|---|---|
quota_warn_vms |
Quota - Warn VMs |
No; must be created |
quota_max_vms |
Quota - Max VMs |
No; must be created |
quota_warn_storage |
Quota - Warn Storage |
No; must be created |
quota_max_storage |
Quota - Max Storage |
Yes |
quota_warn_cpu |
Quota - Warn CPUs |
No; must be created |
quota_max_cpu |
Quota - Max CPUs |
Yes |
quota_warn_memory |
Quota - Warn Memory |
No; must be created |
quota_max_memory |
Quota - Max Memory |
Yes |
If a group is tagged in such a way, then any VM or service provisioning request from any group member is matched against the currently allocated CPUs, memory or storage for the group.
If quotas are defined both in the model and with tags, the tagged value takes priority.
The quota checking process for a virtual machine or instance provision request is triggered by a request_starting event (see Event-triggered provision request quota workflow)
This event policy is handled by the /System/Policy/MiqProvisionRequest_starting policy instance, which has a single rel5 relationship that calls the /System/CommonMethods/QuotaStateMachine/quota state machine.
If the provisioning request would result in the quota being exceeded, then the request is rejected, and the requesting user is emailed through the /{Infrastructure,Cloud}/VM/Provisioning/Email/MiqProvisionRequest_Denied email class.
If the request is within the quota then the workflow simply exits.
Quotas allow us to maintain a degree of control over the depletion of our expensive virtualisation resources, while still empowering our users to create their own virtual machines or instances.
Quotas can be applied to access control groups or tenants. A quota allocated to a tenant can be further subdivided between any child tenants or tenant projects. For example we might have a tenant representing our application development team, and they might have tenant projects representing applications currently under development. We can allocate the EvmRole-tenant_quota_administrator access control role to a virtualisation administrator, who can then further sub-divide the development team’s quota between projects as requested.
When we apply quotas to access control groups, we can additionally tag the groups with warn and max threshold tags on a per-group basis to fine-tune the quota allocation.