Skip to main content

PowerShell + Azure + Python : Use Project Custom Settings

Background

First to set up the background [bit reaching on the Dev side] on the post, quick introduction to what is an Azure Cloud service along with some terms Dev like to throw around:

Cloud Service :
PaaS offering , running VMs on Microsoft Azure. You have control over these VMs as you can remote into them and customize them to run your apps. A typical cloud service contains:

  • Web Role - Windows Server running IIS on top of it.
  • Worker Role - Windows Server.
Now using Visual Studio one can configure the Cloud Service as per ones need (Check Resources at the bottom). There are typically 2 files in your project definition which need tweaking (source : MSDN - link in Resources section) :


  • ServiceDefinition.csdef  : The service definition file defines the runtime settings for your cloud service including what roles are required, endpoints, and virtual machine size. None of the data stored in this file can be changed when your role is running.
  • ServiceConfiguration.cscfg : The service configuration file configures how many instances of a role are run and the values of the settings defined for a role. The data stored in this file can be changed while your role is running.







A full post on how to use Visual Studio to deploy a cloud service is out of scope for this post and me ;)

Task at hand

We were working on a Python project which will run on top of Azure utilizing cloud services (web and worker role). We had to customize our worker role a bit using the custom settings that could be defined for a Cloud project in Visual Studio. 

The customization needed us to read the custom settings defined in the Service Configuration file for the Azure Worker role and then consume it as per some logic.

The link at MSDN shows how to do it in C#, so I tried to port it to PowerShell.
It is relatively easy if you have been working with PS for a while.


Steps:


  1. Create a new Project in Visual Studio.

  2. Select Python Azure Cloud Service template to start with (need Python Azure SDK installed).

  3. After you create the Project from the template, it will ask you to select roles for your Cloud Service. I have added a Web & Worker role, this depends on your project. After that it asks you to select a Python environment, I chose a virtual environment for my Python app again this depends on your project.


  4. Now let's add a custom setting to our Worker role. Right click the Worker role > Properties. It will open up a configuration page like below:

  5. Now go to 'Settings' and click on 'Add Settings' button; go ahead and add the custom setting.



    Note - Adding a custom setting above will make an entry in the ServiceConfiguration.*.csfg files , see below :

  6. Before moving further and showing you how to access the custom setting in your code, it is important to understand the role PowerShell plays in configuring a Role.

    If you notice there is a bin directory under your each Role which contains PS scripts which configure your role e.g installing webpi, windows features etc and also take notice of a ps.cmd file which invokes these PowerShell script as a startup task.



    Take a look at the ServiceDefinition.csdef (which contains the runtime settings for my cloud service) and notice that it creates a startup task for the role.



    Below is the gist showing the ps.cmd batch file which calls our PowerShell Script, you can always modify it to fit the custom requirements you have, leaving up to you to direct Verbose stream to a log file (verbose stream used later):
  7. Now to the final piece in the puzzle , How to access the custom setting value and use it while configuring the Worker Role ?
    Well the example is already provided at the MSDN, Click here

    PowerShell to the rescue. Since PowerShell Script is already being used to configure a cloud service. One can put the extra few lines of code into the Script named ConfigureCloudService.ps1 to access the custom setting and make decisions or perform any action based on the value. You could also add another script and get it called from the ps.cmd of configurecloudservice.ps1 (you know how it works already).

    Easiest way is to load the DLL and then simply call the static method named GetConfigurationSettingValue on the RoleEnvironment Class.

I think it doesn't get easier than this, PowerShell gives us the capability to tap into the .NET framework, as a System Admin working on Microsoft realm it makes me more productive. Have you boarded the PS bandwagon yet ?

Resources:

Configuring an Azure Project
https://msdn.microsoft.com/en-us/library/azure/ee405486.aspx

How to: Configure the Roles for an Azure Cloud Service with Visual Studio
https://msdn.microsoft.com/en-us/library/azure/hh369931.aspx

Popular posts from this blog

Test connectivity via a specific network interface

Recently while working on a Private cloud implementation, I came across a scenario where I needed to test connectivity of a node to the AD/DNS via multiple network adapters.  Many of us would know that having multiple network routes is usually done to take care of redundancy. So that if a network adapter goes down, one can use the other network interface to reach out to the node. In order to make it easy for everyone to follow along, below is an analogy for the above scenario: My laptop has multiple network adapters (say Wi-Fi and Ethernet) connected to the same network. Now how do I test connectivity to a Server on the network only over say Wi-Fi network adapter?

PowerShell + SCCM : Run CM cmdlets remotely

Today I saw a tweet about using implicit remoting to load the Configuration Manager on my machine by Justin Mathews . It caught my eye as I have never really tried it, but theoretically it can be done. Note - The second tweet says "Cannot find a provider with the name CMSite", resolution to which is in the Troubleshooting section at the end.

PowerShell : Trust network share to load modules & ps1

Problem Do you have a central network share, where you store all the scripts or PowerShell modules ? What happens if you try to run the script from a network share ? or if you have scripts (local) which invoke scripts or import PowerShell modules stored on this network share ? Well you would see a security warning like below (Note - I have set execution policy as 'Unrestricted' not 'bypass' here): Run a .ps1 from the network share Well this is a similar warning, which you get when you download scripts from Internet. As the message says run Unblock-File cmdlet to unblock the script and then run it, let's try it.