ShareBlog






         Another Azure site

Archive for Azure Management Library

June 30, 2017

Azure Management Library updated with ability to manage more resources

Filed under: Azure Management Library @ 10:33 am

The Azure Management Library version 1.1 was just released and includes the ability to manage CosmosDB (formerly known as DocumentDB), Azure Container Service and Registry, and Active Directory Graph.  Go to the official announcement for more information and sample code.

June 23, 2017

Handling RBAC using Azure Management Libraries

Filed under: Azure Management Library @ 6:54 pm

If you have been using Azure for any length of time, you know Azure has a concept of Role-Based Access Control (RBAC) which allows you to fine tune who can access what resources (read Get Started with Role-Based Access Control in the Azure portal for more information). This is done by granting various roles to the resources and then adding users and Active Directory (AD) groups (preferably groups) to those roles.  By doing this you can easily maintain who can do what in Azure.

The Azure portal itself allows you do this easily but what about using code?  You can do this using Azure Management Libraries.

As a reminder, the main unit in Azure is a tenant which could have one or more subscriptions inside of it.  Each subscription can have one or more resource groups and each resource group can have one or more resources.  Roles and AD groups live at the tenant level so they apply to all the subscriptions, resource groups, and resources.

This demo application is a .Net Core 1.1 console application.  Additional packages need to be add as below:

Install-Package Microsoft.Azure.Common -Version 2.1.4    
Install-Package Microsoft.Azure.Management.Fluent 
Install-Package Microsoft.Azure.Management.Graph.RBAC.Fluent
Install-Package Microsoft.Extensions.Configuration.Json -Version 1.1.2     
Install-Package Microsoft.NETCore.Portable.Compatibility -Version 1.0.2
Install-Package Microsoft.Extensions.Configuration -Version 1.1.2
Install-Package Microsoft.Azure.Management.Authorization -Version 2.5.0-preview -Pre 
Notice that the “Microsoft.Azure.ManagementAuthorization” package is a preview version.  This is the only version that works with .Net Core 1.1 and as such some of the functionality may change later.

Rather than reading the information to get the Service Principal from a file as was done in previous blog entries, the information that is needed is stored in a settings file.  Refer to my previous blog post on Azure Management Libraries  to get this information.

{
  "AMLSettings": {
    "client": "<client ID>",
    "secret": "<secret key>",
    "tenant": "<tenant ID>"
  }
}

It is fairly straight forward to read this information.

var builder = new ConfigurationBuilder()
   .SetBasePath(Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json");

Configuration = builder.Build();

Use the information being read from the settings file to get the Service Principle information that is being used for the AML program and the login credentials from that Service Principle.  These credentials can then be used to create the AML variable which will be used later.  Note that, in this case, the variable is only used to create a Resource Group and get its name for later use.  The actual setting of the RBAC is done in a different way.

ServicePrincipalLoginInformation loginInfo = new ServicePrincipalLoginInformation()
{
   ClientId = Configuration["AMLSettings:client"],
   ClientSecret = Configuration["AMLSettings:secret"]
};
var credentials = new AzureCredentials(loginInfo, Configuration["AMLSettings:tenant"], AzureEnvironment.AzureGlobalCloud);
var authenticated = Azure
   .Configure()
   .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
   .Authenticate(credentials);
var azure = authenticated.WithDefaultSubscription();

Since there is a need to access the tenant level information in order to work with the Azure AD groups, creation of variables needed are separated rather than combined into one command as done in my previous blog posts..  The “authenticated” variable will allow access to the tenant level data, while the “azure” variable will work on the subscription level to create the other resources. There is also the “credentials” variable that will be used later when assigning the roles to the resource.

Create a demo resource group that we can add the role.

string rgName = "amlrbacresourcegroup";     //Demo Resource group Name

var resourceGroup = azure.ResourceGroups.Define(rgName)
   .WithRegion(Region.USEast)
   .Create();

Next, create the Azure AD group that will be added to the role.  If the AD group is already created then this step can be skipped.  Note that without the check it is possible to create multiple AD groups with the same name.

var adGroup = authenticated.ActiveDirectoryGroups.GetByName(grpName);

if (null == adGroup)
{
   GroupCreateParametersInner parameters = new GroupCreateParametersInner()
   {
      DisplayName = grpName,
      MailNickname = grpName,
   };
   var createdGroup = authenticated.ActiveDirectoryGroups.Inner.Create(parameters);

   System.Threading.Thread.Sleep(20000);

   adGroup = authenticated.ActiveDirectoryGroups.GetByName(grpName);
}

This is fairly straight forward.  Setup the parameters used to create the AD group. In this case only the “DisplayName” and “MailNickname” variables, both of which are required, are set and then create it.  If this group is going to be used immediately,  then there needs to be time to propagate through the Azure AD system hence the 20 second sleep delay.

Next, get the role to use.  Even though roles are tenant level entities, they need to be selected at the same subscription level as the resource where they will be added.

var role = authenticated.RoleDefinitions.GetByScopeAndRoleName($"/subscriptions/{azure.SubscriptionId}", "Contributor");

The “AuthorizationManagmentClient” handles the actual setting of the role to the resource.  Create an instance of it passing in the credentials from the Service Principal and set the proper subscription ID.

var authorizationManagementClient = new Microsoft.Azure.Management.Authorization.AuthorizationManagementClient(credentials)
{
   SubscriptionId = azure.SubscriptionId
};

Setup the parameters needs to assign the group to the role in the resource group.  The “PrincipalID” is what is being set which, in this case, is the group that was selected earlier but it could be an individual user account as well.  The “RoleDefinitionId” is the ID of the role to which the group will be added.

var createParameters = new Microsoft.Azure.Management.Authorization.Models.RoleAssignmentCreateParameters();
createParameters.Properties = new RoleAssignmentProperties()
{
   PrincipalId = adGroup.Id,
   RoleDefinitionId = role.Id,
};

Finally, create the role assignment using the variables that have been setup.  The first parameter is the scope to the resource being used, which is typically the resource’s Id .  The second parameter is a new GUID, and the last parameter is the parameters that were setup in the previous step.

var result = authorizationManagementClient.RoleAssignments.Create(
   resourceGroup.Id,
   Guid.NewGuid().ToString(),
   createParameters.Properties
);

That is all there is to it.  The full source code can be download from GitHub

June 5, 2017

Dependency Injection in a nutshell

Filed under: Azure Management Library @ 4:05 pm

I was working with a new developer on one of my contracts who could not seem to grasp the concept of Dependency Injection. According to Wikipedia, “Dependency injection separates the creation of a client’s dependencies from the client’s behavior, which allows program designs to be loosely coupled and to follow the dependency inversion and single responsibility principles. It directly contrasts with the service locator pattern, which allows clients to know about the system they use to find dependencies.”

Makes sense, right?

I explained it this way:  You are going out and need a car so you contact a ride sharing service.  You may not really care what car you get as long as it meets certain criteria like 4 wheels, brakes, seats, etc…  In that case you just call the company and say “I need a car”.  Dependency Injection works the same way.  You may not care (or in some cases even know) what class you are getting as long as it meets certain criteria.  If you need to log information from your program you may not care if the data is stored in a SQL Server Database, a Cosmo Database, an Azure table, or even a flat file just as long as the data is stored correctly.

He seemed to get it and I hope it helps others.

 

May 29, 2017

Using Azure Management Libraries

Filed under: Azure Management Library @ 7:28 pm

In my last blog post I gave a quick introduction to Azure Management Libraries (AML) for .Net.   In this post we will go through some code examples.  Microsoft has provided an extensive library of samples that you can look through here but the problem is there is no real description of how these were created.

The first thing you will need to do is to download the libraries you want to use.  If you look at the README.MD file in the AML’s GitHub repository, almost at the bottom of the page is the listing of the various Azure Management Libraries and a link to the nuget repository where you can get more information on the library as well as the command needed to download the library.

For this example we will need 3 libraries:

  • Microsoft.Azure.Management.Compute.Fluent;
  • Microsoft.Azure.Management.Fluent;
  • Microsoft.Azure.Management.ResourceManager.Fluent

Create a new Console App using .Net Core as shown below:

Using either PowerShell or the Package Manager Console install the libraries we need from above and then add the appropriate “using” statements.

The first thing we need to do in order for our code to work is authenticate ourselves. This is not done using username and password but rather through Azure Service Principal information either through code or through a file. This file gives you step by step instructions on how to create a Service Principal on your desktop but that can be quite a process (especially with a Windows 10 machine).

Luckily,  at the last Build conference, Microsoft announced that all Azure Portals will have a CLI shell built right into the portal (PowerShell coming soon).  By using that you can by pass all the steps and just use the one shown below.  Note that in the actual file it is suggested to use “jq” to push the output into a file. I do not do that, I just cut the code from my shell and paste it into notepad.  Also note that the code below looks like it wants you to change values like “subscriptionId” but you can paste the line AS IS into the CLI window and it will work.

az ad sp create-for-rbac --expanded-view -o json --query "{subscription: subscriptionId, client: client, key: password, tenant: tenantId, managementURI: endpoints.management, baseURL: endpoints.resourceManager, authURL: endpoints.activeDirectory, graphURL: endpoints.activeDirectoryGraphResourceId}"

This program will generate text like what is shown below (of course the values of the GUIDs have been changed otherwise you could have tenant admin rights to my tenant).  Copy and paste the text into a file for use in your code.  Note that you need to guard this file just as you would your admin username and password credentials.

"authURL": "https://login.microsoftonline.com", "baseURL": "https://management.azure.com/", "client": "55550809-4168-4846-8620-98b32163a9da", "graphURL": "https://graph.windows.net/", "key": "55555555-603b-5555-8d7a-3762d60fe9fb", "managementURI": "https://management.core.windows.net/", "subscription": "55555555-b5da-460d-5555-ac985d5f3b83", "tenant": "55555555-ede8-4da6-5555-2d9d5fd5295f"

If you care what the code is doing is to create a new App registration in Azure AD and stores the key into the Keys area so if your file ever falls into the wrong hands you can delete that app to render the file useless.

Replace the line in the Main method with:

var azure = Azure.Authenticate("c:\\code\\auth.txt").WithDefaultSubscription();

(substituting the name and the location of the file).   This will use the file to get access to the tenant and then use the default subscription for everything.  If you know your subscription’s ID you can use “WithSubscription(<subscriptionId>)” instead.  Your code should look like the following:

Now that are authenticated we can start to manipulate the resources in Azure.  You may have noticed that all the libraries we imported end in “Fluent”.  What this means is that the command can be chained together into one call.  So rather than stating the VM’s name, resource group, and network in 3 different commands, we can do it all at once.  Also, I make a call to “using Microsoft.Azure.Management.ResourceManager.Fluent.Core” rather than just the “Fluent” so that I can get access to some of the enums used below.

There is one caveat to this.  While the commands can be chained together there is an order to how they can be chained together.  For instance to create a VM we need to specify the name first (actually this is done as part of the definition), then we MUST define the region, followed by the resource group, then the  primary network, the private IP address information, public IP Address, machine image, Admin username, Admin password, and then you can add optional information like disks, tags, size, and many more options.  One nice thing about AML commands is that if you are expected to enter complex information like Windows Server image name, there is a enum that has all the values defined like “KnownWindowsVirtualMachineImage.WindowsServer2008R2_SP1”.

Once you have all your values defined you just need to make a call to “Create()” to kick off the process.  There is also a “CreateAsync()” command but, as of this writing, that is still in preview and will not be covered here. A bare minimum VM implementation looks like:

If you notice, I use the “azure” variable that I had defined previously to create the VM.  By calling the “VirtualMachines” class I am saying I want to manipulate VMs and by calling the “Define” method I am saying I want to create a new VM.  Be careful, if the machine already exists this call will through an error.

If I wanted to change values I would use “Update” instead of “Define”.  In order to do that I need to have a reference to the VM.  I can do this a couple of different ways including using the Id of the VM or by using the name of the resource group the VM belongs to as well as the name of the VM itself (this is the method I use most of the time) as shown below:

var windowsVM1 = azure.VirtualMachines.GetByResourceGroup("test", "test");

(note that I called my VM and my Resource Group “test” which probably wouldn’t happen in the real world).

Once you have the reference you can then update the VM.  You do things like add a new data disk (shown below), add tags, change the machine size, and so on.  Once you have all the commands chained together call “Apply” to apply the updates as shown below

One other thing you can do is to manage the resources like turn a VM on or off . This is very easy to do.  Get a reference to the VM like we did above and then just call the “PowerOff()” method to turn the VM off or “Start()” to turn it on.  You can also reset the VM by calling “Restart()”.  No additional commands are needed.

The last thing you can do is to get information about the VM.  Much like you did above, get the reference to the VM and then if you just type in the variable’s name and a period, the Intellisense will show you the VM’s values that you can retrieve.

As you can imagine you can create programs that allow people like help desk users to create and manage resources in Azure without having to have actual logins using Azure Management Libraries.  In my posts I will go through doing just that.

Here is the complete code.

using System;
using Microsoft.Azure.Management.Compute.Fluent;
using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;

namespace AMLDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var azure = Azure.Authenticate("c:\\code\\auth.txt").WithDefaultSubscription();
            var windowsVM = azure.VirtualMachines.Define("test")
                .WithRegion(Region.USEast)
                .WithNewResourceGroup("test")
                .WithNewPrimaryNetwork("10.0.0.0/28")
                .WithPrimaryPrivateIPAddressDynamic()
                .WithoutPrimaryPublicIPAddress()
                .WithPopularWindowsImage(KnownWindowsVirtualMachineImage.WindowsServer2008R2_SP1)
                .WithAdminUsername("garybushey")
                .WithAdminPassword("ThisIsAFakeP@ssw0rd1234")
                .Create();
            Console.WriteLine(windowsVM.Id);

            var windowsVM1 = azure.VirtualMachines.GetByResourceGroup("test", "test");
            windowsVM1.Update()
                .WithNewDataDisk(10)
                .Apply();

        }

    }
}

Azure Management Library

Filed under: Azure Management Library @ 3:16 pm

About a month ago, at the time of this blog post being written, Microsoft announced the general availability of the Azure Management Libraries (AML) for .Net.   There are couple of interesting tidbits in the announcement which you can read here.

One thing that immediately caught my eye was that is an open source project with the source code being saved in GitHub.  While this is not all that amazing seeing how Microsoft is really embracing the open source concept, what is great is that this is open to anyone to contribute to.  If there is something you think the code should do (like setting CORS in Web Apps) you can take a shot at writing it.  If nothing else it can make debugging your issues a lot easier if you can understand what is going on behind the scenes.  The code can be downloaded form here.

The second thing is that this is still a work in progress.  If you look at the chart that is in the README.md file for the GitHub project (I would suggest using this rather than the announcement since it is more likely to be updated with any new features) you will see that there are three sections namely,  “Available as GA”, “Available as Preview”, and “Coming soon”.  For instance, if you look at the “Fundamentals” row you will see that “Async methods” are listed as “Available as Preview”.  I won’t go into how something actually labeled as fundamental is still in preview but from all my testing, async methods are working just fine.

Right now I am sure you are thinking, mainly because it was the first thing I thought, is how does this compare to / compete with Azure Resource Manager (ARM) templates?  Well, both actually use the same REST interfaces behind the scenes so it really comes down to three things: completeness, coding, and management.

Completeness is pretty obvious.  There are probably going to be some things that you can do with an ARM template that you cannot do with AML code.  One of those is DocumentDB Cosmos DB.  This is available in an ARM template, and you can generate the code using Visual Studio, but it is not yet available using AML code.  Therefore if your application requires you to create a Cosmos DB, you would need to use an ARM template.

Coding is probably more of a preference than anything else.  Being a C# developer by trade I will tend to gravitate towards using AML.  While I like JSON and use it quite a bit I would much rather use C# code when I can.  I feel it is much easier to understand.  Not to mention that it takes 150 lines of JSON code to create a VM (mostly generate from Visual Studio) and only about 30 lines of C#.

Another item I would consider is management.  ARM templates are great for defining your resources and updating them as needed but you cannot turn on and off a VM from an ARM template (as least as far as I know).  You can do this with AML code and it only takes 3 lines of code.  The first lines gets the authentication file (which is a blog post of its own), the second gets the reference to the VM, and the third calls “PowerOff” (or “PowerOffAsync”) to shut down the VM.

The authentication file mentioned previously is an experimental feature that allows you to store your Service Principal  information in a file so that other people can, in essence, login to your Azure environment without needing to have the proper credentials. This can be useful in situations where you may have a help desk create VMs for people.  You can easily write a program to create the VMs and use the authentication file so that the help desk users will not need to know the username and password.  However if someone were to get access to the file they would have the same level of access as the person who created it so it needs to be treated with care.

Azure Management Libraries are a great alternative to Azure Resource Management templates for those that prefer coding to JSON.  In some future blog posts I will walk through creating some resources using AML code.

© 2023 ShareBlog   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs