Skip to content
adatum
  • Home
  •  About adatum
  •  Learn Azure Bicep
  •  SCOM Web API
Azure modern application infrastructure with event grid and azure functions Automation

Creating a serverless application with Powershell: Introduction

  • 08/05/201807/01/2025
  • by Martin Ehrnst

Welcome, fellow IT pro. You have found the blog series describing how you can create a serverless application infrastructure with Powershell.

If you consider your self being a ‘modern it pro’, you frequently solve complex tasks and automate your work using code. You know what Git is and have heard people talk about continuous integration. If you can relate, let’s label you a ‘modern it pro’.

When I develop solutions that challenge my knowledge, I often seek advice from our developers. (You know, those who are employed to ‘GIT commit’?) Usually they can share some light on the issue and point me in the right direction.
By developing our own solutions, we have a working proof-of-concept to handover to our developers when things grow too big or complex.

The original challenge

The challenge or scope for my POC was to streamline creation of Azure tenants for our customers. We required to create a tenant, assign subscriptions and do some configuration within Azure AD. Many of these steps was already solved with various scripts, but it is time to consolidate and automate the automation. We decided that we wanted to learn more around the integration and ‘serverless’ PAAS offerings available in Azure.
For the purpose of this blog series we are going to build a new application using the same techniques, in a smaller scale. To create our serverless application infrastructure, we make use of the following Azure offerings:

  • Azure Functions
  • Azure event grid
  • Azure Automation
  • Azure KeyVault

Pizza ordering

I bet you have worked a fair amount of overtime in your career, therefore eaten a lot of pizza as well. Let’s try to build a simple pizza order and delivery process using Event Grid as integration layer and multiple Azure Functions to process the order.

We will break the pizza order and delivery process in to the following steps:

  1. Customer creates/orders a pizza online
  2. Send orderdata to event grid
  3. Azure function subscribe to the “new order” event
  4. Create a new event when pizza is in oven
  5. Post new event when pizza is cooked and ready for delivery
  6. Create a new event when pizza is sent to customer.

Parts in this blog series

  • Part one:  How to set up Event Grid and write custom events with Powershell.
  • Part two: Connect Azure Functions Powershell with Event Grid to complete the circle.

Share this:

  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on X (Opens in new window) X
  • Click to share on Reddit (Opens in new window) Reddit
Azure Logo Automation

Creating Azure AD Application using Powershell

  • 10/04/201807/01/2025
  • by Martin Ehrnst
NOTE: This writeup does not use the latest AZ PowerShell module. I will correct this when I find the time.

Azure AD Application

Azure AD has something called Application registrations. These are often used to integrate with external services and can provide functionality like Single Sign-On to your companies Twitter account. There’s a large selection of applications you can choose from in the Azure Portal, but this post will cover how to create your own application registration using Powershell.

In this scenario, we are creating an app that can access Azure Activity Logs, used by our on-premises Splunk environment. Since I am doing this across 300 tenants the manual approach isn’t feasible.

High-level overview

  • Create the app using Powershell
  • Assign the required API access to the new app
  • Create access key
  • Create new Azure AD Service Principal for our app (SPN)
  • Assign ‘Reader’ role to subscription

Create the app using Powershell

This is the easiest part. Azure Powershell has a pretty simple Cmdlet that let’s you create a new application, New-AzureADApplication. The required steps is to Import AzureRM modules and AzureAD modules. After that, connect to Azure AD using

Connect-AzureAD -Credential -TenantId "domain.onmicrosoft.com"

Now you can run New-AzureAdApplication to create a new app, this example shows the required fields.

New-AzureADApplication -DisplayName "Adatum App Demo" -IdentifierUris "https://localhost/AdatumAppDemo" -HomePage "https://localhost/Adatum"

and in return
ObjectId      AppId                   DisplayName
--------      -----                    -----------
2cd0a284-7b9e-4 34ecfd2a-8f78-38c4a8b0 Adatum App Demo

In the Azure portal we can see our new app registration, but it does not have a service principal and no API access. If you would have gone through the steps creating the app in the portal it self SPN and a “read basic profile” API permission would be added to your app by default.

Assign required API access

This is where I spent the most time. In order to assign permissions to our Azure AD Application we will need to write a bit of code. Applications can be assigned Application Permissions and Delegated permissions. According to the documentation New-AzureAdApplication Cmdlet takes a parameter “RequiredResourceAccess”. This again wan’t something of ‘Microsoft.Open.AzureAD.Model.RequiredResourceAccess’ as a generic list. Using my favourite search engine I found that I also needed to construct this object and add multiple objects (the permissions) to it.

Luckily my friend Jan Vidar Elven (MVP) had an example. A sligthly different approach, but here’s what I did. My app needed access to Azure Service Management API, manually I added this via the portal and explored the JSON manifest to see what GUIDs was added. Later I found a better solution, exploring the Service Principal (API’s) using Get-AzureADServicePrincipal.

Get-AzureADServicePrincipal -All $true | Where-Object {$_.DisplayName -eq "Windows Azure Service Management API"}

which will return something like this.

ObjectId AppId DisplayName



28a1249a-c5bb-4c7b-b94d-064ca5bb1952 797f4846-ba00-4fd7-ba43-dac1f8f63013 Windows Azure Service Management API

Then I could start to build my permission object

## Azure Management API
$AzureMgmtPrincipal = Get-AzureADServicePrincipal -All $true | Where-Object {$_.DisplayName -eq "Windows Azure Service Management API"}
$AzureMgmtAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$AzureMgmtAccess.ResourceAppId = $AzureMgmtPrincipal.AppId

If you had used this object with the ‘RequiredResourceAccess’ parameter now, the app would have assigned Windows Azure Service Management API, but no permissions. Just to be clear, this is the permissions I am talking about

You can explore the same permissions using
$AzureMgmtPrincipal.AppRoles for application permissions and $AzureMgmtPrincipal.Oauth2Permissions for delegated permissions. Azure Management only have one delegated permission

PS C:> $AzureMgmtPrincipal.Oauth2Permissions

AdminConsentDescription : Allows the application to access the Azure Management Service API acting as users in the organization.
AdminConsentDisplayName : Access Azure Service Management as organization users (preview)
Id : 41094075-9dad-400e-a0bd-54e686782033
IsEnabled : True
Type : User
UserConsentDescription : Allows the application to access Azure Service Management as you.
UserConsentDisplayName : Access Azure Service Management as you (preview)
Value : user_impersonation

Who doesen’t love GUIDs?

Now add this permission to a new ‘microsoft.open.azuread.model.resourceAccess’ object

$AzureSvcMgmt = New-Object -TypeName "microsoft.open.azuread.model.resourceAccess" -ArgumentList "41094075-9dad-400e-a0bd-54e686782033", "Scope" before you add that permission object to the ‘resource access object’ created earlier.

$AzureMgmtAccess.ResourceAccess = $AzureSvcMgmt

If you where adding multiple permissions, repeat the above. After you completed this step, our first object $AzureMgmtAccess have an app ID assigned (Azure management api) with the corresponding Resource access object(s)
ResourceAppId ResourceAccess



797f4846-ba00-4fd7-ba43-dac1f8f63013 {class ResourceAccess {...

Now you can re-run our first command but add the permission parameter (delete the app created earlier or change the identifier)

New-AzureADApplication -DisplayName "Adatum App Demo" -IdentifierUris "https://localhost/AdatumAppDemo" -HomePage "https://localhost/Adatum" RequiredResourceAccess @($AzureMgmtAccess)

Check your portal now 🙂

Application Access Key

We have to create an access key for us to programmatically logging in via the application. Depending on your scenario, you might want to create multiple keys, but in this example I am sticking with one. Just like in the Azure portal you will specify the validity time for your key. The example below will add a key wich expire in one year.

New-AzureADApplicationPasswordCredential -ObjectId $AdatumDemoApp.ObjectId -CustomKeyIdentifier "Access Key" -EndDate (get-date).AddYears(1)

If you want the key to not be activated immediately, set the appropriate date time by using StartDate parameter.

Create new Azure AD service principal

For our application to access within our tenant, we need to assign a new service principal. The security principle will allow us to access the subscription (or other resources for that matter.) You can read more about security principals for users and services here, Application and service principal objects in Azure Active Directory (Azure AD)

To create the service principal in via Powershell, run the following: New-AzureADServicePrincipal -AppId -Tags @("WindowsAzureActiveDirectoryIntegratedApp")
Pay attention to that tag. It is required if you want the app to show under app integrations in the Azure AD portal view. Documented here

RBAC / IAM subscription access

The app I am creating is used to read Azure activity logs. To be allowed to read these logs, the app must be assigned ‘Read’ permission on the subscription level. To assign a new role, use the New-AzureRmRoleAssignment cmdlet, using ObjectID, RoleDefinitionName and Scope as input parameters.

New-AzureRmRoleAssignment -ObjectId 'SPN objectId' -RoleDefinitionName "Reader" -Scope "/subscriptions/$SubScriptionId"

PS: When you put the complete script together, you will find that the SPN is create async in Azure Resource Manager. Meaning that you will get the output, but the principal isn’t created. To get around this in our provisioning I created a while loop. Not the prettiest you will find, but works for now.


while ($addRole.DisplayName -ne $AzureSplunkAdApp.DisplayName ) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for SPN to create"
$addRole = New-AzureRmRoleAssignment -ObjectId $AzureSplunkAdAppAppSPN.ObjectId -RoleDefinitionName "Reader" -Scope "/subscriptions/$SubScriptionId"
}

Final script

I have put together a complete script that will create this demo application. No error handling and your risk 🙂

Share this:

  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on X (Opens in new window) X
  • Click to share on Reddit (Opens in new window) Reddit
Azure

Azure monitoring, connecting the dots

  • 04/01/201807/01/2025
  • by Martin Ehrnst

Azure Monitoring

Welcome to the continuing saga on how to monitor your customers Azure tenants being a service provider. Previously we have covered how to authenticate against Microsoft CSP, using Azure Resource Health API with Powershell and more.

This post is all about connecting the dots. We are far away from finished, but things are moving in this project and at the time of writing, we have two separate projects going.
The first one  is focused on creating a single pane of glass for all our customers’ workflows. This involves custom coding and management pack development for SCOM. The second one, which this post will cover, is how we have designed each customer tenant and how we plan to use built-in Azure monitoring functionality.

 

Customer tenant setup

Working for a service provider we need to construct Azure tenants by taking in to account that we are going to manage cloud resources, so using many cloud features makes a lot of sense. The challenge ist that we always have to think about how we can integrate with an existing deployment and work with monitoring solutions on premises.

When we first started out this project we looked in-to what have been done before, and most of the examples we found wouldn’t scale to our requirements or used OMS/Log Analytics only. We wanted to use our SCOM environment for alert handling, dashboard and platform health as SCOM is already integrated with customer portals, CMDBs and more. We will discuss more on that later in this blog post.

Things are moving very fast in Azure, we have changed our inital customer tenant setup twice before we found a structure we believe is future friendly.
When a customer sign up for an Azure Subscription, we populate their tenant with a default monitoring resource group and a OMS/Log Analytics workspace (LA). Along with the default LA workspace we add the Azure Activity Log, Web Apps and Office 365 solutions as standard.
For “bread and butter” type of Azure Resources, such as compute and web apps we setup the same type of monitoring regime we provide for on-premise resources, but we use alerts in Azure Monitor. This approach works well for Azure Resources which do not have existing, custom Log Analytics solutions and searches to provide health state. This means that VMs deployed using our custom ARM template will also include Monitor Alerts such as “CPU Usage % above 95” and “Web app response time above x”. In conjunction with Azure Monitor we use Azure Resource Health wich will provide health state data regardless of resource type, and custom alerts in monitor or Log Analytics.

Below is a (not so detailed) illustration on our default tenant.

 

SCOM and Azure Integration

We use System Center Operations Manager (SCOM) as our main monitoring platform for operating systems and applications. As SCOM is already integrated with our ticketing system, CMDB and other internal tools it seems reasonable to provide insight to application and workloads running in Azure on the same monitoring platform. That way we optimally can provide a single pane of glass in to the on premise, hybrid and cloud only workloads.

 

Azure Management Packs

To get monitoring data in to our on prem SCOM we looked in to two major options.

Option #1:
The official Azure Management pack from Microsoft. he official MP discovery process/adding new tenants cannot be automated. It relies on a GUI where you sign it to the tenant etc. neither does it provide any “umbrella” functionality for companies enrolled in the CSP program.

Option #2:
Daniele Grandini’s Azure/OMS management pack. Daniele’s management packs provide insight to Log Analytics, Azure Backup and Automation, but relies on the official Microsoft MP for initial discovery. Daniele’s management packs focuses on the solutions within the “Monitoring + management” (formerly known as OMS) space in Azure. Since much of the alerting features from OMS/Log Analytics are moving to Azure Monitor, I reached out to Daniele and asked if he had looked in to creating a management pack for that. He had looked a little in to it, but was also concerned about the rapid changes. Unfortunately this MP is bound to the initial discovery from the official Azure MP. A service provider managing several hundred tenants (and growing) cannot have that limitation. I hope to be able to help Daniele with the upcoming Azure Monitor MP.

Here’s where our problems started. I wanted to discover all our manged tenants automatically. Take advantage of being a CSP we set out to create our own management pack(s). I have create one management pack for the CSP platform that integrate with the Partner Center API (see example in this blog post) to do the initial discovery. Tenants and subscriptions are populated as objects in SCOM. Further, using a Partner Center Managed Application we can pre-consent access to all managed tenants. That means we can use this applications credentials to authenticate against each of our managed tenants, by-passing the limitation within the official management pack. All resources are the created as object with a hosting relationship to resourcegroup, subscription and tenant. Basic monitoring is done through Azure Resource Health API.

Below is a diagram showing the structure of our CSP management pack

Credentials used to authenticate against partner center and the Azure tenants is provided through SCOM RunAs accounts.

Our next step in SCOM and Azure integration is to create an Azure Monitor Management pack that reference the CSP management pack. This will provide the more enriched monitoring provided by Azure Monitor. Due to many recent changes to the monitor platform I have decided to wait and see where we end up. At the time of writing Azure Monitor have two new alert features in preview and none of their API’s are officially documented – i will come back with examples when I have something tangible.

Summary

To provide effective monitoring as a service provider for customers which span on-prem and cloud environments, we recommend the following:

  1. For “bread and butter” monitoring use a combination of SCOM and Azure Monitor
  2. If in the CSP program. Create a management pack using CSP rest API’s (hopefully I can share our MP later) combined with a custom Azure Monitor MP
  3. Not a CSP? Look in to a combination of the official MP and Daniele’s management packs.
  4. Deploy Log Analytics as default to all tenants. This will give you an advantage when customers require custom solutions and log sources.

Wrapping up

All service providers do their monitoring differently, but hopefully you have gotten some ideas on how you can do yours. Our solution is far from being finished, but I feel we have a structure that are future proof (the modern type of future). Hopefully we can share the SCOM management packs later, but feel free to contact me on specifics. Just remember I cannot share the MP itself at this point in time.

Until further notice, this will be the closing post on how you can do Azure Monitoring as a service provider.

 

Big thanks to Kevin Green and Cameron Fuller for providing feedback and to reach out to other community friends on my behalf.

Share this:

  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on X (Opens in new window) X
  • Click to share on Reddit (Opens in new window) Reddit

Posts pagination

1 2 3 4 5 6 … 10

Popular blog posts

  • SCOM Alerts to Microsoft Teams and Mattermost
  • How to move Azure blobs up the path
  • Azure Application registrations, Enterprise Apps, and managed identities
  • Serverless application with PowerShell: Azure Functions
  • Export overrides to CSV, XML & HTML

Categories

Automation Azure Azure Active Directory Azure Bicep Azure DevOps Azure Functions Azure Lighthouse Azure Logic Apps Azure Monitor Azure Policy Community Conferences CSP Monitoring DevOps GitHub Guest blogs Infrastructure As Code Kubernetes Microsoft CSP MPAuthoring OMS Operations Manager Podcast Powershell Uncategorised Windows Admin Center Windows Server

Follow Martin Ehrnst

  • X
  • LinkedIn

RSS feed RSS - Posts

RSS feed RSS - Comments

Microsoft Azure MVP

Martin Ehrnst Microsoft Azure MVP
Adatum.no use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it. Cookie Policy
Theme by Colorlib Powered by WordPress