Skip to content

Deployment

Jason Taylor edited this page Oct 3, 2022 · 3 revisions

This page provides basic instructions on how to deploy apps built using the template.

The template includes a built-in CI/CD workflow to automatically build, test, and deploy your app. This workflow has been built using GitHub Actions, so in order to leverage it, you will first need to create a new GitHub repository for your project. Once complete, follow the steps below to set up your environment and deploy your app to Azure. If you run into any problems, be sure to review the resources included at the end of this page.

Prerequisites

Install the following before continuing:

Sign in to Azure

Sign in to your Azure account using PowerShell and the Azure CLI:

az login --use-device-code

Create workload identities

Create two workload identities, one for your test environment and another for your production environment.

Define variables for your GitHub username and repository name:

$githubOrganizationName='jasontaylordev'
$githubRepositoryName='CleanArchitectureBlazor'

Create a workload identity for your test environment:

$testApplicationRegistrationDetails=$(az ad app create --display-name 'blazor-website-test') | ConvertFrom-Json
$testApplicationRegistrationObjectId=$testApplicationRegistrationDetails.id
$testApplicationRegistrationAppId=$testApplicationRegistrationDetails.appId

Create two federated credentials for the workload identity:

$credential = @{
  name="blazor-website-test";
  issuer="https://token.actions.githubusercontent.com";
  subject="repo:${githubOrganizationName}/${githubRepositoryName}:environment:Test";
  audiences=@("api://AzureADTokenExchange")
} | ConvertTo-Json

$credential | az ad app federated-credential create --id $testApplicationRegistrationObjectId --parameters "@-"

$credential = @{
  name="blazor-website-testbranch";
  issuer="https://token.actions.githubusercontent.com";
  subject="repo:${githubOrganizationName}/${githubRepositoryName}:ref:refs/heads/main";
  audiences=@("api://AzureADTokenExchange")
} | ConvertTo-Json

$credential | az ad app federated-credential create --id $testApplicationRegistrationObjectId --parameters "@-"

The first is used when the workflow runs the deploy job, the second is used when the workflow runs the validate job.

Create workload identity and federated credentials for the production environment:

$productionApplicationRegistrationDetails=$(az ad app create --display-name 'blazor-website-production') | ConvertFrom-Json
$productionApplicationRegistrationObjectId=$productionApplicationRegistrationDetails.id
$productionApplicationRegistrationAppId=$productionApplicationRegistrationDetails.appId

$credential = @{
  name="blazor-website-production";
  issuer="https://token.actions.githubusercontent.com";
  subject="repo:${githubOrganizationName}/${githubRepositoryName}:environment:Production";
  audiences=@("api://AzureADTokenExchange")
} | ConvertTo-Json

$credential | az ad app federated-credential create --id $productionApplicationRegistrationObjectId --parameters "@-"

$credential = @{
  name="blazor-website-productionbranch";
  issuer="https://token.actions.githubusercontent.com";
  subject="repo:${githubOrganizationName}/${githubRepositoryName}:ref:refs/heads/main";
  audiences=@("api://AzureADTokenExchange")
} | ConvertTo-Json

$credential | az ad app federated-credential create --id $productionApplicationRegistrationObjectId --parameters "@-"

Create resource groups and grant the workload identity access

First, create the test environment resource group and grant the workflow identity access:

$testResourceGroupResourceId=$(az group create --name CleanArchitectureTest --location australiaeast --query id --output tsv)

az ad sp create --id $testApplicationRegistrationObjectId

az role assignment create --assignee $testApplicationRegistrationAppId --role Contributor --scope $testResourceGroupResourceId

Next, create the production environment resource group and grant the workflow identity access:

$productionResourceGroupResourceId=$(az group create --name CleanArchitectureProduction --location australiaeast --query id --output tsv)

az ad sp create --id $productionApplicationRegistrationObjectId
														
az role assignment create --assignee $productionApplicationRegistrationAppId --role Contributor --scope $productionResourceGroupResourceId

Prepare GitHub secrets

Run the following code to show you the names and values you need to create as GitHub secrets:

echo "AZURE_CLIENT_ID_TEST: $testApplicationRegistrationAppId"
echo "AZURE_CLIENT_ID_PRODUCTION: $productionApplicationRegistrationAppId"
echo "AZURE_TENANT_ID: $(az account show --query tenantId --output tsv)"
echo "AZURE_SUBSCRIPTION_ID: $(az account show --query id --output tsv)"
echo "SQL_SERVER_ADMINISTRATOR_LOGIN_PASSWORD_TEST: SecurePassword!111"
echo "SQL_SERVER_ADMINISTRATOR_LOGIN_PASSWORD_PRODUCTION: SecurePassword!999"

The passwords above are examples only, be sure to set your own.

Browse to your GitHub repository and select Settings > Secrets > Actions. For each of the above secrets, select New repository secret and set the corresponding names and values.

Create environments in GitHub

Browse to your GitHub repository and select Settings > Environments. Create the following environments:

  • Test
  • Production

Deploy your app

Browse to your GitHub repository and select Actions and then the deploy-website-end-to-end workflow. The workflow can be triggered manually using the workflow_dispatch event trigger or automatically when you push a commit or tag.

Configure the IdentityServer signing certificate

Create a self-signed certificate within Azure KeyVault for Identity Server token signing. This is a manual process that must be completed for each environment, e.g. Test and Production. Once the certificate is set up in an environment, the process will not need to be repeated. I'd love to automate this process, so let me know if you can provide some guidance.

In the Azure Portal, browse to the relevant key vault (e.g. kv-CleanArchitecturetest) and select Certificates, then select Generate/Import to create a new certificate. Complete the Create a certificate form as follows:

image

Note that Subject should match the value specified within src/WebUI/Server/appsettings.json, for example:

image

Click Create and wait for the new self-signed certificate to be generated.

Next, browse to the relevant app service and select Certificates (preview), then select Bring your own certificates (.pfx), and then click Add certificate. Follow these steps:

  1. Set Source to Import from Key Vault
  2. Click Select key vault certificate
  3. Set the Subscription, Key vault, Certificate fields to the relevant values
  4. Click Select to select the signing certificate
  5. Click Validate and then Add to add the certificate to the app service

Once the certificate has been added, copy the Thumbprint value into your clipboard.

Next, you will add an application setting to make the certificate accessible to your application. Within the app service, select Configuration and click New application setting. Specify as follows:

  • Name WEBSITE_LOAD_CERTIFICATES
  • Value [certificate thumbprint]

Click OK to add the new setting and Save to save the changes are restart your application. Once the application has restarted, the application will be live.

Ensure you repeat these steps for each environment, e.g. Test and Production.

Resources

The following resources are highly recommended: