Azure License Manager (ALM) is as licensable module in the EmpowerID Suite that is designed to help organizations inventory their Azure licenses and expenses across multiple Azure tenants for cost reporting and allocation of license expenses to the different business areas of the organization. To understand how Azure Licensing Manager can help your organization with the costs associated with Azure licenses, it is helpful to review how Azure provides it licensing.
For each Azure tenant, there exists one Azure Active Directory and in that Active Directory you can enable various Microsoft products to license them. Each product includes one or more Service Plans, which are the components or the services that are offered in that product, such as Office 365 Enterprise E3, Visio and Project. So if your organization chooses to subscribe to Office Enterprise E3 for your tenant, that product becomes a subscription with a specified number of licensed users with a per user per month cost.
Azure Licensing Challenges
There are multiple challenges with managing license distribution and license reporting for organizations using Microsoft Office 365 and Azure. One key challenge is that when you subscribe to licenses with Azure and Office 365, you can only subscribe once. For large organizations with multiple departments or business units using these licenses, there’s no way to determine how many licenses are being consumed by each of those units; nor is there a way to grant responsibility to groups in the organization for managing who gets licenses, who can approve license assignments and how much of the organization’s license budget is being consumed by various portions of the company.
The below example illustrates how the challenges with determining how much licensing costs are being consumed by the various units of an organization. As can be seen, there exists a company consisting of a headquarters department with two business units, one located in Germany and another located in the United States. The company has one Azure subscription for Office 365 Enterprise E3 and one subscription for Visio Online Plan 1. In the case of Office 365 Enterprise E3, there are 10,000 users at a list price of $20 per month, which is an annual expense of $2,400,000. Some of these licenses would be consumed by users in Germany, some would be consumed by users in the United States, and some would be consumed by users in the headquarters location. The question becomes, How many licenses are being consumed by each unit and how are those licenses being managed? With native Office 365 features, there’s no real way to allocate the responsibility or to portion off those licenses to each of these business units and to report on how much they’re spending or to allow them to manage their own license assignments. Azure Licensing Manager allows organizations to answer these questions.
How Does Azure Licensing Manager Help?
EmpowerID provides a very flexible cost and responsibility allocation mechanism within Azure License Manager called "license pools and bundles." License pools and bundles allow you to break up your subscriptions to match your logical organization structure. The below image shows how the license pools can be assigned to owners.
License Pools and Bundles
In the above example, there exists a company consisting of a headquarters department with two business units, one located in Germany and another located in the United States. Germany and the United States each have a license pool with a number of subscription licenses and a license pool owner. License pools are simply containers of licensing for reporting purposes. This allows costs to be allocated based on the license pools. Licenses are allocated to a license pool by creating “license bundles,” which can be mapped to only one subscription with a specified number user accounts. The organization can now see how many licenses are being consumed by which unit and allocate the costs to those respective units.
License bundles are really the object that makes it all possible. They're the policy object to which a subscription is being granted to end users. And that license bundle is mapped to which group will fulfill it. Each license bundle creates a single Azure subscription and pushes the resultant assignees into a single Azure AD group. License bundles are the assignable policy object. License bundles can be assigned to any EmpowerID actor type, including users, groups, Management Roles, Business Roles, etc. in EmpowerID, and they'll end up delivering that resulting Azure AD user a license in a subscription by putting them in an Azure AD group in that tenant that is mapped to a license.
License Bundle Eligibility
So license bundle assignees are about who will automatically receive the license. Any of those assignees will be automatically added to the license fulfillment queue and pushed into the mapped license bundle group in Azure AD to give them that license. Now you can also configure who should be eligible to receive a license bundle, so you might have many license bundles again broken down to match your organizational structure. So we have our license bundles in our pool in Germany. We have a license bundles and a pool in the United States. We've even maybe further broken those down the standard employee license bundle in Germany versus the intern license bundle. So we want control that if users are shopping for licenses, we don't want them to see license bundles that aren't really meant for them. So if I'm an intern in Germany, I should only see the Internet bundle if it wasn't automatically assigned to me or if maybe we have project or optional Microsoft products, we don't want those advertised to everyone, only to those individuals who could request them. So license bundle eligibility uses the same idea as the assignees where you can map out who should be eligible to receive a license, who should be excluded from that list and not be eligible. And then the engine calculates the result in eligibility. So eligibility is really a way to advertise specific licenses to the right people so that end users are not overwhelmed. They don't see too many licenses of the same type. And they they're not presented with options that they are not allowed to request. So you're advertising to these audiences which license bundles are relevant and requestable by them.
License Fulfillment Flow
License fulfillment is the process of taking the policies in EmpowerID about who should have which license bundles, and then making those changes out into your Azure tenant, adding those resulting users, Azure AD users, to the appropriate license groups, which are matched to each of those bundles. So again, we talked about EmpowerID calculating the resultant assignees for a license bundle, which takes all the assignees minus exclusions.
Now there's a job in EmpowerID we discussed called the "License Pool Compiler" and it is what looks at the resultant assignees for each license bundle. It also looks at the inventory data about who already has a license via a license group - so who's already in these license groups. It looks at this in the "GroupAccountLicensePoolServiceBundle" table. That's really what says which groups contain, which user accounts because of which license bundles. And it looks at that. It says, OK. The resultant assignees should be this. But these are the users that have this group membership already.
So, we can calculate the delta. And it adds those delta entries about which users need to be added and which users should be removed because they're not allowed to have that license bundle anymore. It adds, as is entries to the License Fulfillment Queue, which is stored in a table known as the "AZLicensePoolServiceBundlePersonChangeInbox." So, you might hear referred to as the license inbox. It's an inbox where items are added into the inbox for processing, additions of users to license groups and removals for users from license groups.
Now another job is monitoring this queue and grabbing them in batches for high volume processing. And it's called the "LicensePoolChangeInboxProcessor." So, it processes these inbox entries by grabbing them, calling out to the EmpowerID Azure AD SCIM App service in your tenant and making the call to add or remove users to and from the appropriate license groups. So, this is really the end-to-end of how that license fulfillment flow works.
Components of Azure Licensing Manager
Azure License Manager is an enterprise-scale, high-security product that can be run on premise or as Software-as-a-Service run by EmpowerID as Web and Application Server containers in the cloud or on premise. As shown below, it is comprised of components common to all EmpowerID connectors with several that are specific to the module. A high-level description of these components follows.
EmpowerID Azure AD SCIM App Service
EmpowerID provides a workflow that allows you to publish an App Service, known as the “EmpowerID Azure AD SCIM App Service,” to a connected Azure system. The EmpowerID Azure Active Directory SCIM App Service is a SCIM compliant REST API that you publish to Azure in order to inventory so that EmpowerID to interface with and communicate to your Azure Active Directory in order to inventory data about the users, groups and license assignments in those tenants. The app service is configured for Azure AD authentication and uses a managed identity (service principal) to communicate with the Graph API to perform actions in the tenant. These actions include tasks like retrieving license information and assigning and removing users to and from license groups.
EmpowerID Jobs
EmpowerID consists of a large number of jobs for very granular processing of different items such as inventory information, attribute flow, group membership, account lockout detection and even license assignment changes and stores that information in its SQL database or Identity Warehouse. Jobs can run across multiple servers in parallel to support even the largest environments. The key jobs for Azure License Manager include the following:
Job | Purpose of Job |
---|---|
Inventory | This job is responsible for inventorying the users, groups, group memberships, attributes and other information in Azure Active Directory. It uses the Azure AD SCIM Microservice App Service mentioned above to retrieve this information. |
Inventory Inbox | This job claims and processes all the data contained in the AzureJSONInbox table in EmpowerID. This table is populated during inventory and stores inventoried information for all Azure-specific information such as license subscriptions, RBAC entities such as management groups, and information about license assignments. The job has two steps:
|
License Pool Compiler | This job processes each enabled license pool based on the schedule set for that license pool. It evaluates the assignments and the exclusions and compiles the resultant assignments of who should have that license bundle. This then results in creating entries in the license fulfillment queue, also known as the license inbox, to add or remove user accounts from Azure AD license groups that are mapped to each license bundle. It calculates the result of who should have that license bundle versus who is currently in that license group because of the license bundle and puts entries in the license fulfillment queue for who should be added to and who should be removed from a particular license bundle. |
License Pool Change Inbox Processor | This job reads the entries placed in the license fulfillment queue by the License Pool Compiler and connects to the Azure AD SCIM microservice to process those entries in your tenants, adding or removing users to and from license groups. |
Identity Warehouse
The EmpowerID Identity Warehouse is comprised of a large number of tables for storing and maintaining information about each connected resource system and the objects in those systems, including those within the EmpowerID system itself. These tables are differentiated by resource type and have records corresponding to both inventoried and non-inventoried objects alike. For Azure AD, some examples of the former include the Azure_AccountLicense, Azure_GroupLicense, and Azure_ManagedIdentity tables, while examples of the latter include the OrgRole, OrgZone, and Person tables (these tables correspond to unique objects created in EmpowerID). When EmpowerID inventories an account store like Azure AD, it writes all resource objects in those systems—and the important attributes of those objects—to the appropriate table in the Identity Warehouse, adding the attributes of those objects as column values. In this way, user accounts are added to the Account table, account stores are added to the AccountStore table, Office 365 subscriptions are written to the Office365Subscription table, accounts belonging to an Office 365 subscription to the Office365SubscriptionAccount table, and so on.
Inventoried Data
The below image presents a high-level overview of how EmpowerID stores and gathers the inventory data it retrieves when connected to Azure.
On the right side of the image, we see our Azure tenant and on the left we see our EmpowerID instance—whether it's on premise or a SaaS instance. EmpowerID is running as Web and Application Server containers hosting inventory jobs that pull the data from Azure and stores it in the appropriate tables of the Identity Warehouse. Users from Azure Active Directory are stored in the Accounts table, groups in the Group table, and the products to which the tenant has subscribed in the AZLocalServiceBundle table. Additionally, detailed information about which users or groups are assigned to which of these subscriptions, as well as which of product features of the service plans are enabled or disabled on each of these assignments is stored in the AZAssigneeLocalServiceBundleService table. While the image shows just a few of the tables, it allows you to see the overall flow of how EmpowerID could securely communicate to an Azure App service running in your tenant, using a managed identity to talk to the Graph API to retrieve this information and to store it in the identity warehouse.
When EmpowerID inventories Azure AD, it creates an account in the EmpowerID Identity Warehouse for each Azure AD user account, a group for each Azure AD group, assigns group memberships to users based on their group memberships in Azure. Imported user information can be managed and synchronized with data in any connected back-end user directories.
Once connected, you can manage this data from EmpowerID in the following ways:
Account Management
Inventory Azure AD user accounts
Create, Update and Delete Azure AD user accounts
Enable and Disable Azure AD user accounts
Update passwords for Azure AD user accounts
Group Management
Inventory Azure AD groups
Inventory Azure AD group memberships
Create and Delete Azure AD groups
Add and Remove members to and from Azure AD groups
Attribute Flow
Users in Azure AD are inventoried as accounts in EmpowerID, which are then linked EmpowerID Person objects. The below table shows the attribute mappings of Azure AD user attributes to EmpowerID Person attributes.
Azure AD Attribute | Corresponding EmpowerID Attribute | Description |
---|---|---|
Name | Name | Name of the user |
name.familyName | LastName | Last name of the user |
name.givenName | FirstName | First name of the user |
name.middleName | MiddleName | Middle name of the user |
displayName | FriendlyName | Display Name of the user |
name.honorificSuffix | GenerationalSuffix |
|
title | Title | Title of the user |
email[?(@type=='work')].value | Work email address of the user | |
['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'].['department'] | Department | Department of the user |
['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'].['EmployeeNumber'] | EmployeeID | Employee ID of the user |
addresses[?(@.type=='work')].streetAddress | StreetAddress | Street address of the user |
addresses[?(@.type=='work')].locality | City | City in which the user resides or works |
addresses[?(@.type=='work')].region | State | State in which the user resides or works |
addresses[?(@.type=='work')].country | Country | Country of the user |
addresses[?(@.type=='work')].postalCode | PostalCode | Postal code of the user |
phoneNumbers[?(@.type=='home')].value | HomeTelephone | Home telephone of the user |
preferredLanguage | PreferredLanguage | Preferred language of the user |
phoneNumbers[?(@.type=='other')].value | Telephone | Telephone number for the person |
phoneNumbers[?(@.type=='fax')].value | Fax | Fax number for the person |