Skip to content

Commit

Permalink
PR - Split the Todo and Weather API into different containers for sca…
Browse files Browse the repository at this point in the history
…ling individually (Azure-Samples#13)

* project restructuring

* change deployment process

* change bicep variables

* change azure variables values

* removing debug parameter

* remove no-unused vars

* remove outputs with secrets

* add variable to connection string

* remove bicep variable

* change rg name

* add WeatherApi action

* change path

* change action version

* update images

* update docs

* add key vault docs

* update documentation

* update version docker/build-push-action

* vscode configuration
  • Loading branch information
leandromsft authored Dec 15, 2022
1 parent d513f60 commit 64a7a29
Show file tree
Hide file tree
Showing 125 changed files with 888 additions and 499 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/aspnetcore-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
dotnet-version: 6.0.x

- name: Restore
run: dotnet restore src/aspnetcore.sln
run: dotnet restore src/ContainerApp.sln

- name: Build
run: dotnet build src/aspnetcore.sln --configuration ${{ env.CONFIGURATION }} --no-restore
run: dotnet build src/ContainerApp.sln --configuration ${{ env.CONFIGURATION }} --no-restore

- name: Test
run: dotnet test src/aspnetcorewebapi.test/aspnetcorewebapi.test.csproj --configuration ${{ env.CONFIGURATION }} --no-build --verbosity normal --logger trx --results-directory TestResults
run: dotnet test src/ContainerApp.Test/ContainerApp.Test.csproj --configuration ${{ env.CONFIGURATION }} --no-build --verbosity normal --logger trx --results-directory TestResults
121 changes: 65 additions & 56 deletions .github/workflows/aspnetcore-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,61 @@ on: workflow_dispatch
# branches: [ main ]

env:
AZ_RG_NAME: 'rg-dotnet-containerapp'
AZ_RG_NAME: 'rg-dotnetcontainerapp'
AZ_RG_LOCATION: 'eastus'
AZ_ACR_NAME: 'acrdotnetcontainerapp'
AZ_AKS_NAME: 'aksdotnetcontainerapp'
AZ_SQLSERVER_NAME: 'sqldotnetcontainerapp'
AZ_KV_NAME: 'kvdotnetcontainerap'
AZ_LOADTEST_NAME: 'ltstdotnetcontainerap'

jobs:

iac:
runs-on: ubuntu-latest
steps:
# Checkout code
- name: Checkout aspnetcoreiac
- name: Checkout
uses: actions/checkout@v3

# Log into Azure
- name: Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

# Create Resource Group
- name: Create Resource Group
run: |
if [ $(az group exists --name ${{ env.AZ_RG_NAME }}) = false ]; then
az group create --name ${{ env.AZ_RG_NAME }} --location ${{ env.AZ_RG_LOCATION }}
else
echo "Resource group already exists"
fi
# Deploy Bicep file
- name: Deploy Template
uses: Azure/arm-deploy@v1.0.8
uses: Azure/arm-deploy@v1
with:
scope: subscription
resourceGroupName: ${{ env.AZ_RG_NAME }}
region: ${{ env.AZ_RG_LOCATION }}
template: src/aspnetcoreiac/main.bicep
template: src/ContainerApp.IAC/main.bicep
deploymentMode: Incremental
deploymentName: 'gh-actions'
parameters: rgName=${{ env.AZ_RG_NAME }} rgLocation=${{ env.AZ_RG_LOCATION }} acrName=${{ env.AZ_ACR_NAME }} clusterName=${{ env.AZ_AKS_NAME }} sqlserverName=${{ env.AZ_SQLSERVER_NAME }} sqlAdminLogin=${{ secrets.AZURE_SQL_USERNAME }} sqlAdminPassword=${{ secrets.AZURE_SQL_PASSWORD }}
parameters: acrName=${{ env.AZ_ACR_NAME }} clusterName=${{ env.AZ_AKS_NAME }} sqlserverName=${{ env.AZ_SQLSERVER_NAME }} sqlAdminLogin=${{ secrets.AZURE_SQL_USERNAME }} sqlAdminPassword=${{ secrets.AZURE_SQL_PASSWORD }} kvName=${{ env.AZ_KV_NAME }} loadTestName=${{ env.AZ_LOADTEST_NAME }}

build:
needs: iac
runs-on: ubuntu-latest
steps:
# Checkout code
- name: Checkout aspnetcoreiac
- name: Checkout
uses: actions/checkout@v3

- name: Change Version variable
uses: microsoft/variable-substitution@v1
with:
files: 'src/aspnetcorewebapp/appsettings.json'
files: 'src/ContainerApp.WebApp/appsettings.json'
env:
Version: ${{ GITHUB.RUN_NUMBER }}

Expand Down Expand Up @@ -85,42 +95,66 @@ jobs:
username: ${{ env.ACR_LOGIN }}
password: ${{ env.ACR_PASSWORD }}

- name: Build and push aspnetcorewebapi image
uses: docker/build-push-action@v2.10.0
- name: Build and push TodoApi image
uses: docker/build-push-action@v3
with:
context: src/aspnetcorewebapi
file: src/aspnetcorewebapi/Dockerfile
context: src/ContainerApp.TodoApi
file: src/ContainerApp.TodoApi/Dockerfile
tags: |
${{ env.ACR_URL }}/aspnetcorewebapi:${{ GITHUB.RUN_NUMBER }}
${{ env.ACR_URL }}/aspnetcorewebapi:latest
${{ env.ACR_URL }}/containerapp.todoapi:${{ GITHUB.RUN_NUMBER }}
${{ env.ACR_URL }}/containerapp.todoapi:latest
push: true

- name: Build and push WeatherApi image
uses: docker/build-push-action@v3
with:
context: src/ContainerApp.WeatherApi
file: src/ContainerApp.WeatherApi/Dockerfile
tags: |
${{ env.ACR_URL }}/containerapp.weatherapi:${{ GITHUB.RUN_NUMBER }}
${{ env.ACR_URL }}/containerapp.weatherapi:latest
push: true

- name: Build and push aspnetcorewebapp image
uses: docker/build-push-action@v2.10.0
- name: Build and push ContainerApp.WebApp image
uses: docker/build-push-action@v3
with:
context: src/aspnetcorewebapp
file: src/aspnetcorewebapp/Dockerfile
context: src/ContainerApp.WebApp
file: src/ContainerApp.WebApp/Dockerfile
tags: |
${{ env.ACR_URL }}/aspnetcorewebapp:${{ GITHUB.RUN_NUMBER }}
${{ env.ACR_URL }}/aspnetcorewebapp:latest
${{ env.ACR_URL }}/containerapp.webapp:${{ GITHUB.RUN_NUMBER }}
${{ env.ACR_URL }}/containerapp.webapp:latest
push: true

- name: Replace variables
run: |
echo Build Number = ${{ GITHUB.RUN_NUMBER }}
urlApp=${{ env.ACR_URL }}/aspnetcorewebapp:${{ GITHUB.RUN_NUMBER }}
urlApi=${{ env.ACR_URL }}/aspnetcorewebapi:${{ GITHUB.RUN_NUMBER }}
sqlConnString="Server=tcp:sqldotnetcontainerapp.database.windows.net,1433;Initial Catalog=TodoItem_DB;Persist Security Info=False;User ID=${{ secrets.AZURE_SQL_USERNAME }};Password=${{ secrets.AZURE_SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
urlApp=${{ env.ACR_URL }}/containerapp.webapp:${{ GITHUB.RUN_NUMBER }}
urlTodoApi=${{ env.ACR_URL }}/containerapp.todoapi:${{ GITHUB.RUN_NUMBER }}
urlWeatherApi=${{ env.ACR_URL }}/containerapp.weatherapi:${{ GITHUB.RUN_NUMBER }}
sqlConnString="Server=tcp:${{ env.AZ_SQLSERVER_NAME }}.database.windows.net,1433;Initial Catalog=TodoItem_DB;Persist Security Info=False;User ID=${{ secrets.AZURE_SQL_USERNAME }};Password=${{ secrets.AZURE_SQL_PASSWORD }};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
echo URL APP = $urlApp
echo URL TODO API = $urlTodoApi
echo URL WEATHER API = $urlWeatherApi
sed -i "s|_ImageUrlApp_|$urlApp|g" src/kubernetes-containerapp.yaml
sed -i "s|_ImageUrlApi_|$urlApi|g" src/kubernetes-containerapp.yaml
sed -i "s|_ConnString_|$sqlConnString|g" src/kubernetes-containerapp.yaml
echo "*** Replace ContainerApp.WebApp/k8s-deployment.yaml ***"
sed -i "s|_ImageUrlApp_|$urlApp|g" src/ContainerApp.WebApp/k8s-deployment.yaml
echo "*** Replace ContainerApp.TodoApi/k8s-deployment.yaml ***"
sed -i "s|_ImageUrlApi_|$urlTodoApi|g" src/ContainerApp.TodoApi/k8s-deployment.yaml
sed -i "s|_ConnString_|$sqlConnString|g" src/ContainerApp.TodoApi/k8s-deployment.yaml
echo "*** Replace ContainerApp.WeatherApi/k8s-deployment.yaml ***"
sed -i "s|_ImageUrlApi_|$urlWeatherApi|g" src/ContainerApp.WeatherApi/k8s-deployment.yaml
- name: Upload Kubernetes files
uses: actions/[email protected]
with:
name: k8s
path: src/kubernetes-containerapp.yaml
path: |
src/ContainerApp.WebApp/k8s-deployment.yaml
src/ContainerApp.TodoApi/k8s-deployment.yaml
src/ContainerApp.WeatherApi/k8s-deployment.yaml
release-to-dev:
needs: build
Expand All @@ -138,22 +172,6 @@ jobs:
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

# Setup ACR variables
- name: Set the ACR values
id: setup-variables
run: |
url_acr=$(az acr show -n ${{ env.AZ_ACR_NAME }} --query loginServer --output tsv)
login_acr=$(az acr credential show -n ${{ env.AZ_ACR_NAME }} --query username --output tsv)
password_acr=$(az acr credential show -n ${{ env.AZ_ACR_NAME }} --query passwords[0].value --output tsv)
echo "::add-mask::$url_acr"
echo "::add-mask::$login_acr"
echo "::add-mask::$password_acr"
echo "ACR_URL=$url_acr" >> $GITHUB_ENV
echo "ACR_LOGIN=$login_acr" >> $GITHUB_ENV
echo "ACR_PASSWORD=$password_acr" >> $GITHUB_ENV

# Set the target Azure Kubernetes Service (AKS) cluster.
- name: Deploy set context
Expand All @@ -162,22 +180,13 @@ jobs:
creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: ${{ env.AZ_AKS_NAME }}
resource-group: ${{ env.AZ_RG_NAME }}

# Create image pull secret for ACR
- name: Create k8s secret
uses: azure/k8s-create-secret@v1
with:
container-registry-url: ${{ env.ACR_URL }}
container-registry-username: ${{ env.ACR_LOGIN }}
container-registry-password: ${{ env.ACR_PASSWORD }}
secret-name: mysecret
namespace: default
arguments: --force true

# Deploy app to AKS
- name: Deploy to k8s
uses: azure/k8s-deploy@v1
with:
manifests: my-app-artifact/kubernetes-containerapp.yaml
imagepullsecrets: mysecret
namespace: default
manifests: |
my-app-artifact/ContainerApp.WebApp/k8s-deployment.yaml
my-app-artifact/ContainerApp.TodoApi/k8s-deployment.yaml
my-app-artifact/ContainerApp.WeatherApi/k8s-deployment.yaml
48 changes: 37 additions & 11 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": "aspnetcorewebapp",
"name": "ContainerApp.TodoApi",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "buildApp",
"preLaunchTask": "buildTodoApi",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/aspnetcorewebapp/bin/Debug/net6.0/aspnetcorewebapp.dll",
"program": "${workspaceFolder}/src/ContainerApp.TodoApi/bin/Debug/net6.0/ContainerApp.TodoApi.dll",
"args": [],
"cwd": "${workspaceFolder}/src/aspnetcorewebapp",
"cwd": "${workspaceFolder}/src/ContainerApp.TodoApi",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
Expand All @@ -30,14 +30,39 @@
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": "aspnetcorewebapi",
"name": "ContainerApp.WeatherApi",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "buildApi",
"preLaunchTask": "buildWeatherApi",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/aspnetcorewebapi/bin/Debug/net6.0/aspnetcorewebapi.dll",
"program": "${workspaceFolder}/src/ContainerApp.WeatherApi/bin/Debug/net6.0/ContainerApp.WeatherApi.dll",
"args": [],
"cwd": "${workspaceFolder}/src/aspnetcorewebapi",
"cwd": "${workspaceFolder}/src/ContainerApp.WeatherApi",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}"
}
},
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": "ContainerApp.WebApp",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "buildWebApp",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/ContainerApp.WebApp/bin/Debug/net6.0/ContainerApp.WebApp.dll",
"args": [],
"cwd": "${workspaceFolder}/src/ContainerApp.WebApp",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
Expand All @@ -59,10 +84,11 @@
],
"compounds": [
{
"name": "aspnetcorewebapi & aspnetcorewebapp",
"name": "All Projects",
"configurations": [
"aspnetcorewebapi",
"aspnetcorewebapp"
"ContainerApp.WeatherApi",
"ContainerApp.TodoApi",
"ContainerApp.WebApp"
]
}
]
Expand Down
20 changes: 16 additions & 4 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,36 @@
"version": "2.0.0",
"tasks": [
{
"label": "buildApp",
"label": "buildWebApp",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/aspnetcorewebapp/aspnetcorewebapp.csproj",
"${workspaceFolder}/src/ContainerApp.WebApp/ContainerApp.WebApp.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "buildTodoApi",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/ContainerApp.TodoApi/ContainerApp.TodoApi.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "buildApi",
"label": "buildWeatherApi",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/aspnetcorewebapi/aspnetcorewebapi.csproj",
"${workspaceFolder}/src/ContainerApp.WeatherApi/ContainerApp.WeatherApi.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
Expand Down
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ This is the application architecture diagram

The project is divided as follows:

- **src/aspnetcoreiac:** Bicep files for create Azure environment
- **src/aspnetcorewebapi:** Rest APIs to communicate with database
- **src/aspnetcorewebapp:** Web Application interact with rest API
- **src/aspnetcorewebapi.test:** Unit Testing project
- **src/ContainerApp.IAC:** Bicep files for create Azure environment
- **src/ContainerApp.TodoApi:** TODO API to communicate with SQL Server database
- **src/ContainerApp.WeatherApi:** WEATHER API simulates weather forecasts
- **src/ContainerApp.WebApp:** Web Application interact with rest TODO API and
- **src/ContainerApp.Test:** Unit Testing project

## Getting Started

Expand Down Expand Up @@ -50,13 +51,7 @@ To run the application in debug mode, select the *Debug* menu and select the *as

![Running](/docs/images/img03.png "Application")

Another option to run application based on docker containers. This application user 3 containers as show bellow:

- **aspnetcoredb:** SQL Server
- **aspnetcorewebapi:** Rest APIs to communicate with SQL Server database (backend)
- **aspnetcorewebapp:** ASP NET MVC application to communicate with API (frontend)

In the root directory of the application we have the *DockerCompose.yml* file with all the necessary configurations to running the application using containers. To start run the command below.
Another option to run application based on docker containers. In the root directory of the application we have the *DockerCompose.yml* file with all the necessary configurations to running the application using containers. To start run the command below.

```sh
docker-compose -f 'DockerCompose.yml' up --build -d
Expand All @@ -78,6 +73,8 @@ This bicep file will create the following resources in Azure.

- **[Azure Monitor](https://docs.microsoft.com/en-us/azure/azure-monitor/overview)** helps you maximize the availability and performance of your applications and services. It delivers a comprehensive solution for collecting, analyzing, and acting on telemetry from your cloud and on-premises environments.

- **[Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/general/)** is a cloud service for securely storing and accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, or cryptographic keys

First step is create a Service Principal identity to GitHub connect to Azure Subscription

```sh
Expand Down Expand Up @@ -145,6 +142,8 @@ Navigate to the file [aspnetcore-deployment.yml](.github/workflows/aspnetcore-de
- AZ_ACR_NAME
- AZ_AKS_NAME
- AZ_SQLSERVER_NAME
- AZ_KV_NAME
- AZ_LOADTEST_NAME

This example using manual trigger, to start the workflow following these steps:

Expand Down
Binary file modified docs/images/img01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/img04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/img07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/img09.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

appsettings.Development.json

coverage.json

# User-specific files
Expand Down
Loading

0 comments on commit 64a7a29

Please sign in to comment.