Azure Stack API’s – Working directly with the Resource Manager API Layer (Technical Preview 1)
Introduction
To work with the Azure’s Resource Manager, you have a number of options. For example, you have these SDK’s to simplify development:
- Azure .NET SDK’s https://azure.microsoft.com/en-us/documentation/api/
- Azure Resource Manager SDK’s – JAVA, Python, and Ruby https://azure.microsoft.com/en-us/blog/azure-resource-manager-preview-sdks/
- Azure Resource Manager PowerShell Cmdlets https://msdn.microsoft.com/en-us/library/azure/mt125356.aspx
Note: I can’t stress enough that this is simply a model I use, mostly for validation and there certainly are other choices depending on project and requirements. Again this is for MAS TP1 which uses Azure AD so this may also be different moving forward for you.
The beauty of cloud consistency means that these tools and patterns are also the method in which you can develop against Azure Stack’s Resource Manager. Keeping in mind Azure Stack is in Technical Preview and not all API’s are available. This blog post offers another way, one that takes away the complexity for SDK’s and PowerShell modules and allows for the ability to understand and learn the API’s as a Restful service in their most foundational form.
Why work directly with APIs?
Besides the ability to learn what’s happening underneath the covers, so to speak, debugging and translation to other languages can be easier. In PowerShell the obvious and easiest option is to utilize the Azure PowerShell cmdlets like Get-AzureRmSubscription or Get-AzureRmVM but this is hard to translate into other scripting or coding languages and if trouble exists it’s a little more complicated to debug. This should not be considered a recommendation on best practice as the note above highlights but for the purposes of testing it should suffice.
To Begin
No matter the method in which you choose to develop, either SDK’s, PowerShell, CLI or directly with APIs there are some basic requirements for a project that need to be met, some of which are managed by the PowerShell or CLI: These are:
- Authentication and authorization – Click Here for information on authenticating a service principal with ARM.
- The application needs to be registered with Azure Active Directory and given permission – Click Here for more details.
- Restful requests can then be made to the API’s correct URI’s with the above information used to create a bearer token – Click Here for Azure’s documentation for ARM API’s. (Note: This is for Azure public cloud so the API versions and available resources will differ from Azure Stacks API’s but this is a great place to start in a cloud consistent world)
In the Technical Preview of Azure Stack - which uses Azure Active Directory -, the first step is to create an application in the Azure Portal. Next, give that application delegated permission to the Azure Stack API application which was created during the install of the technical preview.
Step 1
Create an application in the Classic Azure Portal https://manage.windowsazure.com within the Active Directory you used to install Azure Stack.
Add application:
- Within the directory used for Azure Stack select Applications tab and then select Add+ in the bottom menu to add an application.
- When asked ‘What do you want to do?’ select the “Add an application my organization is developing” option.
- Under the ‘Tell us about your application’ screen enter a name for your application and select the ‘Web application’ type.
- Then enter a sign in URL, here you can enter https://localhost
- Under APP ID URI enter a unique App URI, for example https://localhost/appname/
Step 2
Configure the applications authorization to Azure Stack’s API’s.
Configure Application:
- Select the configure tab and take note of the Client ID GUID (you’ll need this later)
- Under Keys, select the drop down called ‘select duration’ and pick 1 year.
- Click save and go back to the keys section and copy the newly created key (this is the only chance to get it! )
- Under the permissions section click add application and in the dialog box drop down the show menu and select all apps. Click the check button.
- In the list of applications find the AzureStack.local-Api application and select it, then click the plus sign now in the name column. Then click the check.
- It’s now added to the permissions list so drop down the delegated permissions and select the Access AzureStack.local-Api app and then click save again.
- As a last piece of required data, select the ‘VIEW ENDPOINTS’ and in the new dialog box you’ll see several choices. The important piece here is GUID you can see in each dialog box for each of the endpoints listed. This is an easy way to get your Tenant ID in GUID format.
Act on Azure Stacks API’s
This next steps requires their own sections. I’ll show some examples in PowerShell and Python but essentially all we are doing is sending a correctly formed HTTPS request to the Azure Stack API to perform the action we wish to perform. The request can be a GET request just like when you request a web page from a site but in API terms this is a request for information. Or it can be other types like a DELETE request or a PUT request which will delete a resource or create a resource. All requests made to a service, even web sites require a header but for ARM API’s they require some specific information.
Getting Tenants Authorization Token
To retrieve the AAD Token for the tenant’s authorization to access Azure Stacks API’s we’ll make a POST request to the OAUTH token endpoint https://login.microsoftonline.com/{0}/oauth2/token where {0} is your tenant ID from the earlier steps in creating and authorizing applications. We also need to set the grant type and scope.
Using PowerShell, let’s set some parameters:
$ClientID = "<Enter you Client ID>" $ClientKey = "<Enter your client secret>"
$TenantID = "<Enter Tenant ID GUID from Endpoints>"
$User = <"Enter the tenant user name, for example:Tenant1@shawngibbs.onmicrosoft.com"
$Password = "<Enter your Tenant password>"
$AppIdUri = "https://azurestack.local-api/" $AADURI = "https://login.microsoftonline.com/{0}/oauth2/token" -f $TenantID
In Python, setting parameters looks like this:
CLIENT_ID = ""<Enter you Client ID>"
CLIENT_SECRET =""<Enter your client secret>"
CLIENT_TENANTID = "<Enter Tenant ID GUID from Endpoints>"
CLIENT_USERNAME = "Tenant1@shawngibbs.onmicrosoft.com"
CLIENT_PASSWORD = "<Enter your Tenant password>" CLIENT_RESOURCE = "https://azurestack.local-api/" CLIENT_LOGIN_URL= "https://login.microsoftonline.com/" URL = CLIENT_LOGIN_URL + CLIENT_TENANTID + "/oauth2/token"
Making the request for token. Since PowerShell and Python differ in how they deal with the object model and this in turn changes the returned data, we’ll handle it in a way that is easy to deal with, although there may certainly be better ways to do the next step. For Python, we’ll set the acceptable response type to JSON with a request header: headers = {"Accept":"application/json". For PowerShell, this can be set to content type in the command parameters. The request will require a body of content that represents the grant request information and type.
For PowerShell, the request body:
$GrantBody = "grant_type=password&scope=openid&resource={0}&client_id={1}&client_secret={2}&username={3}&password={4}" -f $AppIdUri, $ClientID, $ClientKey, $User, $Password
For Python, the request body:
params = {"grant_type": "password",
"scope": "openid",
"resource": CLIENT_RESOURCE,
"client_id": parameters.CLIENT_ID,
"client_secret": parameters.CLIENT_SECRET,
"username": CLIENT_USERNAME,
"password": parameters.CLIENT_PASSWORD}
Now let’s make the calls to the authorization API and parse out the token we will use to make additional request to the resource managers API.
For PowerShell:
$AADTokenResponse = Invoke-RestMethod -Uri $AADURI -ContentType "application/x-www-form-urlencoded" -Body $GrantBody -Method Post -Verbose
$AADtoken = $AADTokenResponse.access_token
For Python:
response = requests.post(URL, data = params, headers=headers)
response_json = response.json()
token = response_json['access_token']
The end result is that we have the JWT (‘JSON Web Token’) now saved as a variable in PowerShell and Python. This now gets attached to future requests as the ‘Authorization’ part of the requests header. We’ll also set some other header variables just set language and response type.
In PowerShell:
$Headers = @{Authorization = "Bearer $AADtoken "
"Accept" = "application/json"
"x-ms-effective-locale" = "en.en-us"
}
In Python:
headers = {"Authorization": "Bearer "+ token, "Accept": "application/json", "x-ms-effective-locale":"en.en-us"}
At this point, we set the URI of the specific resources API we wish to get or set and make additional calls with the above headers that include the authorization token. For brevity, we’ll simply request subscriptions for the specific tenant, parse the response and since multiple subscriptions may exist, we’ll walk through each.
In PowerShell:
$GetSubscriptionsURI = "https://api.azurestack.local/subscriptions?api-version=1.0&includeDetails=true"
$Subscriptions = (Invoke-RestMethod -Uri $GetSubscriptionsURI -ContentType "application/json" -Headers $Headers -Method Get -Debug -Verbose).value
$Subscriptions
In Python:
SUBURL = "https://api.azurestack.local/subscriptions?api-version=1.0&includeDetails=true"
response = requests.get(SUBURL, headers=headers, verify=False)
response_json = json.loads(response.text)
response_value = response_json['value']
for sub in response_value:
print("My subscription ID is: " + sub['subscriptionId'])
Result
At this point, you have the basics needed to communicate directly with the Azure Stack Resource Management API’s. Even if this is not the model you choose to do your development moving forward, it should at least enlighten you to what is happening. These API’s are everything you need when you want to perform exactly the same tasks that you do via the portal, PowerShell or CLI.