Deploy ZavaStorefront On Azure: A Dev Environment Guide

by Alex Johnson 56 views

In this comprehensive guide, we will walk through the process of provisioning Azure infrastructure for the ZavaStorefront web application, specifically tailored for a development environment. Our approach focuses on modern deployment practices, robust monitoring, and leveraging Infrastructure as Code (IaC) to ensure consistency and repeatability. We'll cover everything from setting up the necessary Azure resources to deploying your application without requiring Docker on local developer machines.

Goal

The primary goal is to provision a complete Azure infrastructure for the ZavaStorefront web application, optimized for development purposes. This includes setting up the necessary compute, storage, and monitoring resources, all while adhering to best practices for security and scalability. By the end of this guide, you'll have a fully functional development environment that supports rapid iteration and testing.

Requirements

Before we dive into the implementation, let's outline the key requirements for our Azure infrastructure:

  • Region: All resources must be deployed in the westus3 region to ensure proximity and compliance.
  • Resource Group: All resources will be grouped into a single resource group dedicated to this environment, simplifying management and cost tracking.
  • Azure App Service for Linux: The ZavaStorefront web application will be deployed as a web app running on Linux, providing a flexible and cost-effective hosting platform.
  • Deployment via Docker: We will use Azure Container Registry (ACR) to store our Docker images, enabling seamless deployment to App Service. Crucially, we will avoid requiring Docker installation on developer machines by using Azure Developer CLI (AZD) and Bicep for deployment.
  • Azure RBAC: App Service must pull images from ACR using Azure Role-Based Access Control (RBAC), eliminating the need for passwords and enhancing security.
  • Monitoring: Application Insights will be integrated for comprehensive performance and health monitoring, providing insights into application behavior and potential issues.
  • AI Services: Microsoft Foundry resources for both GPT-4 and Phi will be provisioned, taking advantage of the availability in the westus3 region.
  • Infrastructure as Code: All resources will be defined and deployed using Bicep templates compatible with Azure Developer CLI (AZD), ensuring consistent and repeatable deployments.

Tasks

To achieve our goal, we will perform the following tasks:

  1. Define Bicep Modules: Create Bicep modules for each required Azure resource, including the Resource Group, Linux App Service, Azure Container Registry (with RBAC-enabled access for App Service), Application Insights, and Microsoft Foundry resources for GPT-4 and Phi.
  2. Implement azd CLI Workflow: Ensure the deployment workflow leverages the azd CLI for seamless and automated deployments.
  3. Secure ACR Image Pull: Confirm that the App Service can securely pull images from ACR using RBAC, without relying on passwords.
  4. Integrate Application Insights: Add monitoring via Application Insights to the web app, providing real-time insights into application performance and health.
  5. Document Usage and Local Development Steps: Document the necessary steps for local development, with a focus on avoiding Docker installation locally.

Detailed Implementation

Let's delve into the detailed implementation of each task. First, we'll define the Bicep modules for each Azure resource. These modules will serve as the foundation for our Infrastructure as Code (IaC) approach, enabling us to define and deploy our infrastructure in a repeatable and consistent manner. By utilizing Bicep, we gain access to a declarative language that simplifies the creation and management of Azure resources.

1. Define Bicep Modules

Bicep is an Infrastructure as Code (IaC) language that allows you to define Azure resources in a declarative manner. This approach ensures that your infrastructure is consistent and repeatable. Let's create Bicep modules for each required Azure resource.

Resource Group Module (main.bicep)

First, we define the resource group. This module is the foundation for all our resources, as it provides a logical container for them. By defining the resource group in Bicep, we can ensure that it is created with the correct settings and in the desired location. Here's a sample Bicep code for creating a resource group:

resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: 'zavastorefront-dev-rg'
  location: 'westus3'
}

output resourceGroupName string = rg.name

This Bicep code defines a resource group named zavastorefront-dev-rg in the westus3 region. The output statement exports the name of the resource group, which can be used by other modules.

Linux App Service Module (appservice.bicep)

Next, we define the Linux App Service. This module will create the web app that hosts the ZavaStorefront application. We'll configure it to run on Linux and integrate with Azure Container Registry (ACR) to pull the Docker image. Here's a sample Bicep code for creating a Linux App Service:

param appServiceName string
param location string
param containerRegistryDns string
param containerName string
param tag string

resource appServicePlan 'Microsoft.Web/serverfarms@2020-12-01' = {
  name: '${appServiceName}-plan'
  location: location
  sku: {
    name: 'B1'
    tier: 'Basic'
  }
  kind: 'Linux'
  properties: {
    reserved: true
  }
}

resource appService 'Microsoft.Web/sites@2020-12-01' = {
  name: appServiceName
  location: location
  kind: 'app,linux'
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      linuxFxVersion: 'DOCKER|${containerRegistryDns}/${containerName}:${tag}'
      appSettings: [
        {
          name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE'
          value: 'false'
        }
      ]
    }
  }
  dependsOn: [
    appServicePlan
  ]
}

output appServiceId string = appService.id

This Bicep code defines an App Service Plan and an App Service. The App Service is configured to run on Linux and pull the Docker image from the specified container registry. The dependsOn statement ensures that the App Service Plan is created before the App Service.

Azure Container Registry Module (acr.bicep)

We need an Azure Container Registry (ACR) to store our Docker images. This module will create the ACR instance and configure it to allow the App Service to pull images using Azure RBAC. This eliminates the need for storing passwords and enhances security. Here's a sample Bicep code for creating an ACR:

param acrName string
param location string

resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' = {
  name: acrName
  location: location
  sku: {
    name: 'Basic'
  }
  properties: {
    adminUserEnabled: false
  }
}

output acrId string = acr.id
output acrLoginServer string = acr.properties.loginServer

This Bicep code defines an ACR instance with a Basic SKU. The adminUserEnabled property is set to false to disable the admin user, which is not needed when using RBAC.

Application Insights Module (appinsights.bicep)

Monitoring is crucial for any application. This module will create an Application Insights instance and configure the App Service to send telemetry data to it. Here's a sample Bicep code for creating an Application Insights instance:

param appInsightsName string
param location string

resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: appInsightsName
  location: location
  kind: 'web'
  properties: {
    Application_Type: 'web'
    WorkspaceResourceId: '/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.OperationalInsights/workspaces/your-log-analytics-workspace'
  }
}

output appInsightsInstrumentationKey string = appInsights.properties.InstrumentationKey

This Bicep code defines an Application Insights instance. The WorkspaceResourceId property specifies the Log Analytics workspace to use for storing telemetry data. Make sure to replace the placeholder values with your actual subscription ID, resource group, and Log Analytics workspace name.

Microsoft Foundry Resources Module (foundry.bicep)

To leverage AI services like GPT-4 and Phi, we need to provision Microsoft Foundry resources. This module will create the necessary resources for both models. Here's a sample Bicep code for creating a Microsoft Foundry resource:

param gpt4ResourceName string
param phiResourceName string
param location string

resource gpt4Resource 'Microsoft.CognitiveServices/accounts@2023-01-01-preview' = {
  name: gpt4ResourceName
  location: location
  kind: 'GPT-4'
  sku: {
    name: 'S0'
  }
  properties: {
    apiProperties: {
      nonStandardApi: true
    }
  }
}

resource phiResource 'Microsoft.CognitiveServices/accounts@2023-01-01-preview' = {
  name: phiResourceName
  location: location
  kind: 'Phi'
  sku: {
    name: 'S0'
  }
  properties: {
    apiProperties: {
      nonStandardApi: true
    }
  }
}

output gpt4ResourceId string = gpt4Resource.id
output phiResourceId string = phiResource.id

This Bicep code defines two Microsoft Foundry resources, one for GPT-4 and one for Phi. The kind property specifies the type of resource, and the sku property specifies the pricing tier.

2. Implement azd CLI Workflow

Azure Developer CLI (AZD) simplifies the process of building and deploying applications to Azure. It provides a set of commands that automate common tasks, such as provisioning resources, deploying code, and setting up CI/CD pipelines. By using AZD, we can streamline our deployment workflow and reduce the risk of errors.

To use AZD, you need to create an azd.yaml file in the root of your project. This file defines the project's metadata, such as the name, location, and type. Here's a sample azd.yaml file:

name: zavastorefront
location: westus3

services:
  web:
    project: ./src/ZavaStorefront.WebApp
    language: js
    host: appservice

This azd.yaml file defines a project named zavastorefront in the westus3 region. It also defines a service named web, which corresponds to the ZavaStorefront web application. The project property specifies the location of the project's source code, the language property specifies the programming language, and the host property specifies the hosting platform.

3. Secure ACR Image Pull

To enable the App Service to securely pull images from ACR using RBAC, we need to assign the AcrPull role to the App Service's managed identity. This role grants the App Service the necessary permissions to pull images from ACR without relying on passwords. Here's a sample Bicep code for assigning the AcrPull role:

param appServicePrincipalId string
param acrId string

resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
  name: guid(appServicePrincipalId, acrId, 'AcrPull')
  scope: acrId
  properties: {
    roleDefinitionId: '/subscriptions/your-subscription-id/providers/Microsoft.Authorization/roleDefinitions/7f951dda-4ed3-4680-a7ca-43fe13541776'
    principalId: appServicePrincipalId
    principalType: 'ServicePrincipal'
  }
}

This Bicep code assigns the AcrPull role to the App Service's managed identity. The roleDefinitionId property specifies the ID of the AcrPull role, and the principalId property specifies the ID of the App Service's managed identity. Make sure to replace the placeholder value with your actual subscription ID.

4. Integrate Application Insights

To integrate Application Insights with the App Service, we need to add the APPINSIGHTS_INSTRUMENTATIONKEY application setting to the App Service. This setting tells the App Service to send telemetry data to the specified Application Insights instance. Here's a sample Bicep code for adding the APPINSIGHTS_INSTRUMENTATIONKEY application setting:

param appServiceName string
param appInsightsInstrumentationKey string

resource appService 'Microsoft.Web/sites@2020-12-01' existing = {
  name: appServiceName
}

resource appServiceAppSettings 'Microsoft.Web/sites/config@2020-12-01' = {
  name: 'appsettings'
  parent: appService
  properties: {
    APPINSIGHTS_INSTRUMENTATIONKEY: appInsightsInstrumentationKey
  }
}

This Bicep code adds the APPINSIGHTS_INSTRUMENTATIONKEY application setting to the App Service. The existing keyword tells Bicep that the App Service already exists, and the parent property specifies the App Service to which the setting should be added.

5. Document Usage and Local Development Steps

Finally, we need to document the necessary steps for using the ZavaStorefront development environment. This includes instructions for deploying the application, accessing the Application Insights dashboard, and performing local development without Docker. By providing clear and concise documentation, we can ensure that developers can quickly get up to speed and start contributing to the project.

Conclusion

In this guide, we walked through the process of provisioning Azure infrastructure for the ZavaStorefront web application, specifically tailored for a development environment. We covered everything from setting up the necessary Azure resources to deploying your application without requiring Docker on local developer machines. By following these steps, you can create a robust and scalable development environment that supports rapid iteration and testing. For further information on Azure deployment best practices, visit the Microsoft Azure Documentation.