/// <summary>
        /// Specifies that applications running on the virtual machine requires the given access role
        /// with scope of access limited to the arm resource identified by the resource id specified
        /// in the scope parameter.
        /// </summary>
        /// <param name="scope">Scope of the access represented in arm resource id format.</param>
        /// <param name="asRole">Access role to assigned to the virtual machine.</param>
        /// <return>VirtualMachineMsiHelper.</return>
        ///GENMHASH:EFFF7ECD982913DB369E1EF1644031CB:9F5B63517E99FAB38D9622B261E856C1
        internal VirtualMachineMsiHelper WithRoleBasedAccessTo(string scope, BuiltInRole asRole)
        {
            this.requireSetup = true;
            string key = scope.ToLower() + "_" + asRole.ToString().ToLower();

            if (!this.rolesToAssign.ContainsKey(key))
            {
                this.rolesToAssign.Add(key, new System.Tuple <string, BuiltInRole>(scope, asRole));
            }
            return(this);
        }
        /// <summary>
        /// Creates RBAC role assignments for the virtual machine service principal.
        /// </summary>
        /// <param name="virtualMachine">The virtual machine.</param>
        /// <return>An observable that emits the created role assignments.</return>
        ///GENMHASH:ACFB6162939077C3462B391EB2DD5A18:01A98853651D800A25EE02E4E8B4FAB6
        private async Task <List <Microsoft.Azure.Management.Graph.RBAC.Fluent.IRoleAssignment> > CreateRbacRoleAssignmentsAsync(IVirtualMachine virtualMachine, CancellationToken cancellationToken = default(CancellationToken))
        {
            List <IRoleAssignment> roleAssignments = new List <IRoleAssignment>();

            if (!this.rolesToAssign.Any() &&
                !this.roleDefinitionsToAssign.Any())
            {
                return(roleAssignments);
            }
            var servicePrincipal = await rbacManager.ServicePrincipals.GetByIdAsync(virtualMachine.Inner.Identity.PrincipalId, cancellationToken);

            await ResolveCurrentResourceGroupScopeAsync(virtualMachine);

            var roleAssignments1 = await Task.WhenAll(rolesToAssign.Values.Select(async(scopeAndRole) =>
            {
                BuiltInRole role = scopeAndRole.Item2;
                string scope     = scopeAndRole.Item1;
                return(await CreateRbacRoleAssignmentIfNotExistsAsync(servicePrincipal, role.ToString(), scope, true, cancellationToken));
            }));

            roleAssignments.AddRange(roleAssignments1);

            var roleAssignments2 = await Task.WhenAll(roleDefinitionsToAssign.Values.Select(async(scopeAndRole) =>
            {
                string roleDefinition = scopeAndRole.Item2;
                string scope          = scopeAndRole.Item1;
                return(await CreateRbacRoleAssignmentIfNotExistsAsync(servicePrincipal, roleDefinition, scope, false, cancellationToken));
            }));

            roleAssignments.AddRange(roleAssignments2);

            return(roleAssignments.FindAll(roleAssignment => roleAssignment != null));
        }
        /// <summary>
        /// Creates RBAC role assignments for the virtual machine scale set MSI service principal.
        /// </summary>
        /// <param name="scaleSet">The virtual machine scale set.</param>
        /// <return>An observable that emits the created role assignments.</return>
        ///GENMHASH:2E7E577AEA0C43B5B8D7B57BEFEF1E29:DDAE54B3372466B701A29E3B6A6362B2
        internal async Task <List <Microsoft.Azure.Management.Graph.RBAC.Fluent.IRoleAssignment> > CreateMSIRbacRoleAssignmentsAsync(IVirtualMachineScaleSet scaleSet, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (!requireSetup)
            {
                return(new List <IRoleAssignment>());
            }
            else if (!scaleSet.IsManagedServiceIdentityEnabled)
            {
                return(new List <IRoleAssignment>());
            }
            else if (!this.rolesToAssign.Any() && !this.roleDefinitionsToAssign.Any())
            {
                return(new List <IRoleAssignment>());
            }

            try
            {
                var servicePrincipal = await rbacManager
                                       .ServicePrincipals
                                       .GetByIdAsync(scaleSet.Inner.Identity.PrincipalId, cancellationToken);

                await ResolveCurrentResourceGroupScopeAsync(scaleSet);

                List <IRoleAssignment> roleAssignments = new List <IRoleAssignment>();
                var roleAssignments1 = await Task.WhenAll(rolesToAssign.Values.Select(async(scopeAndRole) =>
                {
                    BuiltInRole role = scopeAndRole.Item2;
                    string scope     = scopeAndRole.Item1;
                    return(await CreateRbacRoleAssignmentIfNotExistsAsync(servicePrincipal, role.ToString(), scope, true, cancellationToken));
                }));

                roleAssignments.AddRange(roleAssignments1);

                var roleAssignments2 = await Task.WhenAll(roleDefinitionsToAssign.Values.Select(async(scopeAndRole) =>
                {
                    string roleDefinition = scopeAndRole.Item2;
                    string scope          = scopeAndRole.Item1;
                    return(await CreateRbacRoleAssignmentIfNotExistsAsync(servicePrincipal, roleDefinition, scope, false, cancellationToken));
                }));

                roleAssignments.AddRange(roleAssignments2);

                return(roleAssignments.FindAll(roleAssignment => roleAssignment != null));
            }
            finally
            {
                Clear();
            }
        }