Dockerize the API and run in AKS (#4)

This commit is contained in:
Jim Counts 2022-09-26 07:28:06 -07:00 коммит произвёл GitHub
Родитель 2c1d80ef2e
Коммит d67ae7f36a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
32 изменённых файлов: 228 добавлений и 81 удалений

63
.github/workflows/deploytoAksCluster.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
on: [push]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
ACR_LOGIN_SERVER: taw4acrjrc23a.azurecr.io
AKS_NAMESPACE: health-check
CONTAINER_IMAGE: taw4acrjrc23a.azurecr.io/humongous-healthcare-api:${{ github.sha }}
steps:
- uses: actions/checkout@master
- uses: azure/docker-login@v1
with:
login-server: ${{ env.ACR_LOGIN_SERVER }}
username: ${{ secrets.acr_username }}
password: ${{ secrets.acr_password }}
- name: Build and push image to ACR
id: build-image
run: |
docker build "$GITHUB_WORKSPACE/Humongous.Healthcare" -f "Humongous.Healthcare/Dockerfile" -t ${CONTAINER_IMAGE} --label dockerfile-path=Humongous.Healthcare/Dockerfile
docker push ${CONTAINER_IMAGE}
- uses: azure/k8s-set-context@v1
with:
kubeconfig: ${{ secrets.aks_kubeConfig }}
id: login
- name: Create namespace
run: |
namespacePresent=`kubectl get namespace | grep ${AKS_NAMESPACE} | wc -l`
if [ $namespacePresent -eq 0 ]
then
echo `kubectl create namespace ${AKS_NAMESPACE}`
fi
- uses: azure/k8s-create-secret@v1
with:
namespace: ${{ env.AKS_NAMESPACE }}
container-registry-url: ${{ env.ACR_LOGIN_SERVER }}
container-registry-username: ${{ secrets.acr_username }}
container-registry-password: ${{ secrets.acr_password }}
secret-name: dockerauth
- uses: Azure/k8s-create-secret@v1
with:
namespace: ${{ env.AKS_NAMESPACE }}
secret-type: 'generic'
secret-name: cosmosdb
arguments:
--from-literal=cosmosdb-account=${{ secrets.COSMOSDB_ACCOUNT }}
--from-literal=cosmosdb-key=${{ secrets.COSMOSDB_KEY }}
- uses: azure/k8s-deploy@v1.2
with:
namespace: ${{ env.AKS_NAMESPACE }}
manifests: |
manifests/deployment.yml
manifests/service.yml
images: |
${{ env.CONTAINER_IMAGE }}
imagepullsecrets: |
dockerauth

Просмотреть файл

@ -1,4 +1,4 @@
<h1>Win with App Innovation -- Contoso Healthcare Proof of Concept</h1>
<h1>Win with App Innovation -- Humongous Healthcare Proof of Concept</h1>
<h2>Before the hands-on lab</h2>

Просмотреть файл

@ -1,4 +1,4 @@
<h1>Win with App Platform -- Contoso Healthcare Proof of Concept</h1>
<h1>Win with App Platform -- Humongous Healthcare Proof of Concept</h1>
<h2>Hands-on lab</h2>
@ -14,9 +14,9 @@ September 2022
- [Before the hands-on lab](#before-the-hands-on-lab)
- [Exercise 1: Finish configuring Azure services and retrieve values](#exercise-1--finish-configuring-azure-services-and-retrieve-values)
- [Task 1: Create Cosmos DB container](#task-1-create-cosmos-db-container)
- [Exercise 2: Review and publish the Contoso Healthcare Web API service](#exercise-2--review-and-publish-the-contoso-healthcare-web-api-service)
- [Task 1: Review the Contoso Healthcare Web API service](#task-1--review-the-contoso-healthcare-web-api-service)
- [Task 2: Deploy the Contoso Healthcare Web API service to App Services](#task-2--deploy-the-contoso-healthcare-web-api-service-to-app-services)
- [Exercise 2: Review and publish the Humongous Healthcare Web API service](#exercise-2--review-and-publish-the-Humongous-healthcare-web-api-service)
- [Task 1: Review the Humongous Healthcare Web API service](#task-1--review-the-Humongous-healthcare-web-api-service)
- [Task 2: Deploy the Humongous Healthcare Web API service to App Services](#task-2--deploy-the-Humongous-healthcare-web-api-service-to-app-services)
- [Exercise 3: Configure continuous deployment with GitHub Actions](#exercise-3--configure-continuous-deployment-with-github-actions)
- [Task 1: Create and Edit a GitHub Action](#task-1--create-and-edit-a-github-action)
- [Exercise 4: Configure API Management](#exercise-4--configure-api-management)
@ -34,13 +34,13 @@ In this hands-on-lab, you will build a proof of concept for an Application Innov
## Overview
**Contoso Healthcare** is a global network of healthcare providers with presence throughout the industry. Contoso Healthcare wishes to drive a new Health Checks initiative, which specifically entails building a suite of health check applications for end users. These applications will allow users to submit information on their current health status and submit a questionnaire concerning any medical symptoms they might have experienced over the past 14 days.
**Humongous Healthcare** is a global network of healthcare providers with presence throughout the industry. Humongous Healthcare wishes to drive a new Health Checks initiative, which specifically entails building a suite of health check applications for end users. These applications will allow users to submit information on their current health status and submit a questionnaire concerning any medical symptoms they might have experienced over the past 14 days.
Contoso already uses a variety of Microsoft Azure services, taking advantage of both Infrastructure-as-a-Service and Platform-as-a-Service offerings. Their software engineers and infrastructure team have a good working familiarity with Azure services and wish to use this opportunity to develop an innovative product which can serve as a guide for future modernization of their existing applications and infrastructure.
Humongous already uses a variety of Microsoft Azure services, taking advantage of both Infrastructure-as-a-Service and Platform-as-a-Service offerings. Their software engineers and infrastructure team have a good working familiarity with Azure services and wish to use this opportunity to develop an innovative product which can serve as a guide for future modernization of their existing applications and infrastructure.
The Engineering team at Contoso Healthcare is looking for a modern, innovative application platform, but this is not the only key group which will be involved. Business Analysts will be responsible for creating the business logic and user experience for most of the Health Checks applications. ~~TODO These Business Analysts are not software developers, and they would like a low-code or no-code approach to application development without relying on Engineering.~~ These applications should be able to access API endpoints which the Engineering team plan to build.
The Engineering team at Humongous Healthcare is looking for a modern, innovative application platform, but this is not the only key group which will be involved. Business Analysts will be responsible for creating the business logic and user experience for most of the Health Checks applications. ~~TODO These Business Analysts are not software developers, and they would like a low-code or no-code approach to application development without relying on Engineering.~~ These applications should be able to access API endpoints which the Engineering team plan to build.
Contoso would like to manage one API for accessing the back end of all of these health applications. In practice, Contoso expects something on the order of 15-20 endpoints to support the breadth of their health check application suite, but for the purposes of a proof of concept, they would like to see two endpoints implemented: one which submits information on current health status and one which retrieves submissions for the registered user. The key data points Contoso would like to see in this proof of concept are as follows:
Humongous would like to manage one API for accessing the back end of all of these health applications. In practice, Humongous expects something on the order of 15-20 endpoints to support the breadth of their health check application suite, but for the purposes of a proof of concept, they would like to see two endpoints implemented: one which submits information on current health status and one which retrieves submissions for the registered user. The key data points Humongous would like to see in this proof of concept are as follows:
- Submission ID, generated by the system
- Patient ID, handled as part of a future authentication process. For the proof of concept, it would be okay for the end application to hard-code the patient ID
@ -48,9 +48,9 @@ Contoso would like to manage one API for accessing the back end of all of these
- Current health status (one of "I feel well" or "I feel unwell")
- A list of symptoms over the past 14 days, where each symptom is a free-form text entry with no validation
Contoso's Engineering team also wish to have all data stored in a single database, as this will simplify security and open up opportunities for their data scientists to analyze the data most efficiently. In addition, they would like to centralize management of any access points to the data. Different Engineering teams will work on separate API endpoints and they are interested in anything which can improve the coordination between teams. As far as data storage is concerned, the architects would like to see flexible data structures. The reason for this is that individual providers in their network often have differing requirements on what data they collect, depending on their specialization. The questionnaires which end users fill out will likely differ based on facility, mode of treatment, nation, and region. They may also change over time to support additional testing options, such as asking end users a subset of the questions sometimes or adding and removing questions from the survey applications.
Humongous's Engineering team also wish to have all data stored in a single database, as this will simplify security and open up opportunities for their data scientists to analyze the data most efficiently. In addition, they would like to centralize management of any access points to the data. Different Engineering teams will work on separate API endpoints and they are interested in anything which can improve the coordination between teams. As far as data storage is concerned, the architects would like to see flexible data structures. The reason for this is that individual providers in their network often have differing requirements on what data they collect, depending on their specialization. The questionnaires which end users fill out will likely differ based on facility, mode of treatment, nation, and region. They may also change over time to support additional testing options, such as asking end users a subset of the questions sometimes or adding and removing questions from the survey applications.
For this proof of concept, Contoso would also like to see a model example of Continuous Integration and Continuous Deployment (CI/CD) pipelines for code development and deployment.
For this proof of concept, Humongous would also like to see a model example of Continuous Integration and Continuous Deployment (CI/CD) pipelines for code development and deployment.
## Solution architecture
@ -58,13 +58,13 @@ The following diagram provides a high-level overview of the Azure services we wi
![High-level architecture, as described below.](media/architecture-diagram.png "High-level architecture")
API Management will allow Contoso Healthcare to centralize and manage information on a variety of API endpoints. These API endpoints may be implemented using a variety of Azure services, but the one which makes the most intuitive sense is Azure App Services. The serverless approach to Azure Function apps would fit Contoso's desire to limit dependencies on their operations staff, so it is also a good choice, but the Contoso developers already have experience developing Web API applications and can easily adapt that knowledge to App Services. ~~TODO API Management also allows developers and business analysts to create Power Apps from the Azure portal, making it easy to consume these exposed API endpoints.~~
API Management will allow Humongous Healthcare to centralize and manage information on a variety of API endpoints. These API endpoints may be implemented using a variety of Azure services, but the one which makes the most intuitive sense is Azure App Services. The serverless approach to Azure Function apps would fit Humongous's desire to limit dependencies on their operations staff, so it is also a good choice, but the Humongous developers already have experience developing Web API applications and can easily adapt that knowledge to App Services. ~~TODO API Management also allows developers and business analysts to create Power Apps from the Azure portal, making it easy to consume these exposed API endpoints.~~
To store and retrieve data, the functions will use Cosmos DB for data storage. This satisfies customer requests for a flexible schema and includes a rich .NET interface. Furthermore, via Cosmos Link, we can include an automated process to make data available in Azure Synapse Analytics dedicated SQL pools or Spark pools. This allows Contoso Healthcare data scientists to analyze data across a variety of end users over time without building extensive ELT pipelines or processes. Because this would be a "phase two" operation, it deserves mention in an architectural diagram but will not be part of the proof of concept.
To store and retrieve data, the functions will use Cosmos DB for data storage. This satisfies customer requests for a flexible schema and includes a rich .NET interface. Furthermore, via Cosmos Link, we can include an automated process to make data available in Azure Synapse Analytics dedicated SQL pools or Spark pools. This allows Humongous Healthcare data scientists to analyze data across a variety of end users over time without building extensive ELT pipelines or processes. Because this would be a "phase two" operation, it deserves mention in an architectural diagram but will not be part of the proof of concept.
For this solution, we used GitHub for source control and continuous integration/continuous deployment tasks. Azure DevOps is another viable alternative. After checking code in, a GitHub Action will deploy the .NET Web API code to an existing App Service, making changes and deployment straightforward. This also provides the opportunity to perform unit and integration testing against code before deploying the code, although that is out of scope of the proof of concept.
Azure Front Door is a layer 7 load balancer which includes web application firewall (WAF) capabilities. This allows Contoso to implement the [Gatekeeper architecture pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/gatekeeper) and secure their APIs against malicious traffic, including IP addresses from known bot networks. Contoso can use Azure-managed rule sets, as well as creating custom rule sets to monitor, redirect, or block traffic as configured.
Azure Front Door is a layer 7 load balancer which includes web application firewall (WAF) capabilities. This allows Humongous to implement the [Gatekeeper architecture pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/gatekeeper) and secure their APIs against malicious traffic, including IP addresses from known bot networks. Humongous can use Azure-managed rule sets, as well as creating custom rule sets to monitor, redirect, or block traffic as configured.
> **Note**: This proof of concept will not include the Azure Front Door or Synapse Analytics services.
@ -110,11 +110,11 @@ Refer to the [Before the hands-on lab setup guide](Before%20the%20Hands-On%20Lab
4. Select **OK** to create the container. This will take you to the Data Explorer pane for Cosmos DB.
## Exercise 2: Review and publish the Contoso Healthcare Web API service
## Exercise 2: Review and publish the Humongous Healthcare Web API service
### Task 1: Review the Contoso Healthcare Web API service
### Task 1: Review the Humongous Healthcare Web API service
1. Open the hands-on lab in Visual Studio Code and use the terminal to navigate to the `Contoso.Healthcare` project.
1. Open the hands-on lab in Visual Studio Code and use the terminal to navigate to the `Humongous.Healthcare` project.
2. Run the following commands in the terminal to restore and build the project, bringing in necessary packages.
@ -187,7 +187,7 @@ Refer to the [Before the hands-on lab setup guide](Before%20the%20Hands-On%20Lab
10. When you are done, use `Ctrl+C` to stop the dotnet service.
### Task 2: Deploy the Contoso Healthcare Web API service to App Services
### Task 2: Deploy the Humongous Healthcare Web API service to App Services
1. Open the Azure extension for Visual Studio Code. Navigate to the **App Service** menu and select your App Service account. Then, select the **Deploy to Web App...** option.
@ -197,9 +197,9 @@ Refer to the [Before the hands-on lab setup guide](Before%20the%20Hands-On%20Lab
![Select the Browse option.](media/vscode-app-service-1.png 'Browse for a folder')
3. Choose the **Contoso.Healthcare** folder.
3. Choose the **Humongous.Healthcare** folder.
![Select the Contoso.Healthcare folder.](media/vscode-app-service-2.png 'Choose a folder')
![Select the Humongous.Healthcare folder.](media/vscode-app-service-2.png 'Choose a folder')
4. Choose the subscription hosting the App Service in the next step, and then select the App Service itself in the following step.
@ -240,7 +240,7 @@ Refer to the [Before the hands-on lab setup guide](Before%20the%20Hands-On%20Lab
![Open the workflows folder.](media/cicd-workflows.png 'Open the workflows folder')
4. Inside the folder, there should be one YAML file. Open that file and then select the **Edit** option to modify this file. We will need to make a change to build and deploy just the **Contoso.Healthcare** folder within our entire repository.
4. Inside the folder, there should be one YAML file. Open that file and then select the **Edit** option to modify this file. We will need to make a change to build and deploy just the **Humongous.Healthcare** folder within our entire repository.
![Edit the GitHub Action.](media/cicd-edit.png 'Edit file')
@ -249,7 +249,7 @@ Refer to the [Before the hands-on lab setup guide](Before%20the%20Hands-On%20Lab
```yaml
defaults:
run:
working-directory: ./Contoso.Healthcare/
working-directory: ./Humongous.Healthcare/
```
6. After committing your changes, the GitHub Action should run automatically and succeed. Select the **Actions** menu option to review workflow outcomes. There will be one prior failure, which happened when App Services set up the initial GitHub Action pointing to the root folder.
@ -305,7 +305,7 @@ Because this project uses the `Swashbuckle.AspNetCore` NuGet package, we can bui
> **Note:** If you receive a 500 error, make sure that you configured the web service URL in the prior step.
6. Contoso Healthcare would like to perform rate limiting as a method of limiting risk of Denial of Service attacks. In order to enable rate limiting on an API, return to the **Design** menu and ensure that you have selected **HealthChecks** and **All operations**. From there, select **+ Add policy** under **Inbound processing**.
6. Humongous Healthcare would like to perform rate limiting as a method of limiting risk of Denial of Service attacks. In order to enable rate limiting on an API, return to the **Design** menu and ensure that you have selected **HealthChecks** and **All operations**. From there, select **+ Add policy** under **Inbound processing**.
![Add a new inbound processing policy.](media/apim-new-policy.png 'Add policy')
@ -313,7 +313,7 @@ Because this project uses the `Swashbuckle.AspNetCore` NuGet package, we can bui
![Select the Limit call rate policy.](media/apim-select-policy.png 'Select policy')
8. Contoso would like to ensure that a particular user does not send more than 10 calls over a 300-second period. Enter those values into the appropriate fields and select **Save** to create this policy.
8. Humongous would like to ensure that a particular user does not send more than 10 calls over a 300-second period. Enter those values into the appropriate fields and select **Save** to create this policy.
![Limit inbound calls to no more than 10 per 300 seconds per user.](media/apim-create-policy.png 'Create policy')

Просмотреть файл

@ -0,0 +1,2 @@
Dockerfile
charts/*

Просмотреть файл

@ -1,12 +1,12 @@
using Humungous.Healthcare.Models;
using Humungous.Healthcare.Services;
using Humongous.Healthcare.Models;
using Humongous.Healthcare.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Humungous.Healthcare.Controllers
namespace Humongous.Healthcare.Controllers
{
[Route("[controller]")]
[ApiController]

Просмотреть файл

@ -2,7 +2,7 @@ FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy everything
COPY ./Humungous.Healthcare.csproj .
COPY ./Humongous.Healthcare.csproj .
# Restore as distinct layers
RUN dotnet restore
@ -16,4 +16,4 @@ RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "Humungous.Healthcare.dll"]
ENTRYPOINT ["dotnet", "Humongous.Healthcare.dll"]

Просмотреть файл

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31424.327
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Humungous.Healthcare", "Humungous.Healthcare.csproj", "{D11CC17B-A232-4B52-878E-76F5976DD09E}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Humongous.Healthcare", "Humongous.Healthcare.csproj", "{D11CC17B-A232-4B52-878E-76F5976DD09E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

Просмотреть файл

@ -4,7 +4,7 @@ using System.Linq;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace Humungous.Healthcare.Models
namespace Humongous.Healthcare.Models
{
public class HealthCheck
{

Просмотреть файл

@ -7,7 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Humungous.Healthcare
namespace Humongous.Healthcare
{
public class Program
{

Просмотреть файл

@ -36,7 +36,7 @@
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('HumungousHealthcareAPI', subscription().subscriptionId)))]",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('HumongousHealthcareAPI', subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
@ -49,7 +49,7 @@
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "HumungousHealthcareapim",
"name": "HumongousHealthcareapim",
"type": "Microsoft.ApiManagement/service",
"location": "[parameters('resourceLocation')]",
"properties": {
@ -59,7 +59,7 @@
"hostnameConfigurations": [
{
"type": "Proxy",
"hostName": "Humungoushealthcareapim.azure-api.net",
"hostName": "Humongoushealthcareapim.azure-api.net",
"encodedCertificate": null,
"keyVaultId": null,
"certificatePassword": null,
@ -94,9 +94,9 @@
},
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "HumungousHealthcareapim/HumungousHealthcareAPI",
"name": "HumongousHealthcareapim/HumongousHealthcareAPI",
"properties": {
"displayName": "HumungousHealthcareAPI",
"displayName": "HumongousHealthcareAPI",
"apiRevision": "1",
"description": null,
"subscriptionRequired": true,
@ -117,7 +117,7 @@
},
"apiVersion": "2019-12-01",
"dependsOn": [
"HumungousHealthcareapim"
"HumongousHealthcareapim"
]
}
]

Просмотреть файл

@ -21,7 +21,7 @@
},
"resourceName": {
"type": "string",
"defaultValue": "HumungousHealthcare",
"defaultValue": "HumongousHealthcare",
"metadata": {
"description": "Name of the main resource to be created by this template."
}

Просмотреть файл

@ -36,7 +36,7 @@
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('HumungousHealthcareAPI', subscription().subscriptionId)))]",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('HumongousHealthcareAPI', subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
@ -49,7 +49,7 @@
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "HumungousHealthcareapim",
"name": "HumongousHealthcareapim",
"type": "Microsoft.ApiManagement/service",
"location": "[parameters('resourceLocation')]",
"properties": {
@ -59,7 +59,7 @@
"hostnameConfigurations": [
{
"type": "Proxy",
"hostName": "Humungoushealthcareapim.azure-api.net",
"hostName": "Humongoushealthcareapim.azure-api.net",
"encodedCertificate": null,
"keyVaultId": null,
"certificatePassword": null,
@ -94,13 +94,13 @@
},
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "HumungousHealthcareapim/HumungousHealthcareAPI",
"name": "HumongousHealthcareapim/HumongousHealthcareAPI",
"properties": {
"displayName": "Humungous.Healthcare",
"displayName": "Humongous.Healthcare",
"apiRevision": "1",
"description": null,
"subscriptionRequired": false,
"serviceUrl": "https://Humungoushealthcare.azurewebsites.net",
"serviceUrl": "https://Humongoushealthcare.azurewebsites.net",
"path": "",
"protocols": [
"https"
@ -117,7 +117,7 @@
},
"apiVersion": "2019-12-01",
"dependsOn": [
"HumungousHealthcareapim"
"HumongousHealthcareapim"
]
}
]

Просмотреть файл

@ -21,7 +21,7 @@
},
"resourceName": {
"type": "string",
"defaultValue": "HumungousHealthcare",
"defaultValue": "HumongousHealthcare",
"metadata": {
"description": "Name of the main resource to be created by this template."
}

Просмотреть файл

@ -36,7 +36,7 @@
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('HumungousHealthcare', subscription().subscriptionId)))]",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('HumongousHealthcare', subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
@ -54,7 +54,7 @@
"location": "[parameters('resourceLocation')]",
"properties": {
"publisherEmail": "lino@thetrainingboss.com",
"publisherName": "Humungous Healthcare",
"publisherName": "Humongous Healthcare",
"notificationSenderEmail": "apimgmt-noreply@mail.windowsazure.com",
"hostnameConfigurations": [
{
@ -99,9 +99,9 @@
},
{
"type": "Microsoft.ApiManagement/service/apis",
"name": "LinoAPIM/HumungousHealthcare",
"name": "LinoAPIM/HumongousHealthcare",
"properties": {
"displayName": "HumungousHealthcare",
"displayName": "HumongousHealthcare",
"apiRevision": "1",
"description": null,
"subscriptionRequired": true,

Просмотреть файл

@ -21,7 +21,7 @@
},
"resourceName": {
"type": "string",
"defaultValue": "HumungousHealthcareAppService",
"defaultValue": "HumongousHealthcareAppService",
"metadata": {
"description": "Name of the main resource to be created by this template."
}

Просмотреть файл

@ -17,7 +17,7 @@
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Humungous.Healthcare": {
"Humongous.Healthcare": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,

Просмотреть файл

@ -1,7 +1,7 @@
{
"dependencies": {
"apis1": {
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.ApiManagement/service/HumungousHealthcareapim/apis/HumungousHealthcareAPI",
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.ApiManagement/service/HumongousHealthcareapim/apis/HumongousHealthcareAPI",
"type": "apis.azure"
}
}

Просмотреть файл

@ -1,9 +1,9 @@
{
"dependencies": {
"apis1": {
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.ApiManagement/service/HumungousHealthcareapim/apis/HumungousHealthcareAPI",
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.ApiManagement/service/HumongousHealthcareapim/apis/HumongousHealthcareAPI",
"type": "apis.azure",
"apiEndpoint": "https://Humungoushealthcareapim.azure-api.net/"
"apiEndpoint": "https://Humongoushealthcareapim.azure-api.net/"
}
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"dependencies": {
"apis1": {
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.ApiManagement/service/LinoAPIM/apis/HumungousHealthcare",
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.ApiManagement/service/LinoAPIM/apis/HumongousHealthcare",
"type": "apis.azure"
}
}

Просмотреть файл

@ -1,4 +1,4 @@
using Humungous.Healthcare.Models;
using Humongous.Healthcare.Models;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,7 +7,7 @@ using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Fluent;
using Microsoft.Extensions.Configuration;
namespace Humungous.Healthcare.Services
namespace Humongous.Healthcare.Services
{
public class CosmosDbService : ICosmosDbService
{

Просмотреть файл

@ -1,10 +1,10 @@
using Humungous.Healthcare.Models;
using Humongous.Healthcare.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Humungous.Healthcare.Services
namespace Humongous.Healthcare.Services
{
public interface ICosmosDbService
{

Просмотреть файл

@ -1,4 +1,4 @@
using Humungous.Healthcare.Services;
using Humongous.Healthcare.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
@ -12,7 +12,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Humungous.Healthcare
namespace Humongous.Healthcare
{
public class Startup
{
@ -30,7 +30,7 @@ namespace Humungous.Healthcare
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Humungous.Healthcare", Version = "v1" });
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Humongous.Healthcare", Version = "v1" });
});
services.AddSingleton<ICosmosDbService>(InitializeCosmosClientInstanceAsync(Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult());
}
@ -43,7 +43,7 @@ namespace Humungous.Healthcare
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Humungous.Healthcare v1"));
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Humongous.Healthcare v1"));
app.UseRouting();

Просмотреть файл

@ -1 +0,0 @@
Dockerfile

Просмотреть файл

@ -1,4 +1,4 @@
# Contoso Healthcare -- Win with App Platform
# Humongous Healthcare -- Win with App Platform
This repository shows one potential solution for the following case study.
## Instructions
@ -9,15 +9,15 @@ The Hands-On Lab guide contains a shortened version of the case study, but the f
## Case Study
**Contoso Healthcare** is a global network of healthcare providers with presence throughout the industry. Contoso Healthcare wishes to drive a new Health Checks initiative, which specifically entails building a suite of health check applications for its 7,500 combined direct and partner network employees worldwide to use. These applications will allow users to submit information on their current health status and submit a questionnaire concerning any medical symptoms they might have experienced over the past 14 days. Employees would enter this information before leaving for work each day, allowing Contoso to track potential employee health issues over time.
**Humongous Healthcare** is a global network of healthcare providers with presence throughout the industry. Humongous Healthcare wishes to drive a new Health Checks initiative, which specifically entails building a suite of health check applications for its 7,500 combined direct and partner network employees worldwide to use. These applications will allow users to submit information on their current health status and submit a questionnaire concerning any medical symptoms they might have experienced over the past 14 days. Employees would enter this information before leaving for work each day, allowing Humongous to track potential employee health issues over time.
Molly Fischer, the Chief Technical Officer (CTO) and Vice President of Engineering at Contoso Healthcare, wants to use cloud services for their Health Checks initiative, thereby freeing Contoso Healthcare from any physical requirements for on-premises hardware. Contoso already uses a variety of Microsoft Azure services, taking advantage of both Infrastructure-as-a-Service and Platform-as-a-Service offerings. Their software engineers and infrastructure team have a good working familiarity with Azure services and wish to use this opportunity to develop an innovative product which can serve as a guide for future modernization of their existing applications and infrastructure.
Molly Fischer, the Chief Technical Officer (CTO) and Vice President of Engineering at Humongous Healthcare, wants to use cloud services for their Health Checks initiative, thereby freeing Humongous Healthcare from any physical requirements for on-premises hardware. Humongous already uses a variety of Microsoft Azure services, taking advantage of both Infrastructure-as-a-Service and Platform-as-a-Service offerings. Their software engineers and infrastructure team have a good working familiarity with Azure services and wish to use this opportunity to develop an innovative product which can serve as a guide for future modernization of their existing applications and infrastructure.
The Engineering team at Contoso Healthcare wants a modern, innovative application platform, but this is not the only key group which will be involved. Antonio de la Cruz, Vice President of Product Management, made clear that business analysts will be responsible for creating the business logic and user experience for most of the Health Checks applications. These business analysts are not software developers, and de la Cruz needs a low-code or no-code approach to application development which will enable his team to work without relying on Engineering. These applications should be able to access API endpoints which the Engineering team plan to build.
The Engineering team at Humongous Healthcare wants a modern, innovative application platform, but this is not the only key group which will be involved. Antonio de la Cruz, Vice President of Product Management, made clear that business analysts will be responsible for creating the business logic and user experience for most of the Health Checks applications. These business analysts are not software developers, and de la Cruz needs a low-code or no-code approach to application development which will enable his team to work without relying on Engineering. These applications should be able to access API endpoints which the Engineering team plan to build.
Contoso architects have sketched out a high-level overview of their ideal API, but there is some disagreement within the team around whether the techniques they should use for endpoint design and access. One architect believes that a HTTP-based REST API, using classic endpoints like GET and POST, would be best because Contoso engineers have a fair amount of experience working with .NET MVC and Web API applications. A second architect would prefer a GraphQL approach, arguing that it is a more modern and flexible take on API design. Their third architect is indifferent between the two approaches but strongly prefers using the Command and Query Responsibility Separation (CQRS) pattern for any API design. The three architects have all agreed that, because they are not as familiar as they would like to be with Azure services, they will put a great deal of weight on Microsoft's advice. They're all confident that their software engineers could handle either REST or GraphQL, but want to learn about best practices, as well as understand what works best in Azure.
Humongous architects have sketched out a high-level overview of their ideal API, but there is some disagreement within the team around whether the techniques they should use for endpoint design and access. One architect believes that a HTTP-based REST API, using classic endpoints like GET and POST, would be best because Humongous engineers have a fair amount of experience working with .NET MVC and Web API applications. A second architect would prefer a GraphQL approach, arguing that it is a more modern and flexible take on API design. Their third architect is indifferent between the two approaches but strongly prefers using the Command and Query Responsibility Separation (CQRS) pattern for any API design. The three architects have all agreed that, because they are not as familiar as they would like to be with Azure services, they will put a great deal of weight on Microsoft's advice. They're all confident that their software engineers could handle either REST or GraphQL, but want to learn about best practices, as well as understand what works best in Azure.
Contoso would like to manage one API for accessing the back end of all these health applications. In practice, Contoso expects something on the order of 15 to 20 endpoints to support the breadth of their health check application suite, but for the purposes of a proof of concept, they would like to have two endpoints implemented: one which submits information on current health status and one which retrieves submissions for the registered user. The key data points Contoso would like to have in this proof-of-concept are as follows:
Humongous would like to manage one API for accessing the back end of all these health applications. In practice, Humongous expects something on the order of 15 to 20 endpoints to support the breadth of their health check application suite, but for the purposes of a proof of concept, they would like to have two endpoints implemented: one which submits information on current health status and one which retrieves submissions for the registered user. The key data points Humongous would like to have in this proof-of-concept are as follows:
- Submission ID, generated by the system.
- Patient ID, handled as part of a future authentication process. For the proof of concept, it would be okay for the end application to hard-code the patient ID.
@ -25,21 +25,21 @@ Contoso would like to manage one API for accessing the back end of all these hea
- Current health status (one of "I feel well" or "I feel unwell").
- A list of symptoms over the past 14 days, where each symptom is a free-form text entry with no validation.
When retrieving submissions for a registered user, they would like the ability to retrieve all submissions for the logged-in user or pass in a submission ID to retrieve details solely on that particular submission. Contoso Engineering plans to expand these requirements in their full product implementation, such as extending the data model and implementing lookup lists and checks on symptoms. For a proof of concept, however, they do not want to complicate things unnecessarily.
When retrieving submissions for a registered user, they would like the ability to retrieve all submissions for the logged-in user or pass in a submission ID to retrieve details solely on that particular submission. Humongous Engineering plans to expand these requirements in their full product implementation, such as extending the data model and implementing lookup lists and checks on symptoms. For a proof of concept, however, they do not want to complicate things unnecessarily.
The expectation is that Contoso software engineers will implement all API endpoints for the Health Checks initiative (beyond what you will create for the proof of concept), and multiple, independent teams may implement different endpoints over time. Both Molly and the architects would like this system to be as simple to manage as possible. While there is an Operations team in the Engineering department, that group tends to be overwhelmed with existing tasks and they have very limited time available to manage new software solutions. Ideally, the software engineers should be able to instrument, monitor, and manage these endpoints themselves, but Contoso Healthcare does not have a great DevOps culture today. They are moving in that direction, but would appreciate any tooling, processes, or product selections which could make the process of instrumentation, monitoring, and management easier for their software engineers.
The expectation is that Humongous software engineers will implement all API endpoints for the Health Checks initiative (beyond what you will create for the proof of concept), and multiple, independent teams may implement different endpoints over time. Both Molly and the architects would like this system to be as simple to manage as possible. While there is an Operations team in the Engineering department, that group tends to be overwhelmed with existing tasks and they have very limited time available to manage new software solutions. Ideally, the software engineers should be able to instrument, monitor, and manage these endpoints themselves, but Humongous Healthcare does not have a great DevOps culture today. They are moving in that direction, but would appreciate any tooling, processes, or product selections which could make the process of instrumentation, monitoring, and management easier for their software engineers.
Antonio's Business Analysts would like to develop applications to facilitate the communication between customers in the Contoso health care network and their health care providers. They aim to develop systems which let customers input vital metrics from mobile, tablet, or desktop devices. For mobile and tablet devices, they would like to make the health check applications mobile apps rather than having customers navigate to a website for data entry. This mobile application interface should be as close to native Android or iOS as possible, but Antonio warns us that Contoso does not have much experience developing mobile applications and the Engineering department would need a significant ramp-up time to move on an initiative like this, making code-heavy mobile development a non-starter at this time for Contoso Healthcare.
Antonio's Business Analysts would like to develop applications to facilitate the communication between customers in the Humongous health care network and their health care providers. They aim to develop systems which let customers input vital metrics from mobile, tablet, or desktop devices. For mobile and tablet devices, they would like to make the health check applications mobile apps rather than having customers navigate to a website for data entry. This mobile application interface should be as close to native Android or iOS as possible, but Antonio warns us that Humongous does not have much experience developing mobile applications and the Engineering department would need a significant ramp-up time to move on an initiative like this, making code-heavy mobile development a non-starter at this time for Humongous Healthcare.
Antonio has spent the last few months researching products, such as Amazon Honeycode, which would allow his Business Analysts to use an Excel-like approach to build web and mobile applications. He's very interested in the product but is not convinced that it's a perfect fit for his team. Because Contoso already uses Azure for some of their needs, Antonio is interested in reviewing Microsoft-native options to see if there is something which might work even better for his team than Honeycode might. Antonio would appreciate any comparative intelligence with product competitors, so that he knows he'll have made the right decision. He is familiar with some of the players, such as Google's AppSheet and Salesforce, but wants to make sure he is getting more than what he describes as a "sales pitch" from Microsoft.
Antonio has spent the last few months researching products, such as Amazon Honeycode, which would allow his Business Analysts to use an Excel-like approach to build web and mobile applications. He's very interested in the product but is not convinced that it's a perfect fit for his team. Because Humongous already uses Azure for some of their needs, Antonio is interested in reviewing Microsoft-native options to see if there is something which might work even better for his team than Honeycode might. Antonio would appreciate any comparative intelligence with product competitors, so that he knows he'll have made the right decision. He is familiar with some of the players, such as Google's AppSheet and Salesforce, but wants to make sure he is getting more than what he describes as a "sales pitch" from Microsoft.
Although Antonio's team will do much of the front-end application work, Molly does not want this to become a "shadow IT" initiative. She would like, as much as possible, to have Antonio's team working in a single, collaborative environment, where her Engineering department can review application security, ensure that everything is configured properly, and manage costs most efficiently. They are very concerned with security breaches based on misconfiguration. As Antonio put it, "I don't want one of my people to check the wrong box and suddenly we have governments fining us due to regulatory violations."
Molly and the Engineering team also wish to have all data stored in a single database, as this will simplify security and open opportunities for their data scientists to analyze the data most efficiently. In addition, they would like to centralize management of any access points to the data. Different Engineering teams will work on separate API endpoints and Molly is interested in anything which can improve the coordination between teams and make their architecture group's lives easier. Molly strongly prefers centralized solutions, and she does have a concern around the overlapping capabilities in Azure services. She does not want to spend the time combining a lot of applications to get to Contoso's desired solution, so the fewer the number of working parts, the better it is in her mind.
Molly and the Engineering team also wish to have all data stored in a single database, as this will simplify security and open opportunities for their data scientists to analyze the data most efficiently. In addition, they would like to centralize management of any access points to the data. Different Engineering teams will work on separate API endpoints and Molly is interested in anything which can improve the coordination between teams and make their architecture group's lives easier. Molly strongly prefers centralized solutions, and she does have a concern around the overlapping capabilities in Azure services. She does not want to spend the time combining a lot of applications to get to Humongous's desired solution, so the fewer the number of working parts, the better it is in her mind.
As far as data storage is concerned, the architects focused on the need for flexible data structures. The reason for this is that individual providers in their network often have differing requirements on what data they collect, depending on their specialization. Antonio provided as one example that all providers in the network will be able to generate admission, transfer, and discharge records based on a common HL7 format. Beyond that, however, the data elements collected for outpatient treatment facility for a minor surgical procedure might differ considerably from 23-hour observation in a behavioral health treatment facility. The questionnaires which end users fill out will likely differ based on facility, mode of treatment, nation, and region. Antonio also mentioned that these questionnaires may change over time to support additional testing options, such as asking end users a subset of the questions sometimes or adding and removing questions from the survey applications. Antonio is not sure just how often these changes will occur but mentioned tha Contoso Healthcare's clinical research staff is excited to have that potential capability.
As far as data storage is concerned, the architects focused on the need for flexible data structures. The reason for this is that individual providers in their network often have differing requirements on what data they collect, depending on their specialization. Antonio provided as one example that all providers in the network will be able to generate admission, transfer, and discharge records based on a common HL7 format. Beyond that, however, the data elements collected for outpatient treatment facility for a minor surgical procedure might differ considerably from 23-hour observation in a behavioral health treatment facility. The questionnaires which end users fill out will likely differ based on facility, mode of treatment, nation, and region. Antonio also mentioned that these questionnaires may change over time to support additional testing options, such as asking end users a subset of the questions sometimes or adding and removing questions from the survey applications. Antonio is not sure just how often these changes will occur but mentioned tha Humongous Healthcare's clinical research staff is excited to have that potential capability.
Following up from Antonio's point, Molly reiterated that any solution should have the capability to analyze large-scale data later, as Contoso Healthcare data scientists and the clinical research staff are hoping to perform longitudinal studies of end user symptoms over an extended period to test the efficacy of various treatment regimes. Their data scientists have medical records information, but that information is limited to a subset of end users who were admitted for treatment and the opportunity to analyze data on symptoms treated outside of a health care facility is of great interest to them.
Following up from Antonio's point, Molly reiterated that any solution should have the capability to analyze large-scale data later, as Humongous Healthcare data scientists and the clinical research staff are hoping to perform longitudinal studies of end user symptoms over an extended period to test the efficacy of various treatment regimes. Their data scientists have medical records information, but that information is limited to a subset of end users who were admitted for treatment and the opportunity to analyze data on symptoms treated outside of a health care facility is of great interest to them.
Another consideration that Molly would like to keep in mind is that Engineering has relied on their Jenkins-based Continuous Integration and Continuous Deployment (CI/CD) pipelines for code development and deployment on-premises and into virtual machines hosted on Azure. This works well for their existing code bases, but they are interested in learning how to use Azure DevOps or GitHub Actions, taking the knowledge they have earned over time and applying it to these new technologies. The concern Molly expressed, however, is that Microsoft seems to be giving ambiguous and contradictory advice on which platform teams like hers should use and would like clarity on what the right answer is.

54
manifests/deployment.yml Normal file
Просмотреть файл

@ -0,0 +1,54 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: "humongous-healthcare-api"
spec:
replicas: 3
selector:
matchLabels:
app: "humongous-healthcare-api"
template:
metadata:
labels:
app: "humongous-healthcare-api"
spec:
containers:
- name: "humongous-healthcare-api"
image: "taw4acrjrc23a.azurecr.io/humongous-healthcare-api:0.0.0"
env:
- name: CosmosDb__Account
valueFrom:
secretKeyRef:
name: cosmosdb
key: cosmosdb-account
optional: false
- name: CosmosDb__Key
valueFrom:
secretKeyRef:
name: cosmosdb
key: cosmosdb-key
optional: false
- name: CosmosDb__DatabaseName
value: HealthCheckDB
- name: CosmosDb__ContainerName
value: HealthCheck
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /HealthCheck
port: http
readinessProbe:
httpGet:
path: /HealthCheck
port: http
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 200m
memory: 256Mi

15
manifests/service.yml Normal file
Просмотреть файл

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: "humongous-healthcare-api"
labels:
app: "humongous-healthcare-api"
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: "humongous-healthcare-api"

Просмотреть файл

@ -30,9 +30,23 @@
"cosmosDbAccountName": "[concat(resourceGroup().name, '-cosmosdb-', parameters('uniqueSuffix'))]",
"appServiceAccountName": "[concat(resourceGroup().name, '-appsvc-', parameters('uniqueSuffix'))]",
"apiManagementServiceName": "[concat(resourceGroup().name, '-apiservice-', parameters('uniqueSuffix'))]",
"hostingPlanName": "[concat('contoso-asp-', uniqueString(resourceGroup().id))]"
"hostingPlanName": "[concat('Humongous-asp-', uniqueString(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.ContainerRegistry/registries/providers/roleAssignments",
"apiVersion": "2018-09-01-preview",
"name": "[concat(variables('acrName'), '/Microsoft.Authorization/', guid(variables('acrName')))]",
"dependsOn": [
"[concat('Microsoft.ContainerService/managedClusters/', variables('clusterName'))]"
],
"properties": {
"roleDefinitionId": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]",
"principalType": "ServicePrincipal",
"principalId": "[reference(variables('clusterName'), '2022-06-01').identityProfile.kubeletidentity.objectId]",
"scope": "[resourceId('Microsoft.ContainerRegistry/registries/', variables('acrName'))]"
}
},
{
"type": "Microsoft.ContainerService/managedClusters",
"apiVersion": "2022-05-02-preview",
@ -68,7 +82,7 @@
"name": "Basic"
},
"properties": {
"adminUserEnabled": false
"adminUserEnabled": true
}
},
{