AIS recently held an internal hackathon for Microsoft Power Platform to expose our team to the platform, concepts, approaches through hands-on experience and to demonstrate the role Power Platform plays in modernizing legacy applications in the cloud.

As a premier Microsoft partner, Power Platform has quickly become a core part of our holistic enterprise cloud transformation strategy. Our teams have helped enterprises across Financial Services, Insurance, Health and Life Sciences, and the Government leverage Power Platform for enterprise-grade application modernization in the last three years.

We’re integrating Power Platform with Azure and Microsoft 365 for powerful legacy modernization capabilities, and throughout the project, we uncovered new lessons learned to share across project teams.

The Power Platform Market

There’s been a surge in demand for Low Code Modernization solutions in the last few years. Many organizations are looking to enable Line of Business (LOB) owners and teams to build productivity and collaboration solutions, offsetting the continued strain on IT teams.

Microsoft answered the call with Power Platform. Since its release, we’ve been working with product teams and industry leaders to develop adoption frameworks, accelerators, and solutions to help organizations get the most out of their Power Platform investments. The demand has grown such that we’re continuing to introduce new ways to build our Power Platform skills. Enter Our hackathon team.

“Power platform is really a ‘work less do more,’ as it would even get the integrations done with legacy systems without writing a single line of code. This I have never experienced in my 13 years of experience, just amazing. The perspective of low-code-no-code is completely changed with this experience, it is an enterprise development tool that can connect your teams’ apps to outlook app to data verse to SQL. You name the technology; it has a connector to fit in.”
– Technology Lead at AIS, Kranthi Kiran Gullapalli

Meet the Hackathon Team

There was a lot of initial interest in learning the platform from our India-based team out of the AIS Hyderabad HQ. Over a dozen people committed weeks of their time inside and outside of regular working hours in the pursuit of the Power Platform experience.

Some of the participants included employees from our HUB team. The HUB is a group of employees fully dedicated to helping AIS project teams deliver successful cloud modernization projects.​ This team consolidates knowledge and experience to provide rapid research and guidance for cloud migration and modernization projects­­­. As app modernization using Power Platform work grows, we wanted to allow individuals to skill up on the platform.

But the HUB team members weren’t the only participants. These groups comprised learners and teachers across account teams. Teams were broken down into several pods with a leader to guide that team’s focus area for the project, including Dataverse data migration and integration, authentication, Power Apps Portals development, and more.

“MPP Hackathon” is where the idea of converting a monolithic application to a Power Apps Portal became a reality. Initially, some ideas flowed on reimagining a typical legacy app to Power Apps Portal, but the hackathon allowed us to experiment & try it. Hackathon helped me & my team to have hands-on exposure to the MPP environment. We worked with data modeling and got to know better on Dataverse (In-house storage in MPP). We took our first of many steps towards App Modernization with this hackathon as we are new to MPP. Microsoft Power Platform is a suite of business services that unifies our data. It provides a powerful way to analyze data, act on newly generated insights, deliver personalization, and automate business processes.”
– Jagrati Modi, Software Developer

A Mission to Innovate, Passion for Learning

AIS strives to provide ongoing learning opportunities for our employees. And we’re lucky to have a team that is so passionate about learning, innovation, and the continual pursuit of new skills.

We’ve developed programs like aisU to nurture a growing community of continued education, knowledge sharing, and technical excellence. We offer various opportunities to gain exposure to new technology and concepts, such as training boot camps, technology deep dives, and level-up sessions presented by consultants based on project experience.

Access to the methodologies, approaches, and lessons learned from these project teams helps employees gain the know-how and resources to consult on and deliver similar projects within their accounts successfully.

These opportunities aim to help AIS improve overall project delivery, presales support, and envisioning capabilities for better customer outcomes.

Up Next: Our Approach

Stay tuned for part two of this series as we dive deeper into the approach and execution of an end-to-end application modernization project leveraging Power Platform, API Integration, Dataverse, Azure DevOps, and more.

Until then, check out some of our open job opportunities. We’re always looking to add passionate technologists to our growing team. Introduce yourself and let’s talk about a future career at AIS.

This blog series is for anyone trying to learn how to use the Power Platform. Readers should know software development fundamentals. This blog begins by covering how to create a base Canvas App from an existing table in the Microsoft Dataverse. It reviews all the screens, forms, and changes necessary to make the user interface work as defined in the requirements. By the end of this blog, a fully functioning app will be ready for data entry.

The blog series assumed the following:

  • You have a Power Apps tenant with administrative privileges
  • You have knowledge of software development fundamentals
  • You have completed Part One of this series

Creating the Canvas App

In Part One of this series, I defined our home inventory application, its database, and how its user interface (UI) would look. I also created the underlying tables for our application. With a data source in place, I can create a Canvas App connected to the Microsoft Dataverse. Making and table-based canvas app saves time by creating the base screens. It is also valuable for reverse engineering to understand how to customize the app on your own.

When prompted, use the Items table as this is the focal point of the application.
Focus point of application

This will create a basic Canvas App; the main screen can search for items (there are none at this time of course)
Main screen creating basic canvas app

Clicking the + opens a form to create a new record; at this time, only the Name column is provided.
Creating new record

Expand the EditScreen1 and Select the EditForm1.
Next, add the custom columns that were created in the Microsoft Dataverse to EditForm1.
Adding custom columns created in Dataverse to EditForm1

Pressing the Play button and then clicking + opens the edit form below. The only problem is there are no Item Types, Locations, or Manufacturers yet.

Editing Form with Item Types, Locations, and Manufacturers

Creating the Lookup Forms

Near the top left of the window, click on New screen. Choose Form as the type.
Power Apps Home to create Lookup Forms

On the newly created screen, click on the EditForm element created. On the right side of the screen, select Item Types for the Data source. Click on the LblAppName created and change the Title Property from [Title] to Item Types. Repeat this with Manufacturers and Locations.

Take few minutes to rename the screen and its elements following the Power Apps Canvas App Accessibility Guidelines and the PowerApps Canvas App Coding Standards and Guidelines. This is important for many reasons; for example, screen readers will read these values aloud, and “EditScreen1” would not be valuable to the end-user. Following these guidelines, I have renamed all screens, forms, and controls within the app. For example, these are the names of the screens that I will be using:

Rename the Screen and Elements

Be sure to save if you have not already; click File and then Save (or CTRL+S).

Manufactures Lookup Form

Expand the Manufacturer Edit Screen, select the frmManufacturer, click Edit Fields, and then add the columns Support Phone and Support URL. Delete the Created-On column if desired.
Click the Advanced tab for the OnSuccess action, enter

Navigate(‘Item Edit Screen,’ ScreenTransition.Fade)

Note: This tells the form to navigate back to the Item Edit Screen when this form is complete. For more information, see Back and Navigate functions in Power Apps.
Insert and edit the Manufacturer

Select the cancel icon (X) and change the OnSelect function to:

      ResetForm(frmManufacturerEdit);Navigate(‘Item Edit Screen’,ScreenTransition.Fade)
 

Note: This tells the form to clear its columns and navigate back to the Item Edit Screen. For more information, see Reset function in Power Apps and Back and Navigate functions in Power Apps.

Creating columns to navigate back to the Item Edit Screen

If necessary, rearrange elements; the form should look something like this:
Rearrange Elements to customize form

Locations Lookup Form

Since the Location table only has the Name column, there is no need to add any columns to it; however, I need to repeat the same steps from the Manufacturers form.
Select the frmLocationEdit and update the OnSuccess action to:

      Navigate(‘Item Edit Screen’,ScreenTransition.Fade)
 

Note: This tells the form to navigate back to the Item Edit Screen when this form is complete.
Select the cancel icon (X) and change the OnSelect function to:

      ResetForm(frmLocationEdit);Navigate(‘Item Edit Screen’,ScreenTransition.Fade)
 

Item Type Lookup Form

Since the Item Type table only has the Name column, there is no need to add any columns to it; however, I need to repeat the same steps from the Manufacturers form.
Select the frmItemTypeEdit and update the OnSuccess action to:

       Navigate(‘Item Edit Screen’,ScreenTransition.Fade)
 

Select the cancel icon (X) and change the OnSelect function to:

      ResetForm(frmItemTypeEdit);Navigate(‘Item Edit Screen’,ScreenTransition.Fade)

Completing the Form

Select the frmItemEdit and update the OnSuccess action to:

      Navigate(‘Items Screen’,ScreenTransition.Fade)

Select the cancel icon (X) and change the OnSelect function to:

     ResetForm(frmItemEdit);Navigate(‘Items Screen’,ScreenTransition.Fade)

Select the Item Type field (make sure the field is selected, not the Card). Change the Width function to:

 
     (Parent.Width - 60)*.8

Repeat this for Manufacturer and Location fields.

Creating the Add Buttons

Now I will add the buttons to open the necessary to create a new Item Type, Location, and Manufacturer from the Item form. I will be selecting the data card for Item Type, Location, and Manufacturer and adding a button to it during this process. Any property not mentioned will use the default value. Each of the three buttons shares these properties:

  • Width: (Parent.Width – 60)*.1
  • Text: “+”
  • Size: 48
  • All Padding Properties: 1
  • All Radius Properties: 0
  • Position: 528,63

Select the Item Type card, click on the + button on the far left, expand Popular and select Button. Select the new button, set the shared properties, and then set OnSelect:

 NewForm(frmItemTypeEdit);Navigate(‘Item Type Edit Screen’, ScreenTransition.None)
 

For more information, see EditForm, NewForm, SubmitForm, ResetForm, and ViewForm functions in Power Apps.
Creating Popular navigation
Customize Padding Elements

Select the Manufacturer card, click on the + button on the far left, expand Popular and select Button. Select the new button, set the shared properties, and then set OnSelect:

NewForm(frmManufacturerEdit);Navigate(‘Manufacturer Edit Screen’, ScreenTransition.None)

Select the Location card, click on the + button on the far left, expand Popular and select Button. Select the new button, set the shared properties, and then set OnSelect:

NewForm(frmLocationEdit);Navigate(‘Location Edit Screen’, ScreenTransition.None)

The form should look something like this:
Creating custom forms

Items Screen

Expand the Items Screen and then select the galItems. Notice that the Layout property is Title, subtitle, and body. Now, click on Edit by the Fields property. I want to change ours to Serial Number for lblSerialNumber, Model for lblModel.
Expending Item Screen

Item Details Screen

The last thing that I need to do is complete the Item Details Screen to show a read-only version of the Item record.
Expand the Item Details Screen and select the frmItemDetails. Click on Edit Fields and add the custom fields created in Microsoft Dataverse.
Detailed Item Screen

Next, rearrange the field to match our edit form. Delete the Created-On field if desired.
Customize Field to match Edit form

Click on the Date Purchased value, click Advanced, and Unlock. Change the Text value to:

      DateValue(Parent.Default)
 

This will hide the time as it is not relative. For more information, see DateValue, TimeValue, and DateTimeValue functions in Power Apps.
Adjusting Date Purchased capability

Testing the User Interface

Now, I can test out the implementation:

Next Steps

With our base UI in place, I can enter data; however, there are a couple of final touches that need to be completed. In part three of the series, I will be adding the ability to add item images and barcode scanning.

This blog series is for anyone trying to learn how to use the Power Platform. Readers should know software development fundamentals. It begins by explaining why we would want to create a home inventory system. It then takes the reader over the requirements of the system, including potential future enhancements. It takes time to explain the database model and how it translates into tables in the Microsoft Dataverse. This post concludes with a review of the User Interface mockup.

The blog series assumed the following:

  • You have a Power Apps tenant with administrative privileges
  • You have knowledge of software development fundamentals

Why Create a Home Inventory?

Several years ago, I started considering the number and value of technical assets I had obtained over the years. I wondered what would happen if I were robbed, had a fire, or some other disaster; and found myself wondering if my insurance would cover all my technical assets? According to Consumer Reports:

“having a list or a visual reminder of your belongings can make a big difference in how much your homeowners’ insurance will pay, and thus how well you’ll recover financially.”

At the time, I purchased Quicken Home Inventory Manager, which was adequate at the time; however, advancements in technology have made it obsolete. I want to use my phone and its many capabilities for data entry instead of walking back-and-forth to the computer. I set out designing my home inventory system using the Power Platform with these things in mind.

Requirements

The requirements of the initial system are straight forward:

  • The system should include a phone app for data entry and a web interface for administration
  • Phone and Admin Apps should provide the ability to create, update and delete Items
    • Columns: Name, Description, Item Type, Manufacturer, Serial Number, Model Number, Location, Date Purchased, and Approx. Value, Image
    • Required columns: Name, Model Number, Item Type, Manufacturer, Location, and Image
    • Item Type will look up from the Item Types table
    • The manufacturer will look up from the Manufacturers table
    • Location will look up from the Locations table
    • Users should be able to add an Item Image
  • Phone and Admin Apps should provide the ability to create Item Types
    • Columns: Name
    • Required columns: Name
  • Phone and Admin Apps should provide the ability to create Manufacturers
    • Columns: Name, Support URL, and Support Phone
    • Required columns: Name
    • Support URL should be validated
    • Support Phone should be validated
  • Phone and Admin Apps should provide the ability to create Locations
    • Columns: Name
    • Required columns: Name
  • Admin App should provide the ability to create, update and delete Item Types
  • Admin App should provide the ability to create, update and delete Locations
  • Admin App should provide the ability to create, update and delete Manufacturers
  • The system should allow Admins to export the inventory

Future Enhancements

In addition to the requirements, there are some future enhancements or “nice to haves” that I can investigate adding to the system later, for example:

  • Bar code Scanner – for items with a bar code, it would be helpful to scan these automatically. This could be for serial numbers, model numbers, or even UPC for the entire item.
  • Photo of Receipt – item would be a nice feature to include a picture of the receipt for proof-of-purchase and returns.
  • AI – While this is a tall order, it would be neat to take a picture of an item and have it recognized what kind of item it is, perhaps even determine its Item Type.

The Database Model

Using the requirements above, I can derive a simple database model. There is an Item table that contains most of the data. Each Item record may have 0 or more Image records. Each Item will also have a lookup to a Manufacturer (ex. Microsoft, Sony, etc.), a Location (ex. Master Bedroom, Living Room, etc.), and an ItemType (ex. Appliance, Networking, Computer, etc.).

Database Model

The Dataverse Tables

Using the database model above, I can create custom tables for the system in the Microsoft Dataverse. Due to requirements in the Microsoft Dataverse, I will need to add a Name column to the Image table; I will want to handle this name’s generation when I implement the Item Images part of the application. Below is the resulting data model summary.

Dataverse Table

User Interface Mockup

For the user interface, I will begin with the phone app and develop the administration app later. As data gets added to the system, I will do this because I may discover challenges and new ideas. Additionally, the mockup below does not include the Item Image library, as I will cover it in a separate post. The user interface below begins with the Items screen. Here, users can search, sort, and scroll through items in the system. From the Items screen, a user can view or create a new Item. When a user views an item, they can delete it or edit it. If the user creates or edits an item, they use the same screen; they can also create new Item Types and Manufacturers from this screen. On all screens, cancel, save, and delete actions return to the previous screen. You may notice that the Item Image is not included; this is because I will be adding this later in the series when I start using the phone. For now, I am focusing on the base implementation.

User Interface Mockup

Next Steps

With the requirements defined and tables created in the Microsoft Dataverse, I can now work on the User Interface. In part two of the series, I will create all the necessary screens for the phone app and begin data entry.

I am currently working as a development operation engineer at a client that maintains a large and complex infrastructure with an even more complicated development workflow. Cloud infrastructure had already been provisioned, and several development cycles had been completed when I joined the team a couple of years ago. As a result, I came into an environment that had already established a development workflow, with barely any infrastructure as code (IaC) practices in place.

What is unique about this client is that it maintains six separate web applications, each designated for a different area in the United States; the backends for each application vary from application to application, but the front ends are mostly similar. To avoid a maintenance nightmare, we use code from one repo to deploy the main UI of all six applications; the same code is deployed to each application but configured to run differently through a master configuration file. Each web application is compromised of several sub-applications, each with its codebase.

One of my responsibilities is to spin up and maintain application stacks for new development teams that are working on a specific feature for this client. That feature may or may not be utilized by all six web applications. For this team to develop rapidly, they need a stable testing environment, equipped with continuous delivery, to do their work.

This “application stack” is comprised of:

  • 1 Azure App Service Plan
  • 1 App Service (up to 6)
  • 1 Redis Cache
  • 1 Storage Account

These are Microsoft Azure constructs and are not essential to understand in the context of this post. Keep in mind that 6 separate applications utilize a set of shared resources.

Since the DevOps team at this particular client is small, we were only able to create a script to deploy an application stack for a specific development effort, but we did not get the chance to implement any strategies around maintaining these stacks once they were deployed. As a result, we are applying configurations that need to be applied across the 25-30 application stacks that we maintain has turned out to be a logistical nightmare.

Model 1 Main App RepoThe diagram above represents a high-level overview of a single application stack that we need to maintain; the diagram is scaled down from 6 applications to 3 applications for clarity.

The current script we use to provision application stacks does the following:

  1. Creates all Azure resources
  2. Performs KeyVault configuration
    1. Enabled managed identity on all app services
    2. Adds access policy to the key vault for all app services
    3. Adds key vault references for secret app settings on all app services
  3. Creates 1 Azure DevOps release pipeline to deploy code to all app services; this is done by cloning a base template for a release pipeline that exists before the script is run.

The Problem

Although the deployment script that is currently in use saves time, it falls short on a few things:

If we want to make configuration changes across all the application stacks, we would have to make edits to the deployment script and rerun it on each application stack. This process is entirely too manual and can be improved.

  1. If we want to change the mechanics of how the underlying deployment pipeline functions across all the application stacks, we have to make edits on each deployment pipeline that is tied to a given application stack. This is too tedious and leaves lots of room for error; we initially mitigated some of this by utilizing Azure DevOps task groups.
  2. Configuration drift is widely prevalent; because we do not have an easy way to maintain all of the application environments across the board, minor configuration changes during development are difficult to track and often fail to propagate to our main application stacks.
  3. The Solution: TEMPLATE YOUR LIFE

Azure YAML Templates

This client is relatively young in terms of their cloud journey, especially with Azure and Azure DevOps. They currently rely heavily on Release Pipeline User Interface within Azure DevOps to deploy code to their applications. In recent years, Azure has been subtly urging teams to utilize multi-stage YAML templates instead of the Release Pipeline User Interface to adopt an “infrastructure as code” mindset to the continuous delivery process. With this mindset, there is no difference between “Build” pipelines and “Release” pipelines; the only construct is a pipeline where you can perform any task (build, test, deploy, etc.).

I encourage you to read more about Azure DevOps YAML templates. I’ve included some relevant links below:

Azure DevOps YAML Templates
Azure DevOps Multistage YAML UI Experience
YAML Schema

Given the problem statement above, there is a large need to develop a framework and process around maintaining the cloud infrastructure and its respective continuous delivery process that is easy to manage and propagate changes through.

This is where Azure DevOps YAML templates become useful.

All you need to create a pipeline in Azure DevOps is a YAML file. This YAML file can exist in any code repository. Once this file is imported into a code repository, you can use the Azure DevOps UI to create a pipeline from this file. While you can run the pipeline from the Azure DevOps UI, the pipeline’s changes will be maintained and version within the YAML file itself, just like you would with any application code.

This YAML file can inherit and reference another YAML file that exists in other code repositories.

Template Repository

I am currently developing a code repository that will contain:

  1. Azure ARM templates to version app service configurations (including virtual/sub applications)
  2. Deployment script to deploy ARM templates mentioned above
  3. Azure DevOps YAML files that will function as “release pipelines”:
    1. Create / Refresh shared resources
    2. Create / Refresh app services
    3. Deploy code to app services

When a new workstream or development effort begins, all they need to do is create a simple YAML file that extends from the main (release.yaml) template file in the repo mentioned above (see azurepipeline.yaml below). Once that is done, the first time the development team pushes code to a specified branch, they will be equipped with a new environment with their code changes.

Hierarchy of the Templates

The diagram above represents the hierarchy of the templates in the code repository mentioned above. You can see there are only 7 YAML template files to maintain. The azurepipeline.yaml file inherits these template files. This helps address the challenge mentioned above related to the daunting task of maintaining 25+ release pipelines; changes made to any of the template files will propagate to any azurepipeline.yaml files that inherit from the release.yaml file.

The idea is that we can import the azurepipeline.yaml file that can be into any repo or branch. This file is relatively simple:

azurepipeline.yaml

# run on schedule instead of utilizing ci triggers
name: $(Date:yyyyMMdd)$(Rev:.r)
trigger:
- none
  # pipeline artifact list (previously source artifacts in release pipeline)
extends:
  template: release.yaml@templates

The release.yaml file that the azurepipeline.yaml file extends from looks similar to the one below:

release.yaml

resources:
  # script and template reference
  repositories:
    - repository: templates
      type: git
      name: template-repo
  pipelines:
    - pipeline: main
      project: ExampleProject
      source: YAML\main
      branch: stage
    - pipeline: subapp1
      project: ExampleProject
      source: YAML\subapp1
      branch: stage
    - pipeline: subapp2
      project: ExampleProject
      source: YAML\subapp2
      branch: stage
stages:
- stage: SHARED
  dependsOn: []
  displayName: refresh shared resources
  jobs: 
  - job: refresh_shared_resources
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - template: templates/update-infrastructure.yaml@templates
        parameters:
          sharedOnly: true
- stage: APP1
  dependsOn: ['SHARED']
  variables:
  - template: templates/appvars.yaml@templates
    parameters:
      appName: 'app1'
  displayName: app1 
  jobs: 
  - job: REFRESH_APP1
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - template: templates/update-infrastructure.yaml@templates
        parameters:
          sharedOnly: true
          appName: app1
  - template: templates/app1.yaml@templates
- stage: APP1
  dependsOn: ['SHARED']
  variables:
  - template: templates/appvars.yaml@templates
    parameters:
      appName: 'app1'
  displayName: app1 
  jobs: 
  - job: REFRESH_APP1
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - template: templates/update-infrastructure.yaml@templates
        parameters:
          sharedOnly: true
          appName: app1
  - template: templates/app1.yaml@templates

App stages are created for each app (not shown).

The app template files referenced by the release.yaml file looks similar to the file below:

appl.yaml

jobs:
- deployment: app1
  dependsOn: REFRESH_APP1
  displayName: "DEPLOY APP1"
  environment: stage
  pool:
    vmImage: windows-latest    
  strategy:
    runOnce:
      deploy:
        steps:
        - checkout: self
        - template: configure-app.yaml@templates
        - template: deploy-app.yaml@templates
          parameters:
            isVirtualApp: false
            appName: 'ui'
        - template: deploy-app.yaml@templates
          parameters:
            isVirtualApp: true
            appName: 'subapp1'
        - template: deploy-app.yaml@templates
          parameters:
            isVirtualApp: true
            appName: 'subapp2'

Take note of the different steps that are used to deploy an application. It comprises a configuration step and a deployment step for each sub-application that utilizes the same azure YAML template file with different parameters.

The release.yaml file results in a multi-stage YAML pipeline that looks like the one below:

Release.yaml file results

Resources

The resource section of the template defines what resources your pipeline will use; this is analogous to the artifact section in the release pipeline UI view. You can only have the resources section declared once in your series of templates for a given pipeline. In the example above, it is defined in the release.yaml file, the template that other templates will extend from.

In this example, the resource section references the template repository itself and other build pipelines that produce code artifacts that we will need to deploy to our applications.

Defining the resources section in the base template (release.yaml) allows us to be abstract the choice of artifact sources away from the end-user. This is advantageous if we want to add more sub-applications to our release pipeline; we would only need to change the release resources section.yaml file (changes will propagate to all inherited/extended pipelines).

At the client I work with; this is problematic. In the solution above, all pipelines that extend from release.yaml (that contains the resources section) is limited to only use the specific artifacts AND the branches they are set to pull from, as defined in the base template (release.yaml). We consistently have project teams that need sub-application artifacts from specific branches that their development work exists on. To solve this, we moved the resources section into the extended template (azurepipeline.yaml). However, this isn’t optimal because we would still need to update every comprehensive template if we wanted to add to the resources section across all application stacks.

As far as I know, there is no way to use pipeline variables or template expressions to determine what resource artifacts are needed dynamically. Keep the resources section in the base template and override them within the extended templates.

Dynamic Insertion
Currently, we must maintain a manifest that describes the relationship between each application and its respective sub-applications. For example, app1 could have sub-applications subapp1 and subapp2, and app2 could have sub-applications subapp1 and subapp3 (or any combination of sub-applications). We utilize a JSON file that defines the mappings between application and sub-application. This JSON file is parsed in the deployment script to ensure the correct sub-applications exist before code deployment; in Azure, the sub-application must live before you push code to it. As a result, we also need to maintain sub-applications in each of the different YAML step templates for each application. At this point, I am unaware of an elegant way to iterate over an Azure DevOps pipeline variable to create steps dynamically.

Variable Templates
Template expressions can be applied to variables. This was extremely useful in the context of the solution I was trying to solve. For example, each stage in the pipeline described above is for a particular application with a distinct name. This name is used to determine several properties for its respective pipeline stage. For example, the app1 pipeline stage uses the site name/url app1.azurewebsites.net. The app2 stage uses the site name/url app2.azurewebsites.net. You can see both site names follow the same naming convention. This is a great use case for a variable template.

Here is the variable template I used:

appvars.yaml

parameters:
  appName: ""
  deployToSlot: false
variables:
  siteName: "$(tier)-$(region)-$(app)-${{parameters.appName}}"
  ${{ if eq(parameters.deployToSlot, true) }}:
    corsOrigin:"https://${{parameters.appName}}-$(slotName).azurewebsites.net"
  ${{ if eq(parameters.deployToSlot, false) }}:  
    corsOrigin: “https://${{parameters.appName}}.azurewebsites.net"
  appName: ${{parameters.appName}}
  template: "$(System.DefaultWorkingDirectory)/arm_templates/azuredeploy.json"
  virtualApps: "$(System.DefaultWorkingDirectory)/manifest.json"

You can see that I’ve included a parameters section that takes in appName as a parameter. You can see it in the release.yaml file, this parameter is being applied with:

variables:
  - template: templates/appvars.yaml@templates
    parameters:
      appName: 'app1'

This allows us to cut down on repeated code by using an extendable template for the variables needed for each deployment stage. It is essential to understand how variables and parameters work in Azure pipelines and the different ways they can be expressed in your YAML.

Check out these resources:
YAML Variables Documentation
YAML Parameters Documentation
Developer Community Forum Post

Conclusion

Development operation decisions should be considered in architecture design. In the scenario described above, the architecture I inherited did not foster the most efficient development and deployment workflow. For example, the decision to have sub-applications exist on an individual app service instead of assigning them to their app services. This limited us to deploy the individual applications in series, as you are limited to run one deployment at a time to give app service.

Infrastructure as code implemented in the continuous integration and delivery process can be equally as important as implementing it for your existing infrastructure.

Suppose you are working on a project that requires a complicated development lifecycle with multiple teams needing distinct environments. In this case, it becomes increasingly important to formulate a strategy around maintaining the various environments. Environment creation and code deployment should be as automated as possible. Applying configurations across all environments should be an easy task.

The Dockerfile development workflow is fantastic if you are familiar with the documentation and have spent a lot of time troubleshooting. However, if you are writing your first Dockerfile, it may be challenging to identify and debug certain cases.

During my first foray into the world of containers, I was containerizing a React Application. As I got comfortable copying the correct files into the image and making sure I was running things correctly, I ran the “docker build .” command multiple times. Suddenly, I noticed that my computer was giving me warnings that it was running out of storage! In this article, I will be discussing the concept of a Dangling Container when creating your Dockerfile, and we can finally find out what is taking up so much space on your machine!

What is a Dockerfile?

To quickly recap, a Dockerfile allows you to customize any image to fit your needs. You can add packages, run servers, the possibilities are endless! You start with a base image, i.e. Microsoft Container Registry’s official dotnetcore3.1 image. Then, go through various steps inside of a text document that is parsed by the Docker Engine. Eventually, you have your application running on a container image that has your application. The Docker daemon will read the Dockerfile, and perform whatever tasks you have described in said Dockerfile. Each time a step is run inside a Docker Container – It is a run in an Intermediate Container. Intermediate containers allow Docker to be very efficient in caching, as layers of the intermediate containers make up your final image.

Here is the Dockerfile I will be running, and the application I am using is the simple example found of the reactjs site.

Dockerfile example

Inside my console, I can run “docker build .” and everything will run completely fine, as shown here:

removing intermediate containers

You will notice that the container I have successfully built is a GUID. I did not provide my Docker build step with a tag, provided with the -t flag after the Docker build command. I ran “docker build .” one more time and I have two images of 1.15GB in size.

GUID

However, this isn’t the full story – the intermediate containers are also saved along with your containers themselves. You can see them with the “docker images -a” command.

Docker images -a

As you can see here, I have occupied roughly ~8 GB of Storage when trying to run these containers within approximately the past fifteen minutes of development. During a long project, a microservices architecture running on containers, for example, it is possible to accumulate a significant amount of storage space. Dangling images themselves can be seen here with this command “docker images -f dangling=true”

Docker images prune

In this case, since I missed the -t tag initially, my images are essentially dangling images. They are not associated with a repository.

Finally, to clean up my dangling images, all I need to run is “docker images prune”

Docker images

Developing with Dockerfiles can be difficult, and it can be daunting to step into the world of containers. Remember to prune often, and make sure you tag your images!

Microsoft Power Platform: Application Development Platform for General Purpose Business Apps

In recent years, with the transition to the cloud, SharePoint teams’ recommendation has been to move custom functionality “down” to the client computer or “over” to a host outside of SharePoint. This change has had a direct impact on enterprises that have long viewed SharePoint as an application development platform.

Today’s best practices show that a grouping of applications, such as case management apps, inventory or issue tracking, and fleet management (depicted in the dotted area of the diagram below) is no longer best suited to be built on top of SharePoint. This is where Microsoft Power Platform comes in for cross-platform app development.

Microsoft Power Platform as an app development platform

What is the Microsoft Power Platform (MPP)?

Microsoft Power Platform (or MPP) is being seen as the aPaaS layer that nicely complements mature Azure IaaS and PaaS offerings. Here are a few reasons we’re excited about MPP:

  • It offers a low-code/no code solution for rapid application development
  • The Power Apps component supports cross-platform app development for mobile and responsive web application solutions
  • Flow within MPP also offers a workflow and rules capability for implementing business processes
  • CDS offers a service for storing business objects

SharePoint as an App Development Platform

On January 30, 2007, we released a paper called “SharePoint as an Application Development Platform” to coincide with the release of Microsoft Office SharePoint Server 2007 or MOSS. We didn’t have the slightest expectation that this paper would be downloaded over half a million times from our website.

Based on the broad themes outlined in this paper, we went on to develop several enterprise-grade applications on the SharePoint platform for commercial as well as public sector enterprises. Of course, anyone who participated in SharePoint development in 2007 and onwards can vouch for the excitement around the amazing adoption of SharePoint.

Features, Add-Ins or “Apps,” and More

A few years later, SharePoint 2010 was announced with even more features that aligned with the application development platform theme. In 2013, the SharePoint team went on to add the notion of apps (now called add-ins) – we even wrote a book on SharePoint Apps. The most recent version of SharePoint is 2019 and it continues the tradition of adding new development capabilities.

All the Ingredients for Unprecedented Success

If you look back, it is easy to see why SharePoint was so successful. SharePoint was probably the first platform that balanced self-service capabilities with IT governance. Even though the underlying SharePoint infrastructure was governed by IT, business users could provision websites, document libraries, lists, and more in a self-service manner.

Compare this to the alternative at that time, which was to develop an ASP.NET application from scratch and then having to worry about operationalizing it including backup, recovery, high availability, etc. Not to mention the content and data silo that may result from yet another application being added to the portfolio.

Furthermore, the “Out of the Box” (OOTB) SharePoint applications constructs including lists, libraries, sites, web parts, structured and unstructured content, granular permissions, and workflows allowed developers to build applications in a productive manner.

With all these ingredients for success, SharePoint went on to become an enterprise platform of choice with close to 200 million licenses sold and, in the process, creating a ten-billion-dollar economy.

By 2013, Signs of Strain Emerged for SharePoint as an App Development Platform

With the transition to the cloud and lessons learned from early design choices, weaknesses in SharePoint as an app development platform started to show. Here are some examples:

  • Limitations around structured data – Storing large lists has always been challenging, despite the improvements over the years to increased scalability targets for lists. Combine scalability challenges with the query limitations and it makes for a less than ideal construct for general-purpose business application development.
  • Isolation limitations – SharePoint was not designed with isolation models for custom code. As a result, SharePoint farm solutions that run as full-trust solutions on the server side have fallen out of favor. The introduction of sandbox mode didn’t help since isolation/multi-tenancy was not baked in the original SharePoint design. The current recommendation is to build customizations as add-ins that run on the client side or on an external system.
  • External data integration challenges – BDC (Business Data Services) was designed to bring data from external systems into SharePoint. Business Connectivity Services (BCS) extensibility model was designed to allow an ecosystem of third-party and custom connectors to be built. But BCS never gained significant adoption with limited third-party support. Furthermore, BCS is restricted in the online model.
  • Workflow limitations – Workflows inside SharePoint are based on Windows Workflow Foundation (WF). WF was designed before the REST and HTTP became the lingua franca of integration over the web. As a result, even though SharePoint-based workflows work well for a document-centric workflow like approval, they are limited when it comes to integrating with external systems. Additionally, the combination of WF and SharePoint has not been the easiest thing to debug.
  • Lack of native mobile support – SharePoint was not designed for mobile experiences from the ground up. Over the years, SharePoint has improved the mobile experience through the support for device channels. Device channels allow for selection of different master pages and style sheets based on the target device. But device support is limited to publishing pages and even those require non-trivial work to get right. In a mobile-first world, a platform built with mobile in mind is going to be the ideal cross-platform app development tool for enterprises.
  • Access Services (and other similar services) never took off – Access databases are quintessential examples of DIY Line of Business (LOB) Apps. So when SharePoint 2010 introduced a capability to publish Access databases to SharePoint, it sought to offer the best of both worlds, self-service combined with governance (the latter being the bane of access databases). However, that goal proved too good to be true and Access Services never caught on and are now being deprecated.
  • Development “cliffs” – SharePoint was supposed to enable business users to build their own customizations through tools like Visio and SharePoint designer. The idea was that business users would be able to build customizations themselves using SharePoint designer and if they ran into a limitation (or the “cliff”), they could export their artifacts into a professional development tool like Visual Studio. In reality, this dichotomy of tools never worked and you almost always had to start over.
  • State of art in-low / no-code development – If you look at leading high-productivity application development platforms, the state of art seems to be around a declarative model-driven application approach. In other words, using a drag and drop UI, a user can generate a metadata-based configuration that describes the application, flow of application pages, etc. At runtime, the underlying platform interprets this configuration and binds the actions to the built-in database. SharePoint obviously has a rich history of offering no-code solutions, but it is not based on a consistent and common data model and scripting language.
  • Monolith versus micro-services – In many ways, SharePoint has become a “monolith” with tons of features packed into one product — content management, records management, business process, media streaming, app pages — you name it. Like all monoliths, it may make sense to break the functionality into “micro” services.

Note: With all the challenges listed above, SharePoint as a collaboration software continues to grow. In fact, it’s stronger than ever, especially when it comes to building collaboration-centric apps and solutions using the SharePoint framework and add-ins.

Just visit the thriving open source-based development centered around SharePoint Development to see for yourself.

Enter the Microsoft Power Platform (MPP)

The below diagram depicts a high-level view of the Microsoft Power Platform (MPP).

Microsoft Power Platform Infrastructure Overview

The “UI” Layer: Power Apps, Power BI, and Flow

At the highest level, you have the Power Apps, Power BI, and Flow tools.

Power Apps is a low-code platform as a service (PaaS) solution that allows for business app development with very little code. These apps can be built with drag and drop UI elements that work across mobile, tablet, and web form factors. In addition to the visual elements, there’s an Excel-like language called Power Apps Expression Language that’s designed to implement lightweight business logic and binding visual controls to data. Since Power Apps comes with a player for Android and iPhone devices, it doesn’t need to be published or downloaded from app stores.

Additionally, admin functions like publication, versioning, and deployment environments are baked into the Power Apps service. The PaaS solution can be used to build two types of apps:

  1. Canvas apps – as the name suggests, these allow you to start with a canvas and build a highly-tailored app.
  2. Model-driven apps – also as the name suggests, these allow you to auto-generate an app based on a “model” – business and core processes.

You’re likely already familiar with Power BI. It’s a business analytics as a service offering that allows you to create rich and interactive visualizations of sources of data.

Flow is a Platform as a Service (PaaS) capability that allows you to quickly implement business workflows that connect various apps and services.

Working together, Power Apps, Flow and Power BI allow for business users to easily and seamlessly build the UI, business process, and BI visualizations of a cross-platform, responsive business application. These services are integrated together to make the experience even better. As an example, you can embed a Canvas Power App inside of Power BI or vice versa.

The “Datastore and Business Rules” Layer

Common Database Service (CDS) allows you to securely store and manage data used by business applications. In contrast to a Database as a service offering like Azure SQL Database, think of CDS as a “business objects as a service”. Azure SQL Database removes the need for physical aspects of the database but as a consumer of Azure SQL, you’re still required to own the logical aspects of the data, such as schema, indexing and query optimization, and permissions.

In CDS all you do is define your business entities and their relationships. All logical and physical aspects of the database are managed for you. In addition, you get auditing, field level security, OData API, and rich metadata for free.

Finally, CDS offers a place to host “server-side” business rules in the form of actions and workflows. It’s important to note that CDS is powered by Dynamics CRM under the covers (see [1] for more information on this). This means that any skills and assets that your team has around Dynamics will seamlessly transition to CDS.

“External Systems Connector” Layer

Power Apps comes with a large collection of connectors that allow you to connect with a wide array of third-party applications and services (like SalesForce and Work Day) and bind the data to Power Apps visual controls. In addition, you can also connect to a custom app of service via Azure API Management and Functions.

How Can MPP Alleviate SharePoint Development Challenges?

MPP is a platform designed from the ground up for building business apps. Here’s how it can help alleviate the challenges users may experience with SharePoint as an app development platform.

Challenge SharePoint as a dev platform Power Platform
Structured Data Limits of items, throttling, and queries Backed by a fully relational model
Isolation No server-side isolation model. Server-based farm solutions are discouraged. Each tenant is isolated and allows for running custom code
External Data Integration BCS – limited third-party support 230+ connectors
Workflow Limitations Document-centric workflow HTTP REST based scalable workflow construct that can leverage OOTB connectors
Mobile Support Limited support in the form of device channels Designed from the ground up for mobile support
Development “Cliffs” Hard to transition from citizen dev to prod dev tools There a single tool for citizen developers and pro dev users. Pro dev users have the ability to use the extensibility to call Azure Functions, Logics Apps etc. for richer and complex functionality.
Low Code Development No common domain model or scripting language Designed from the ground-up as a low code development environment.
Monolith vs micro-services-based approach Monolith Comprised of a collection of “micro” services Power Apps, Flow, Power BI, CDS

Comparing Reference Architectures

The following diagram compares the SharePoint and MPP reference architectures.

SharePoint and MPP Reference Architectures Compared

Power Platform Components Inside SharePoint?

It’s noteworthy that advancements in MPP are available in SharePoint. For example, “standalone” Canvas Power Apps and Flow integrate directly into SharePoint are shown in the table below.

In many ways, this development represents a realignment of SharePoint’s place in the application development space. We believe that MPP is the new “hub”, while SharePoint (and other Office 365 components) represent “spokes” in this model.

Power Apps as a “custom form” for a SharePoint list item.

PowerApps as a custom form for a SharePoint list item example

Flow powering a document-centric workflow

Flow powering a document-centric workflow example

Consider MPP for Your Next Business App Development Project

The Microsoft Power Platform is an aPaaS offering that’s designed from the ground up as a general-purpose business application development platform, which includes native mobile support, first-class low-code environment, business data as a service, a lightweight workflow engine, and rich business analytics all in one. We believe that a category of applications, that were previously built on SharePoint will benefit in moving to the Microsoft Power Platform.

[1] xRM with Dynamics CRM

xRM style applications have been built on Dynamics CRM for years. Unfortunately, the licensing story to support this model was not ideal. For example, customers could not license a “base” version without paying for sales, marketing functionality built OOB.

That’s all changing with CDS. Power Apps licenses, such as P1 and P2, give customers access to what’s referred to as “Application Common” or Base instance of CDS.

CDS Apps Instance vs Dynamics Instance

Learn More About MPP & Your App Development Platform Options

The road to general-purpose business application development can be challenging to navigate with all of the tools and platforms available, as well as the unique pros and cons of each option. Not sure where to start? Start with a conversation!

START THE CONVERSATION
See if MPP is a good fit for your orgs app development needs. Contact your partner at AIS today!