- Update API to .net 6
- General QA
- Add frontend app
- Add AKS/ACR

Co-authored-by: Matthew Alan Gray <matthew.gray@hatboysoftware.com>
This commit is contained in:
Jim Counts 2022-09-28 20:03:18 -07:00 коммит произвёл GitHub
Родитель f0f95c5e20
Коммит c1dd215a93
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
21 изменённых файлов: 393 добавлений и 362 удалений

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

@ -1,74 +0,0 @@
name: API - AKS - Build and deploy
on:
push:
branches:
- main
paths:
- Humongous.Healthcare/**
- manifests/**
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
ACR_LOGIN_SERVER: taw5acrjrc26.azurecr.io
AKS_NAMESPACE: health-check
CONTAINER_IMAGE: taw5acrjrc26.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
name: dockerauth - create secret
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
name: cosmosdb - create secret
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

64
.github/workflows/main_taw5-appsvc-jrc26.yml поставляемый
Просмотреть файл

@ -1,64 +0,0 @@
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions
name: Build and deploy ASP.Net Core app to Azure Web App - taw5-appsvc-jrc26
on:
push:
branches:
- main
workflow_dispatch:
env: # <<-- Add environment variables here
REACT_APP_API_URL: ${{ secrets.API_URL }} # <<-- referencing the GitHub secrets
REACT_APP_API_KEY: ${{ secrets.API_KEY }} # <<-- created in Step 2
jobs:
build:
runs-on: windows-latest
defaults: # <<-- Add default working directory
run: # <<-- here to ensure deployment
working-directory: ./Humongous.Healthcare.Web/ # <<-- targets correct path.
steps:
- uses: actions/checkout@v2
- name: Set up .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
- name: Build with dotnet
run: dotnet build --configuration Release
- name: dotnet publish
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: .net-app
path: ${{env.DOTNET_ROOT}}/myapp
deploy:
runs-on: windows-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v2
with:
name: .net-app
- name: Deploy to Azure Web App
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'taw5-appsvc-jrc26'
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_7E8385FCCC8A4525B6ECE134090BAD92 }}
package: .

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

@ -27,6 +27,9 @@ September 2022
3. Install the latest version of [the .NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0).
4. Install [Docker Desktop](https://docs.docker.com/desktop/)
5. Install the [Kubernetes CLI](https://kubernetes.io/docs/tasks/tools/)
## Before the hands-on lab
Duration: 15 minutes

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

@ -16,15 +16,18 @@ September 2022
- [Task 1: Create Cosmos DB container](#task-1-create-cosmos-db-container)
- [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)
- [Task 2: Run the Humongos Healthcare Web API service in a container](#task-2-run-the-humongos-healthcare-web-api-service-in-a-container)
- [Task 3: Push the Humongous Healthcare Web API container image to ACR](#task-3-push-the-humongous-healthcare-web-api-container-image-to-acr)
- [Task 4: Deploy the Humongous Healthcare Web API service to AKS](#task-4-deploy-the-humongous-healthcare-web-api-service-to-aks)
- [Exercise 3: Configure AKS continuous deployment with GitHub Actions](#exercise-3--configure-aks-continuous-deployment-with-github-actions)
- [Task 1: Create a GitHub Actions Workflow](#task-1--create-a-github-actions-workflow)
- [Exercise 4: Configure API Management](#exercise-4--configure-api-management)
- [Task 1: Review the Health Checks API](#task-1--review-the-health-checks-api)
- [Task 2: Connect API Management to the App Service](#task-2--connect-api-management-to-the-app-service)
- [Exercise 5: Create a Power Apps custom connector and application](#exercise-5--create-a-power-apps-custom-connector-and-application)
- [Task 1: Create a custom Power Apps connector](#task-1--create-a-custom-power-apps-connector)
- [Task 2: Use the Power Apps custom connector in a new application](#task-2--use-the-power-apps-custom-connector-in-a-new-application)
- [Exercise 5: Deploy the Humongous Healthcare Web Application to access the Web API](#exercise-5-deploy-the-humongous-healthcare-web-application-to-access-the-web-api)
- [Task 1: Configure API Management to use HTTPS](#task-1-configure-api-management-to-use-https)
- [Task 2: Configure CORS](#task-2-configure-cors)
- [Task 3: Deploy the Humongous Healthcare Web API service to App Services](#task-3-deploy-the-humongous-healthcare-web-api-service-to-app-services)
# Hands-on Lab Step-by-Step
@ -40,7 +43,7 @@ Humongous already uses a variety of Microsoft Azure services, taking advantage o
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 (with the assistance of an outside consulting group). The consulting group will not be required to deploy to AKS and have indicated that they prefer to work with App Services. These applications should be able to access API endpoints which the Engineering team plan to build.
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:
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
@ -54,13 +57,13 @@ For this proof of concept, Humongous would also like to see a model example of C
## Solution architecture
The following diagram provides a high-level overview of the Azure services we will use for implementation. **TODO new diagram**
The following diagram provides a high-level overview of the Azure services we will use for implementation.
![High-level architecture, as described below.](media/architecture-diagram.png "High-level architecture")
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 Kubernetes Service because the engineering team eventual plans to orchestrate a large number of APIs.
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.
To store and retrieve data, the endpoints 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.
@ -82,6 +85,8 @@ Azure Front Door is a layer 7 load balancer which includes web application firew
3. Install the latest version of [the .NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0).
4. Install the latest version of the [Postman](https://www.postman.com/) client.
5. Install [Docker Desktop](https://docs.docker.com/desktop/)
6. Install the [Kubernetes CLI](https://kubernetes.io/docs/tasks/tools/)
## Before the hands-on lab
@ -187,76 +192,334 @@ 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 Humongous Healthcare Web API service to App Services
### Task 2: Run the Humongos Healthcare Web API service in a container
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.
1. Open the hands-on lab in Visual Studio Code and use the terminal to navigate to the `Humongous.Healthcare` project.
![Select the App Service.](media/vscode-app-service.png 'App Service')
2. Create a file named `Dockerfile` and add the following contents.
2. Select **Browse** from the list of folders to deploy.
```dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
![Select the Browse option.](media/vscode-app-service-1.png 'Browse for a folder')
# Copy project file
COPY ./Humongous.Healthcare.csproj .
# Restore as distinct layer
RUN dotnet restore
3. Choose the **Humongous.Healthcare** folder.
# Copy everything else
COPY . .
![Select the Humongous.Healthcare folder.](media/vscode-app-service-2.png 'Choose a folder')
# Build and publish a release
RUN dotnet publish -c Release -o out
4. Choose the subscription hosting the App Service in the next step, and then select the App Service itself in the following step.
![Select the App Service.](media/vscode-app-service-3.png 'Choose an App Service')
5. Select **Deploy** from the next menu to push the service.
![Deploy the App Service.](media/vscode-app-service-4.png 'Deploy the App Service')
6. Navigate to the **Configuration** option in the **Settings** menu for your App Service and select **+ New application setting**. Enter the following application settings:
| Name | Value |
| ----------------------- | -------------------------------------------------- |
| CosmosDb__Account | _enter the URL of your Cosmos DB account_ |
| CosmosDb__Key | _enter the primary key for your Cosmos DB account_ |
| CosmosDb__DatabaseName | _enter `HealthCheckDB`_ |
| CosmosDb__ContainerName | _enter `HealthCheck`_ |
Select **Save** to save these application settings.
![Application settings for the App Service.](media/app-service-app-settings.png 'Application settings')
> **Note:** If you get 404 errors when trying to access your App Service at this point, don't panic! The purpose of this task was to link your existing code with an App Service. In the next task, you will configure a CI/CD process to perform this deployment automatically upon check-in. If you do see 404 errors, the following exercise will correct them.
## Exercise 3: Configure continuous deployment with GitHub Actions
### Task 1: Create and Edit a GitHub Action
1. Navigate to the **Deployment Center** option in the **Deployment** menu for your App Service. From the **Source** drop-down list, select **GitHub**. Note that you may need to authenticate with GitHub and provide specific access permissions for your account.
![Select GitHub for Continuous Deployment (CI/CD).](media/cicd-source.png 'Select code source')
2. Choose your the organization, repository, and primary branch for this lab. Then, select **Save** to create a YAML file containing a GitHub Action in the `.github\workflows` folder of your repository.
![Create a GitHub Action to deploy on code check-in.](media/cicd-create-action.png 'Create a Github Action')
3. Navigate to your GitHub repository via the GitHub website and select the **.github/workflows** folder which now appears.
![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 **Humongous.Healthcare** folder within our entire repository.
![Edit the GitHub Action.](media/cicd-edit.png 'Edit file')
5. Add the following below the line `runs-on: windows-latest` in your YAML file. Then, select **Start commit** and **Commit** to save your changes.
```yaml
defaults:
run:
working-directory: ./Humongous.Healthcare/
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "Humongous.Healthcare.dll"]
```
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.
This is a multi-stage Dockerfile with 2 stages, build and runtime. The build stage uses the .net 6 SDK image which contains all the compilers and tooling needed to create the Web API service. In contrast, the runtime stage is based on the smaller `aspnet` image, which only contains the necesssary binaries to execute asp.net applications.
![Review workflow results on the Actions page.](media/cicd-actions.png 'All workflows')
The build stage:
- Copies the project file into the Docker container and runs `dotnet restore` to retrieve nuget packages. This is a stand-alone layer so that the packages will be cached if we need to run `docker build` again.
- Copies the remaining project files to the container then runs `dotnet publish` to create the Web API service.
7. Once this deployment succeeds, you should be able to navigate to your App Service URL in Postman and perform the same `GET`, `POST`, `PUT`, and `DELETE` operations you could locally.
The runtime stage starts from a clean `aspnet` image without compiler tooling or intermediate object files then:
- Copies the Web API binaries from the build stage.
- Configures the container image to run the Web API on startup.
3. Run the following command to build the container image.
```sh
docker build -t api .
```
4. Run the following command to run an instance of the container image.
```sh
docker run -it -p 5000:80 api
```
5. Use postman (or your browser) to `GET` the following URL and confirm the Web API is functioning inside the container.
`http://localhost:5000/HealthCheck`
6. When you are done, use `Ctrl+C` to stop the container instance.
### Task 3: Push the Humongous Healthcare Web API container image to ACR
1. Use the following command to tag your container image with your ACR login server name and a more descriptive repository name:
```sh
docker tag api <replace with your login server>/humongous-healthcare-api:0.0.0
```
Example:
```sh
docker tag api taw.azurecr.io/humongous-healthcare-api:0.0.0
```
2. Login to the Azure CLI and the ACR instance using the following commands:
```sh
az login
az acr login --name <acrName>
```
Example
```sh
az login
az acr login --name taw
```
3. Use the following command to push the container image to ACR.
```sh
docker push <replace with your login server>/humongous-healthcare-api:0.0.0
```
Example:
```sh
docker push taw.azurecr.io/humongous-healthcare-api:0.0.0
```
### Task 4: Deploy the Humongous Healthcare Web API service to AKS
1. Open the hands-on lab in Visual Studio Code.
2. Create a folder named `manifests` and add a file named `deployment.yml` with the following content:
```yaml
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: "<replace with your login server>/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
```
This manifest contains the AKS deployment configuration for the Humongous Healthcare Web API container images. Be sure to update `<replace with your login server>` with your ACR login server name.
3. Create another YAML file in the `manifest` folder called `service.yml` and add the following content:
```yaml
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"
```
This manifest contains the AKS service configuration for the Humongous Healthcare Web API deployment. Because it is a `LoadBalancer` type service, AKS will make the Web API service available to clients outside the cluster.
4. Login to your AKS cluster using the Azure CLI command shown below.
```sh
az aks get-credentials --name <your cluster name> --resource-group <your resource group>
```
Example
```
az aks get-credentials --name taw-aks --resource-group taw
```
5. Create a Kubernetes namespace for the service using the following command.
```sh
kubectl create namespace health-check
```
6. Create a Kubernetes secret to provide the CosmosDB configuration using the following command.
```sh
kubectl create secret generic cosmosdb --namespace health-check --from-literal=cosmosdb-account='<Replace with your account URL>' --from-literal=cosmosdb-key='<Replace with your account key>'
```
Example:
```sh
kubectl create secret generic cosmosdb --namespace health-check --from-literal=cosmosdb-account='https://taw-cosmosdb.documents.azure.com:443/' --from-literal=cosmosdb-key='qwerty123456!@#$%==='
```
7. Create the AKS deployment and service using the following commands.
```sh
kubectl apply --namespace health-check --filename manifests/deployment.yml --filename manifests/service.yml
```
8. Visit your AKS cluster in the Azure Portal and navigate to "Kubernetes resources > Services and ingresses". Click the "External IP" link for `humonguous-healthcare-api`. **Note**: You will initially recieve a 404 error when the new brower tab opens. Continue to the next step.
![The portal AKS workloads is displayed.](media/aks-service-and-ingresses.png "Service External IP")
9. Add the `/HealthCheck` IP to the end of the URL to view the raw health check data.
![The Health Check data is displayed in the browser.](media/aks-health-checks.png "Health Check JSON")
7. Once this deployment succeeds, you should be able to navigate to your External IP address in Postman and perform the same `GET`, `POST`, `PUT`, and `DELETE` operations you could locally.
## Exercise 3: Configure AKS continuous deployment with GitHub Actions
### Task 1: Create a GitHub Actions Workflow
1. Open the hands-on lab in Visual Studio Code.
2. Create a folder named `.github/workflows` and add a file named `deployToAksCluster.yml` with the following content (remember to replace the placeholders with your ACR name where noted below):
```yaml
name: API - AKS - Build and deploy
on:
push:
branches:
- main
paths:
- Humongous.Healthcare/**
- manifests/**
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
ACR_LOGIN_SERVER: <replace with your ACR name>.azurecr.io
AKS_NAMESPACE: health-check
CONTAINER_IMAGE: <replace with your ACR name>.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
name: dockerauth - create secret
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
name: cosmosdb - create secret
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
```
3. The workflow will fail on the intial run because it requires some secrets to be setup in the repository. Navigate to the repository in GitHub then select "Settings > Secrets > Actions". Finally use the "New Repository Secret" button to create secrets.
![Create a new repository secret.](media/github-new-repository-secret.png "New Repository Secret")
Create the following secrets.
- ACR_USERNAME - Copy from the "Access Keys" pane on your container registry.
- ACR_PASSWORD - Copy from the "Access Keys" pane on your container registry.
- AKS_KUBECONFIG - Use the following Azure CLI command to retrieve the configuration data and save it to a file, then use the contents of the file as your secret: `az aks get-credentials --name <your cluster name> --resource-group <your resource group> --file kube.config`
- COSMOSDB_ACCOUNT - Use the CosmosDb account URI you have previously retrieved during this lab.
- COSMOSDB_KEY - Use the CosmosDb account key you have previously retrieved during this lab.
4. Once you create all the secrets, navigate to the "Actions" tab, select your failed workflow run, and choose "Re-run all Jobs".
5. Once this deployment succeeds, you should still be able to navigate to your App Service URL in Postman and perform the same `GET`, `POST`, `PUT`, and `DELETE` operations you could locally.
## Exercise 4: Configure API Management
@ -264,11 +527,11 @@ Refer to the [Before the hands-on lab setup guide](Before%20the%20Hands-On%20Lab
Because this project uses the `Swashbuckle.AspNetCore` NuGet package, we can build a Swagger API and user interface automatically from our Web API definition. The `ConfigureServices()` method in **Startup.cs** automatically configures a [Swagger OpenAPI interface](https://swagger.io/specification/).
1. Navigate to https://{appsvc}.azurewebsites.net/swagger/v1/swagger.json, replacing `{appsvc}` with the name of your App Service URL. This will take you to a JSON schema describing the Health Check API.
1. Navigate to http://{external-ip}/swagger/v1/swagger.json, replacing `{external-ip}` with the external IP address of your cluster. This will take you to a JSON schema describing the Health Check API.
![Review the Swagger-generated JSON describing this API.](media/swagger-json.png 'API description in JSON format')
2. Navigate to https://{appsvc}.azurewebsites.net/swagger/index.html, again replacing `{appsvc}` with the name of your App Service URL. This will take you to an auto-generated user interface describing each of the API endpoints.
2. Navigate to http://{external-ip}/swagger/index.html, again replacing `{external-ip}` with the external IP address of your cluster. This will take you to an auto-generated user interface describing each of the API endpoints.
![Review the Swagger UI showing API endpoints and available verbs.](media/swagger-ui.png 'Swagger UI')
@ -295,86 +558,103 @@ Because this project uses the `Swashbuckle.AspNetCore` NuGet package, we can bui
![The Health Check endpoints are now available in API Management.](media/apim-endpoints.png 'API Management endpoints')
4. In the **Web service URL** settings entry, enter the base URL for your App Service. Then, select **Save**.
![Update the web service URL to point to your App Service.](media/apim-web-service-url.png 'Web service URL')
5. Select the **Test** menu and then choose the first `GET` method for health checks. Select **Send** to perform a test. You should receive back a response with "200 OK" indicating that the request was successful.
4. Select the **Test** menu and then choose the first `GET` method for health checks. Select **Send** to perform a test. You should receive back a response with "200 OK" indicating that the request was successful.
![Test API Management.](media/apim-test.png 'Perform a test')
> **Note:** If you receive a 500 error, make sure that you configured the web service URL in the prior step.
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**.
5. 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')
7. On the inbound policy list, select the **Limit call rate** policy.
6. On the inbound policy list, select the **Limit call rate** policy.
![Select the Limit call rate policy.](media/apim-select-policy.png 'Select 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.
7. 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')
> **Note:** If you are using the Consumption SKU of API Management, you will not be able to save this policy. In that case, select **Discard** to cancel this operation. You might also need to delete a **rate-limit-key** policy below the **base** policy in your **Inbound processing** section. To do this, select the **...** menu and choose **Delete** to remove it.
## Exercise 5: Create a Power Apps custom connector and application
## Exercise 5: Deploy the Humongous Healthcare Web Application to access the Web API
For this final exercise, you will need a Power Apps subscription. This may be a paid subscription or a free Power Apps developer plan.
### Task 1: Configure API Management to use HTTPS
### Task 1: Create a custom Power Apps connector
1. Open the API Management service in your `taw-win-with-app-platform` resource group. Navigate to the **APIS** option in the **APIs** menu, and select the **HealthChecks** API that was created in a previous exercise from the **All APIs** menu.
1. In your API Management service, navigate to the **Power Platform** menu option in the **APIs** menu. Then, select **Create a connector**.
![Select the HealthCheck API.](media/apim-select-api.png 'HealthCheck API')
![Create a custom connector from API Management to Power Apps.](media/apim-create-connector.png 'Create a connector')
2. Select the **Settings** tab, and select the **HTTPS** setting in the **General** section. Click on the **Save** button at the bottom of the page to save the configuration.
2. Choose **HealthChecks** from the API drop-down list and then select the PowerApps environment you wish to deploy to. Keep the API display name as `HealthChecks` and select **Create**. Note that this operation may take 1-2 minutes to complete.
![Configure HTTPS for the API.](media/apim-configure-https.png 'Configure HTTPS')
![Select the HealthChecks API and publish to an existing Power Apps environment.](media/apim-create-connector-1.png 'Create a connector')
### Task 2: Configure CORS
3. By default, API Management requires callers to pass in a subscription key, and this is what we use for rate limiting. To allow for testing in Power Apps, we will add a new subscription key. To do this, navigate to the **Subscriptions** option on the **APIs** menu and then select **+ Add subscription**.
1. Open the App Service in your `taw-win-with-app-platform` resource group. Copy the App Service endpoint URL from the **Overview** detail and save it for use in a later step.
![Add a new subscription key for API Management.](media/apim-add-subscription.png 'Add a subscription key')
![Obtain the App Service URL.](media/appsvc-endpoint-url.png 'App Service URL')
4. Enter `power-apps-testing` for the Name and `Power Apps Testing` for the Display Name. Then, choose **API** from the Scope menu and in the APIs drop-down menu, choose **HealthChecks**. This will limit the key to one API. Select **Create** to complete this process.
2. Open the API Management service in your `taw-win-with-app-platform` resource group. Navigate to the **APIs** option in the **APIs** menu, and select the **HealthChecks** API that was created in a previous exercise from the **All APIs** menu.
![Create a new subscription key for API Management.](media/apim-new-subscription.png 'Add a new subscription')
![Select the HealthCheck API.](media/apim-select-api.png 'HealthCheck API')
5. To view the key, select the **...** menu for the newly-created subscription and select **Show/hide keys**. Copy the primary key for use later.
3. In the **Design** tab, navigate to the **+ Add policy** option in the **Inbound processing** section.
![Show the keys for a particular subscription.](media/apim-show-keys.png 'Show/hide keys')
> **Note:** Ensure that **All operations** is highlighted to ensure that the CORS policy you are about to add is applied to all of the API endpoints.
### Task 2: Use the Power Apps custom connector in a new application
![Select **+ Add policy** to add a new CORS policy.](media/apim-add-policy.png 'Add CORS Policy')
1. Navigate to [the Power Apps website](https://make.powerapps.com/). In the **Dataverse** menu, select **Custom Connectors**. You should see the **HealthChecks** connector. Choose the **Edit** option to review this connector.
4. Select the **cors** inbound policy from the collection of policies.
![Select the HealthChecks custom connector.](media/pa-custom-connectors.png 'Custom connectors')
![Select CORS inbound policy.](media/apim-select-cors.png 'Select CORS')
2. Navigate to the **5. Test** page and select **+ New connection** to create a new connection for this custom connector.
5. Enter the App Service endpoint URL obtained in step 1 of this task into the **Allowed origins** field. Click on the **Save** button at the bottom of the page to save the configuration.
![Create a new connection.](media/pa-new-connection.png 'New connection')
![Configure the CORS domain.](media/apim-configure-cors.png 'Configure CORS')
3. Enter your subscription key and select **Create** to save this connection. This will take you to the **Connections** menu setting, so return to where you were.
### Task 3: Deploy the Humongous Healthcare Web API service to App Services
![Provide a valid subscription key.](media/pa-new-connection-1.png 'Create a new connection')
1. Open the App Service in your `taw-win-with-app-platform` resource group. Navigate to the **Deployment Center** option in the **Deployment** menu. Select **GitHub** from the **Source** drop-down field and enter the **Organization**, **Repository** and **Branch** of your GitHub repository into the corresponding fields. Click the **Save** button to create the associated GitHub action to deploy the web app.
4. Using the newly-created connection, choose the **get-healthcheck** operation and select **Test operation**. Doing so, you should get back a 200 response code and see the health checks you have created. You may also test the other methods if you wish. Once you have finished, select **Close** to close the custom connector panel.
![Create the Web App deployment action in Github.](media/cicd-create-action.png 'Web App Deployment')
![Test the get-healthcheck operation.](media/pa-test-operation.png 'Test operation')
2. Add the necessary secrets to GitHub for the App Service deployment. Navigate to the repository in GitHub and select "Settings > Secrets > Actions". Use the "New Repository Secret" button to create secrets.
5. On the **Home** menu, select **Canvas app from blank** to create a new canvas app.
![Create repository secrets.](media/github-new-repository-secret.png "Repository Secret")
![Create a new canvas app.](media/pa-new-canvas-app.png 'Canvas app from blank')
Create the following secrets.
6. Name the app **Health Checks** and set the format to **Phone**. Then, select **Create**.
- API_URL - This should be the HealthCheck API Endpoint URL
- API_KEY - This should be the HealthCheck API Subscription API Key
![Name the application and set the format to fit on a phone.](media/pa-new-canvas-app-1.png 'Create an app')
7. On the Power Apps canvas, select the **Data** menu and then choose **+ Add data**. In the dropdown, expand the **Connectors** menu and choose the **HealthChecks** custom connector. You will then be asked to choose a connection; choose the **HealthChecks** connection you created in this task.
3. Locate the GitHub action YAML file created in your repository by Step 1 located in the `.github/workflows` folder. Make the following modifications to the contents to ensure the correct working directory and references to GitHub secrets.
![Add the HealthChecks custom connector to a Power App.](media/pa-add-custom-connector.png 'HealthChecks connector')
At this point, you can reference the **HealthChecks** connector and methods such as `HealthChecks.gethealthcheck()` to populate canvas elements. Using the available API endpoints, you can create a mobile application which allows for entering new health check data, reviewing old health checks, and listing symptoms on a details page.
```yaml
...
![An example health check application built using Power Apps.](media/health-checks-app.png 'The Health Checks app')
env: # <<-- Add environment variables here
REACT_APP_API_URL: ${{ secrets.API_URL }} # <<-- referencing the GitHub secrets
REACT_APP_API_KEY: ${{ secrets.API_KEY }} # <<-- created in Step 2
jobs:
build:
runs-on: windows-latest
defaults: # <<-- Add default working directory
run: # <<-- here to ensure deployment
working-directory: ./Humongous.Healthcare.Web/ # <<-- targets correct path.
steps:
- uses: actions/checkout@v2
- name: Set up .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
...
```

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

@ -25,8 +25,8 @@ export class HealthCheck extends Component {
<td>{this.state.healthstatus}</td>
<td>
<ul>
{this.state.symptoms.map(symptom =>
<li key={symptom}>{symptom}</li>
{this.state.symptoms.map(symptom, index =>
<li key={index}>{symptom}</li>
)}
</ul>
</td>

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

@ -1,19 +0,0 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy everything
COPY ./Humongous.Healthcare.csproj .
# Restore as distinct layers
RUN dotnet restore
# Copy everything
COPY . .
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "Humongous.Healthcare.dll"]

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

@ -1,25 +0,0 @@
# TODO: The maintainer of this repo has not yet edited this file
**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
- **No CSS support:** Fill out this template with information about how to file issues and get help.
- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.
*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
# Support
## How to file issues and get help
This project uses GitHub Issues to track bugs and feature requests. Please search the existing
issues before filing new issues to avoid duplicates. For new issues, file your bug or
feature request as a new Issue.
For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
## Microsoft Support Policy
Support for this **PROJECT or PRODUCT** is limited to the resources listed above.

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

@ -1,54 +0,0 @@
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: "taw5acrjrc26.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

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

@ -1,16 +0,0 @@
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"

Двоичные данные
media/aks-health-checks.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 39 KiB

Двоичные данные
media/aks-service-and-ingresses.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 113 KiB

Двоичные данные
media/apim-add-policy.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 71 KiB

Двоичные данные
media/apim-configure-cors.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 71 KiB

Двоичные данные
media/apim-configure-https.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 103 KiB

Двоичные данные
media/apim-create.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 32 KiB

После

Ширина:  |  Высота:  |  Размер: 40 KiB

Двоичные данные
media/apim-select-api.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 113 KiB

Двоичные данные
media/apim-select-cors.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 94 KiB

Двоичные данные
media/appsvc-endpoint-url.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 118 KiB

Двоичные данные
media/architecture-diagram.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 54 KiB

После

Ширина:  |  Высота:  |  Размер: 47 KiB

Двоичные данные
media/cicd-create-action.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 101 KiB

После

Ширина:  |  Высота:  |  Размер: 174 KiB

Двоичные данные
media/github-new-repository-secret.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 162 KiB