Tutorial: Deploy apps to Azure and Azure Stack

Applies to: Azure Stack integrated systems and Azure Stack Development Kit

Learn how to deploy apps to Azure and Azure Stack using a hybrid continuous integration/continuous delivery (CI/CD) pipeline.

In this tutorial, you'll create a sample environment to:

  • Initiate a new build based on code commits to your Azure DevOps Services repository.
  • Automatically deploy your app to global Azure for user acceptance testing.
  • When your code passes testing, automatically deploy the app to Azure Stack.

Benefits of the hybrid delivery build pipeline

Continuity, security, and reliability are key elements of app deployment. These elements are essential to your organization and critical to your development team. A hybrid CI/CD pipeline lets you consolidate your build pipes across your on-premises environment and the public cloud. A hybrid delivery model also lets you change deployment locations without changing your app.

Other benefits of using the hybrid approach are:

  • You can maintain a consistent set of development tools across your on-premises Azure Stack environment and the Azure public cloud. A common tool set makes it easier to implement CI/CD patterns and practices.
  • Apps and services deployed in Azure or Azure Stack are interchangeable and the same code can run in either location. You can take advantage of on-premises and public cloud features and capabilities.

To learn more about CI and CD:

Tip

hybrid-pillars.png
Microsoft Azure Stack is an extension of Azure. Azure Stack brings the agility and innovation of cloud computing to your on-premises environment. It is the only hybrid cloud that lets you build and deploy hybrid apps anywhere.

The white paper Design Considerations for Hybrid Applications reviews pillars of software quality (placement, scalability, availability, resiliency, manageability, and security) for designing, deploying, and operating hybrid applications. The design considerations assist in optimizing hybrid application design which minimize challenges in production environments.

Prerequisites

You need to have components in place to build a hybrid CI/CD pipeline. The following components will take time to prepare:

  • An Azure OEM/hardware partner can deploy a production Azure Stack. All users can deploy the Azure Stack Development Kit (ASDK).
  • An Azure Stack Operator must complete the following items: deploy the App Service, create plans and offers, create a tenant subscription, and add the Windows Server 2016 image.

Note

If you already have some of these components deployed, make sure they meet the all the requirements before starting this tutorial.

This tutorial assumes that you have some basic knowledge of Azure and Azure Stack. To learn more before starting the tutorial, read the following articles:

Azure requirements

  • If you don't have an Azure subscription, create a free account before you begin.
  • Create a Web App in Azure. Make note of the Web App URL, you need to use it in the tutorial.

Azure Stack requirements

  • Use an Azure Stack integrated system or deploy the Azure Stack Development Kit (ASDK). To deploy the ASDK:
    • The Tutorial: Deploy the ASDK using the installer article gives detailed deployment instructions.

    • Use the ConfigASDK.ps1 PowerShell script to automate ASDK post-deployment steps.

      Note

      The ASDK installation takes approximately seven hours to complete, so plan accordingly.

    • Deploy App Service PaaS services to Azure Stack.

    • Create Plan/Offers in Azure Stack.

    • Create a tenant subscription in Azure Stack.

    • Create a Web App in the tenant subscription. Make note of the new Web App URL for later use.

    • Deploy a Windows Server 2012 Virtual Machine in the tenant subscription. You'll use this server as your build server and to run Azure DevOps Services.

  • Provide a Windows Server 2016 image with .NET 3.5 for a virtual machine (VM). This VM will be built on your Azure Stack as a private build agent.

Developer tool requirements

Prepare the private Azure Pipelines agent for Azure DevOps Services integration

Prerequisites

Azure DevOps Services authenticates against Azure Resource Manager using a Service Principal. Azure DevOps Services must have the Contributor role to provision resources in an Azure Stack subscription.

The following steps describe what's required to configure authentication:

  1. Create a Service Principal, or use an existing Service Principal.
  2. Create Authentication keys for the Service Principal.
  3. Validate the Azure Stack Subscription via Role-Based Access Control to allow the Service Principal Name (SPN) to be part of the Contributor's role.
  4. Create a new Service Definition in Azure DevOps Services using the Azure Stack endpoints and SPN information.

Create a Service Principal

Refer to the Service Principal Creation instructions to create a service principal. Choose Web App/API for the Application Type or use the PowerShell script as explained in the article Create an Azure Resource Manager service connection with an existing service principal .

Note

If you use the script to create an Azure Stack Azure Resource Manager endpoint, you need to pass the -azureStackManagementURL parameter and -environmentName parameter. For example:
-azureStackManagementURL https://management.local.azurestack.external -environmentName AzureStack

Create an access key

A Service Principal requires a key for authentication. Use the following steps to generate a key:

  1. From App registrations in Azure Active Directory, select your app.

    Select the application - Azure Active Directory

  2. Make note of the value of Application ID. You'll use that value when configuring the service endpoint in Azure DevOps Services.

    Application ID - Azure Active Directory

  3. To generate an authentication key, select Settings.

    Edit app settings - Azure Active Directory

  4. To generate an authentication key, select Keys.

    Configure key settings - Azure Active Directory

  5. Provide a description for the key, and set the duration of the key. When done, select Save.

    Key description and duration - Azure Active Directory

    After you save the key, the key VALUE is displayed. Copy this value because you can't get this value later. You provide the key value with the application ID to sign in as the app. Store the key value where your app can retrieve it.

    Key VALUE - Azure Active Directory

Get the tenant ID

As part of the service endpoint configuration, Azure DevOps Services requires the tenant ID that corresponds to the AAD Directory that your Azure Stack stamp is deployed to. Use the following steps to get the tenant ID.

  1. Select Azure Active Directory.

    Azure Active Directory for tenant

  2. To get the tenant ID, select Properties for your Azure AD tenant.

    View tenant properties - Azure Active Directory

  3. Copy the Directory ID. This value is your tenant ID.

    Directory ID - Azure Active Directory

Grant the service principal rights to deploy resources in the Azure Stack subscription

To access resources in your subscription, you must assign the app to a role. Decide which role represents the best permissions for the app. To learn about the available roles, see RBAC: Built in Roles.

You can set the scope at the level of the subscription, resource group, or resource. Permissions are inherited to lower levels of scope. For example, adding an app to the Reader role for a resource group means it can read the resource group and any of its resources.

  1. Navigate to the level of scope you wish to assign the application to. For example, to assign a role at the subscription scope, select Subscriptions.

    Select Subscriptions - Azure Stack

  2. In Subscription, select Visual Studio Enterprise.

    Visual Studio Enterprise - Azure Stack

  3. In Visual Studio Enterprise, select Access Control (IAM).

  4. Select Add role assignment.

    Add role assignment - Azure Stack

  5. In Add permissions, select the role you that you want to assign to the app. In this example, it's the Owner role.

    Owner role permissions - Azure Stack

  6. By default, Azure Active Directory apps aren't displayed in the available options. To find your app, you must provide its name in the Select field to search for it. Select the app.

    App search result - Azure Stack

  7. Select Save to finish assigning the role. You can see your app in the list of users assigned to a role for that scope.

Role-Based Access Control

‎Azure Role-Based Access Control (RBAC) provides fine-grained access management for Azure. By using RBAC, you can control the level of access that users need to do their jobs. For more information about Role-Based Access Control, see Manage Access to Azure Subscription Resources.

Azure DevOps Services Agent Pools

Instead of managing each agent separately, you can organize agents into agent pools. An agent pool defines the sharing boundary for all agents in that pool. In Azure DevOps Services, agent pools are scoped to the Azure DevOps Services organization, which means that you can share an agent pool across projects. To learn more about agent pools, see Create Agent Pools and Queues.

Add a personal access token (PAT) for Azure Stack

Create a personal access token to access Azure DevOps Services.

  1. Sign in to your Azure DevOps Services organization and select your organization profile name.

  2. Select Manage Security to access token creation page.

    Manage Security - Azure Stack

  3. Click Add to create a new personal access token.

    Add Personal access token - Azure Stack

    Create token - Azure Stack

  4. Copy the token.

    Note

    Save the token information. This information isn't stored and won't be shown again when you leave the web page.

    Personal access token - Azure Stack

Install the Azure DevOps Services build agent on the Azure Stack hosted build server

  1. Connect to your build server that you deployed on the Azure Stack host.

  2. Download and deploy the build agent as a service using your personal access token (PAT) and run it as the VM admin.

    Download build agent

  3. Navigate to the folder for the extracted build agent. Run the config.cmd file from an elevated command prompt.

    Extracted build agent

    Register build agent

  4. When the config.cmd finishes, the build agent folder is updated with additional files. The folder with the extracted contents should look like the following example:

    Build agent folder update

    You can see the agent in Azure DevOps Services folder.

Endpoint creation permissions

By creating endpoints, a Visual Studio Online (VSTO) build can deploy Azure Service apps to Azure Stack. Azure DevOps Services connects to the build agent, which connects to Azure Stack.

NorthwindCloud sample app in VSTO

  1. Sign in to VSTO and navigate to the app settings page.

  2. In Settings, select Security.

  3. In Azure DevOps Services Groups, select Endpoint Creators.

    NorthwindCloud Endpoint Creators

  4. On the Members tab, select Add.

    Add a member

  5. On the Add users and groups page, enter a user name and select that user from the list of users.

  6. Select Save changes.

  7. In the Azure DevOps Services Groups list, select Endpoint Administrators.

    NorthwindCloud Endpoint Administrators

  8. On the Members tab, select Add.

  9. On the Add users and groups page, enter a user name and select that user from the list of users.

  10. Select Save changes.

Now that the endpoint information exists, the Azure DevOps Services to Azure Stack connection is ready to use. The build agent in Azure Stack gets instructions from Azure DevOps Services and then the agent conveys endpoint information for communication with Azure Stack.

Create an Azure Stack endpoint

Create an endpoint for Azure AD deployments

You can follow the instructions in Create an Azure Resource Manager service connection with an existing service principal article to create a service connection with an existing service principal and use the following mapping:

Name Example Description
Connection name Azure Stack Azure AD The name of the connection.
Environment AzureStack The name of your environment.
Environment URL https://management.local.azurestack.external Your management endpoint.
Scope level Subscription The scope of the connection.
Subscription ID 65710926-XXXX-4F2A-8FB2-64C63CD2FAE9 User subscription ID from Azure Stack
Subscription name name@contoso.com User subscription name from Azure Stack.
Service Principal client ID FF74AACF-XXXX-4776-93FC-C63E6E021D59 The principal ID from this section in this article.
Service Principal key THESCRETGOESHERE= The key from the same article (or the password if you used the script).
Tenant ID D073C21E-XXXX-4AD0-B77E-8364FCA78A94 The tenant ID you retrieve following the instruction at Get the tenant ID.
Connection: Not verified Validate your connection settings to the service principal.

Now that the endpoint is created, the DevOps to Azure Stack connection is ready to use. The build agent in Azure Stack gets instructions from DevOps and then the agent conveys endpoint information for communication with Azure Stack.

Build agent Azure AD

Create an endpoint for AD FS

The latest update to Azure DevOps lets you create a service connection using a service principal with a certificate for authentication. This connection is required when Azure Stack is deployed with AD FS as the identity provider.

Build agent AD FS

You can create a service connection using the following mapping:

Name Example Description
Connection name Azure Stack ADFS The name of the connection.
Environment AzureStack The name of your environment.
Environment URL https://management.local.azurestack.external Your management endpoint.
Scope level Subscription The scope of the connection.
Subscription ID 65710926-XXXX-4F2A-8FB2-64C63CD2FAE9 User subscription ID from Azure Stack
Subscription name name@contoso.com User subscription name from Azure Stack.
Service Principal client ID FF74AACF-XXXX-4776-93FC-C63E6E021D59 The client ID from the Service Principal you created for AD FS.
Certificate <certificate> Convert the certificate file from PFX to PEM. Paste certificate PEM file content into this field.
Converting PFX to PEM:
openssl pkcs12 -in file.pfx -out file.pem -nodes -password pass:<password_here>
Tenant ID D073C21E-XXXX-4AD0-B77E-8364FCA78A94 The tenant ID you retrieve following the instruction at Get the tenant ID.
Connection: Not verified Validate your connection settings to the service principal.

Now that the endpoint is created, the Azure DevOps to Azure Stack connection is ready to use. The build agent in Azure Stack gets instructions from Azure DevOps and then the agent conveys endpoint information for communication with Azure Stack.

Note

If your Azure Resource Manager endpoint is not exposed to the Internet, the connection validation will fail. This is expected and you can validate your connection by creating a release pipeline with a simple task.

Develop your application build

In this part of the tutorial you'll:

  • Add code to an Azure DevOps Services project.
  • Create self-contained web app deployment.
  • Configure the continuous deployment process

Note

Your Azure Stack environment needs the correct images syndicated to run Windows Server and SQL Server. It must also have App Service deployed. Review the App Service documentation "Prerequisites" section for Azure Stack Operator Requirements.

Hybrid CI/CD can apply to both application code and infrastructure code. Use Azure Resource Manager templates like web app code from Azure DevOps Services to deploy to both clouds.

Add code to an Azure DevOps Services project

  1. Sign in to Azure DevOps Services with an organization that has project creation rights in Azure Stack. The next screen capture shows how to connect to the HybridCICD project.

    Connect to a Project - Azure DevOps Services

  2. Clone the repository by creating and opening the default web app.

    Clone repository - Azure DevOps Services

Create self-contained web app deployment for App Services in both clouds

  1. Edit the WebApplication.csproj file: Select Runtimeidentifier and then add win10-x64. For more information, see Self-contained deployment documentation.

    Configure Runtimeidentifier

  2. Use Team Explorer to check the code into Azure DevOps Services.

  3. Confirm that the application code was checked into Azure DevOps Services.

Create the build pipeline

  1. Sign in to Azure DevOps Services with an organization that can create a build pipeline.

  2. Navigate to the Build Web Application page for the project.

  3. In Arguments, add -r win10-x64 code. This step is required to trigger a self-contained deployment with .NET Core.

    Add argument build pipeline

  4. Run the build. The self-contained deployment build process will publish artifacts that can run on Azure and Azure Stack.

Use an Azure-hosted build agent

Using a hosted build agent in Azure DevOps Services is a convenient option for building and deploying web apps. Agent maintenance and upgrades are automatically performed by Microsoft Azure, which enables a continuous and uninterrupted development cycle.

Configure the continuous deployment (CD) process

Azure DevOps Services and Team Foundation Server (TFS) provide a highly configurable and manageable pipeline for releases to multiple environments such as development, staging, quality assurance (QA), and production. This process can include requiring approvals at specific stages of the application life cycle.

Create release pipeline

Creating a release pipeline is the final step in your app build process. This release pipeline is used to create a release and deploy a build.

  1. Sign in to Azure DevOps Services and navigate to Azure Pipelines for your project.

  2. On the Releases tab, select [ + ] and then pick Create release definition.

    Create release pipeline - Azure DevOps Services

  3. On the Select a Template page, choose Azure App Service Deployment, and then select Apply.

    Apply template - Azure DevOps Services

  4. On the Add artifact page, from the Source (Build definition) pull-down menu, select the Azure Cloud build app.

    Add artifact - Azure DevOps Services

  5. On the Pipeline tab, select the 1 Phase, 1 Task link to View environment tasks.

    Pipeline view tasks - Azure DevOps Services

  6. On the Tasks tab, enter Azure as the Environment name and select the AzureCloud Traders-Web EP from the Azure subscription drop-down list.

    Set environment variables - Azure DevOps Services

  7. Enter the Azure app service name, which is "northwindtraders" in the next screen capture.

    App service name - Azure DevOps Services

  8. For the Agent phase, select Hosted VS2017 from the Agent queue drop-down list.

    Hosted agent - Azure DevOps Services

  9. In Deploy Azure App Service, select the valid Package or folder for the environment.

    Select package or folder - Azure DevOps Services

  10. On the Select File or Folder page, select OK for the folder location.

    Select file or folder - Azure DevOps Services

  11. Save all changes and go back to Pipeline.

    Save changes - Azure DevOps Services

  12. On the Pipeline tab, select Add artifact, and choose the NorthwindCloud Traders-Vessel from the Source (Build Definition) drop-down list.

    Add new artifact - Azure DevOps Services

  13. On the Select a Template page, add another environment. Pick Azure App Service Deployment and then select Apply.

    Select template - Azure DevOps Services

  14. Enter "Azure Stack" as the Environment name.

    Environment name - Azure DevOps Services

  15. On the Tasks tab, find and select Azure Stack.

    Azure Stack environment - Azure DevOps Services

  16. From the Azure subscription drop-down list, select "AzureStack Traders-Vessel EP" for the Azure Stack endpoint.

    Azure subscription drop-down - Azure DevOps Services

  17. Enter the Azure Stack web app name as the App service name.

    App service name - Azure DevOps Services

  18. Under Agent selection, pick "AzureStack -bDouglas Fir" from the Agent queue drop-down list.

    Pick agent - Azure DevOps Services

  19. For Deploy Azure App Service, select the valid Package or folder for the environment. On Select File Or Folder, select OK for the folder Location.

    Pick package or folder - Azure DevOps Services

    Approve location - Azure DevOps Services

  20. On the Variables tab, find the variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS. Set the variable value to true, and set its scope to Azure Stack.

    Configure variable - Azure DevOps Services

  21. On the Pipeline tab, select the Continuous deployment trigger icon for the NorthwindCloud Traders-Web artifact and set the Continuous deployment trigger to Enabled. Do the same thing for the "NorthwindCloud Traders-Vessel" artifact.

    Set continuous deployment trigger - Azure DevOps Services

  22. For the Azure Stack environment, select the Pre-deployment conditions icon set the trigger to After release.

    Set pre-deployment conditions trigger - Azure DevOps Services

  23. Save all your changes.

Note

Some settings for release tasks may have been automatically defined as environment variables when you created a release pipeline from a template. These settings can't be modified in the task settings. However, you can edit these settings in the parent environment items.

Create a release

Now that you've completed the modifications to the release pipeline, it's time to start the deployment. To begin deployment, create a release from the release pipeline. A release may be created automatically; for example, when the continuous deployment trigger is set in the release pipeline. Setting this trigger means that modifying the source code will start a new build and then a new release. However, in this section you'll create a new release manually.

  1. On the Pipeline tab, open the Release drop-down list and select Create release.

    Create a release - Azure DevOps Services

  2. Enter a description for the release, check to see that the correct artifacts are selected, and then select Create. After a few moments, a banner appears indicating that the new release was created, and the release name is displayed as a link. Select the link to see the release summary page.

    Release creation banner - Azure DevOps Services

  3. The release summary page for shows details about the release. In the following screen capture for "Release-2", the Environments section shows the Deployment status for Azure as "IN PROGRESS", and the status for Azure Stack is "SUCCEEDED". When the deployment status for the Azure environment changes to "SUCCEEDED", a banner appears indicating that the release is ready for approval. When a deployment is pending or has failed, a blue (i) information icon is shown. Hover over the icon to see a pop-up that contains the reason for delay or failure.

    Release summary page - Azure DevOps Services

Other views, such as the list of releases, will also display an icon that indicates approval is pending. The pop-up for this icon shows the environment name and more details related to the deployment. It's easy for an administrator see the overall progress of releases and see which releases are waiting for approval.

Monitor and track deployments

This section shows how you can monitor and track all your deployments. The release for deploying the two Azure App Services websites provides a good example.

  1. On the "Release-2" summary page, select Logs. During a deployment, this page shows the live log from the agent. The left pane shows the status of each operation in the deployment for each environment.

    Select the person icon in the Action column for a Pre-deployment or Post-deployment approval to see who approved (or rejected) the deployment, and the message they provided.

  2. After the deployment finishes, the entire log file is displayed in the right pane. Select any Step in the left pane to see the log file for a single step, such as "Initialize Job". The ability to see individual logs makes it easier to trace and debug parts of the overall deployment. You can also Save the log file for a step, or Download all logs as zip.

    Release logs - Azure DevOps Services

  3. Open the Summary tab to see general information about the release. This view shows details about the build, the environments it was deployed to, deployment status, and other information about the release.

  4. Select an environment link (Azure or Azure Stack) to see information about existing and pending deployments to a specific environment. You can use these views as a quick way to verify that the same build was deployed to both environments.

  5. Open the deployed production app in your browser. For example, for the Azure App Services website, open the URL https://[your-app-name].azurewebsites.net.

Next steps