Category Archives: Azure

Deploy an ASP.NET Core and Azure SQL Database app to Azure App Service with Bicep,CLI and VS Code

Deploy software infrastructure with Bicep ( more details can be found from https://www.fuju.org/?p=38184

// based on https://www.fuju.org/?p=38184
RESOURCE_GROUP_NAME=23ExampleRG=23ExampleRG
az group create --name $RESOURCE_GROUP_NAME=23ExampleRG --location "eastasia"
az deployment group create --resource-group $RESOURCE_GROUP_NAME=23ExampleRG --template-file 01-main-web-app-sqldb.bicep  --parameters sqlAdministratorLogin='azuresqladmin' sqlAdministratorLoginPassword='MYSECRTEPASSWORD' location='eastasia'

Deploy sample ASP.NET Core Application to App Service with VS code

#https://www.fuju.org/?p=38044 
# https://docs.microsoft.com/en-us/azure/app-service/tutorial-dotnetcore-sqldb-app

git clone https://github.com/Azure-Samples/msdocs-app-service-sqldb-dotnetcore.git
cd msdocs-app-service-sqldb-dotnetcore
dotnet build .
dotnet publish -c Release
#Right-click on the generated publish folder in the Visual Studio Code explorer and #select Deploy to Web App.

Update database connection string and create database table with entity framework core

APP_SERVICE_NAME=websiteacoss37fw5new
RESOURCE_GROUP_NAME=23ExampleRG
SQL_SERVER_NAME=sqlserverRANDOM

az sql db show-connection-string \
    --client ado.net \
    --name sampledb \
    --server $SQL_SERVER_NAME.database.windows.net
	
az webapp config connection-string set \
    -g $RESOURCE_GROUP_NAME \
    -n $APP_SERVICE_NAME \
    -t SQLServer \
    --settings MyDbConnection="Server=tcp:$SQL_SERVER_NAME.database.windows.net,1433;Database=sampledb;User ID=azuresqladmin;Password='MYSECRETPASSWORD';Encrypt=true;Connection Timeout=30;"

# az sql server firewall-rule create --resource-group $RESOURCE_GROUP_NAME --server $SQL_SERVER_NAME.database.windows.net.database.windows.net --name LocalAccess --start-ip-address <your-ip> --end-ip-address <your-ip>

# Change database connection string in "appsettings.json" 
#"ConnectionStrings": {
#    "MyDbConnection": "Server=tcp:$SQL_SERVER_NAME.database.windows.net,1433;
#        Initial Catalog=sampledb;
#        Persist Security Info=False;
#        User ID=azuresqladmin;Password=MYSECRETPASSWORD;
#        Encrypt=True;
#        TrustServerCertificate=False;"
# }
  
# create database table in target database
dotnet tool install -g dotnet-ef
dotnet ef migrations add InitialCreat --project DotNetCoreSqlDb
dotnet ef database update --project DotNetCoreSqlDb

Access web app logs and delete resources group

az webapp log config \
    --web-server-logging 'filesystem' \
    --name $APP_SERVICE_NAME \
    --resource-group $RESOURCE_GROUP_NAME
	
	
az webapp log tail \
    --name $APP_SERVICE_NAME \
    --resource-group $RESOURCE_GROUP_NAME

az group delete --name $RESOURCE_GROUP_NAME

Azure App Service and Bicep

List of sample deployments of Azure App Service with various scenario by using Bicep

  • Azure App service with Blob
  • Azure App Service + SQLDB + App Insight
  • Azure App Service (Webapp + private endpoint (WebApp and SQL Server) + VNET integration.
  • Application Gateway (private and public listeners) -> Azure App Service (via PE) -> SQL Server (via PE)

Azure App service with Blob:
https://github.com/fujute/m18h/blob/master/bicep/00-main.bicep

# https://github.com/fujute/m18h/blob/master/bicep/00-main.bicep
RESOURCE_GROUP='21ExampleRG'
az group create --name $RESOURCE_GROUP--location westus3
az deployment group create --resource-group $RESOURCE_GROUP --template-file main.bicep --parameters environmentType=nonprod

az deployment group list --output table

Azure App Service + SQLDB + App Insight :
https://github.com/fujute/m18h/blob/master/bicep/01-main-web-app-sqldb.bicep

# https://github.com/fujute/m18h/blob/master/bicep/01-main-web-app-sqldb.bicep
RESOURCE_GROUP='22ExampleRG'
az group create --name $RESOURCE_GROUP --location westus3
az deployment group create --resource-group $RESOURCE_GROUP --template-file 01-main-web-app-sqldb.bicep  --parameters sqlAdministratorLogin='azuresqladmin' sqlAdministratorLoginPassword='PLEASECHANGEtoSECRETPASSWORD' location='westus3'

Azure App Service (Webapp + private endpoint (WebApp and SQL Server) + VNET integration:
Deploys two web apps (frontend and backend) and SQL Server securely connected together with VNet integration (webAppFrontend) and Private Endpoint(webAppBackend,SQLServer)
m18h/02-main-webapp-pe-vnet-integration.bicep at master · fujute/m18h (github.com)

# https://github.com/fujute/m18h/blob/master/bicep/02-main-webapp-pe-vnet-integration.bicep
RESOURCE_GROUP='23ExampleRG'
az group create --name $RESOURCE_GROUP--location westus3
az deployment group create --resource-group $RESOURCE_GROUP--template-file 02-main-webapp-pe-vnet-integration.bicep \
--parameters virtualNetworkName='m6290cvnet' sqlAdministratorLoginPassword='PLEASECHANGETOSECUREPASSWORD'

Reference

Integrate your app with an Azure virtual network

ref:
* https://docs.microsoft.com/en-us/azure/app-service/networking-features
* https://docs.microsoft.com/en-us/azure/app-service/overview-vnet-integration

picture: Regional virtual network integration

Application Gateway integration: Integration with App Service (multi-tenant)

Continue reading Azure App Service and Bicep

Workshop: Azure DevOps Release Gate (Query work items, SonarQube, Azure monitor)

A Sample of “Azure DevOps Release Gate ” the Gates with the following items

  • Query work items: Query Active Bug
  • SonarQube: ” Invoke REST API: POST”
  • Azure monitor: Azure monitor Alert

Software infra:

Based on ” Controlling Deployments using Release Gates | Azure DevOps Hands-on-Labs (azuredevopslabs.com) ” and ” Managing technical debt with SonarQube and Azure DevOps | Azure DevOps Hands-on-Labs (azuredevopslabs.com)

  • 2 Web app for sample canary and production
  • sonarqube in Azure Container Instance
AprRG="1TL-MyResourceGroup"
RNUMBER="041822"

az group create -n $AprRG -l eastasia
az appservice plan create -g $AprRG -n MyPlan --sku S1
az webapp create -g $AprRG -p MyPlan -n "PartsUnlimited-$RNUMBER-Canary"
az webapp create -g $AprRG -p MyPlan -n "PartsUnlimited-$RNUMBER-Prod"

RG_ID=$(az group create --name $AprRG  --location "eastasia" --query "id" --output tsv)
SERVICE_PRINCIPAL_NAME="Exzilla-sp-$RNUMBER"
PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --role contributor --scopes $RG_ID --query "password" --output tsv)
USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)

az container create -g $AprRG --name sonarqubeaci180422 --image sonarqube --ports 9000 --dns-name-label mysonarqube200422 --cpu 2 --memory 3.5

#curl -u ea---fe: http://sonarqubeaci180422.exzilla.com:9000/api/qualitygates/project_status?projectKey=MyShuttle

Hint: Azure DevOps Release Gate with Azure DevOps Starter

To build quick demo for “Release Gate” with condition from Azure Board, Azure Monitor and SonarQube

  1. DevOps Starter ” .NET Core -> App Service ”
  2. Add SonarQube in “build” Pipeline
  3. Add Release ” UAT” Stage (Then, we have Dev & UAT)
  4. Add “Pre-deployment approvals”
  5. Add “Pre-deployment Gates” ” Query work items”
    Azure DevOps -> Boards -> Queries -> Active Bugs -> … -> Security -> ReleaseGate Build Service(myOrg) -> Read ( Allow )
  6. Add “monitoring” gate in “Dev” Stage
  7. Add Agentless Job in Tasks( manual Intervention )
  8. Add ” Post-deployment approvals” Gate “Query Azure Monitor Alerts”
  9. Add ” Post-deployment approvals” Gate “Invoke REST API:POST”

#URL suffix:
api/qualitygates/project_status?projectKey=MyShuttle

#success critirial:
eq(root['projectStatus'].status,'OK')

Sample of Canary releases (ref: What are deployment patterns? – Learn | Microsoft Docs )

Labs:

See Also:

A user delegation SAS for blob with the Azure CLI & azcopy

Sample of using A user delegation SAS for blob with the Azure CLI and copy the blob file via azcopy with the SAS token

MY_RG=11-11RG
SUB_ID=<SUBID>
MY_SCOPES="/subscriptions/$SUB_ID/resourceGroups/$MY_RG/providers/Microsoft.Storage/storageAccounts/m14storage"
RG_ID=$(az group create --name $MY_RG  --location southeastasia --query "id" --output tsv)
SERVICE_PRINCIPAL_NAME=Exzilla-sp-14032022
PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --role "Storage Blob Data Contributor" --scopes $MY_SCOPES  --query "password" --output tsv)
USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)

az login --service-principal -u $USER_NAME -p $PASSWORD --tenant <mytenant>.onmicrosoft.com

END=$(date -u -d "30 minutes" '+%Y-%m-%dT%H:%MZ')
SAS4BLOB=$(az storage blob generate-sas \
    --account-name m14storage \
    --container-name data0314 \
    --name "kblob-file-001.txt" \
    --permissions acdrw \
    --expiry $END \
    --auth-mode login \
    --as-user \
    --full-uri )
	
azcopy copy $SAS4BLOB  . 

See Also:

Questions:

  • SP’s Password protection ?

Create Azure Service Principal and “az login”

Sample of creating Resource Group and then create Service Principle with contributor role under the RG for DevOps Pipeline

#MY_RG=1myResourceGroup
#az group create --name $MY_RG --location southeastasia
#RG_ID=$(az group show --name $MY_RG --query "id" --output tsv)
# or 
MY_RG=1myResourceGroup
RG_ID=$(az group create --name $MY_RG  --location southeastasia --query "id" --output tsv)
SERVICE_PRINCIPAL_NAME=Exzilla-sp-21022022
PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --role contributor --scopes $RG_ID  --query "password" --output tsv)
USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)

az login --service-principal -u $USER_NAME -p $PASSWORD --tenant <mytenant>.onmicrosoft.com

Connect to SQL Database from App Service by using a managed identity – System-assigned.

Running App Service with Azure SQL based

Fix list:
The steps in this guide has been tested with “.NET 6.0”

dotnet tool install -g dotnet-ef
dotnet ef migrations add InitialCreate
dotnet ef database update
dotnet add package Microsoft.Data.SqlClient --version 4.0.1
dotnet add package Azure.Identity --version 1.5.0

appsettings.json :

{
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "CoredBConnection": "Server=tcp:mydatabase-server-sqlsrv.database.windows.net;Authentication=Active Directory Default; Database=CoredB;"
  }
} 
az webapp identity assign --resource-group my-002-rg --name webapp-core-sql-018
CREATE USER [webapp-core-sql-018] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [webapp-core-sql-018];
ALTER ROLE db_datawriter ADD MEMBER [webapp-core-sql-018];
ALTER ROLE db_ddladmin ADD MEMBER [webapp-core-sql-018];
GO

Program.cs :

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllersWithViews();
   services.AddDbContext<MyDatabaseContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("CoredBConnection")));
}

See Also:

Web App & Azure SQL Templates:

  • https://docs.microsoft.com/en-us/azure/azure-sql/database/arm-templates-content-guide?tabs=single-database
  • https://docs.microsoft.com/en-us/azure/app-service/samples-resource-manager-templates
  • https://azure.microsoft.com/en-au/resources/templates/web-app-sql-database/

Configuring self-hosted runners with a default self-signed certificate for GitHub Enterprise Server

Quick fix:

  1. Copy “/etc/haproxy/ssl.crt” from GHE Server to Runner machine under ” /usr/local/share/ca-certificates/ “
  1. Updated the certificate in the runner server by running ” sudo update-ca-certificates “
$ az vm image list --all -f GitHub-Enterprise | grep '"urn":' | sort -V
#Standard E4s v3 (4 vcpus, 32 GiB memory)
$ az vm create -n myghesvr -g My-01-RG --size Standard_E4ds_v4 -l southeastasia --image GitHub:GitHub-Enterprise:GitHub-Enterprise:3.3.3 --storage-sku StandardSSD_LRS
$ az vm disk attach --name ghevm-data-01 --new --resource-group My-01-RG --size-gb 100 --sku Standard_LRS --vm-name myghesvr  
$ az vm open-port -n myghesvr  -g My-01-RG --port 8443
$ az vm open-port -n myghesvr -g My-01-RG --port 122 --priority 903
$ az vm open-port -n myghesvr -g My-01-RG --port 443 --priority 904
$ az vm open-port -n myghesvr -g My-01-RG --port 80 --priority 905


Screenshot: Local machine:

$ scp -P 122 admin@myghesvr.exzilla.com:/etc/haproxy/ssl.crt .
$ scp ssl.crt azuser@gherne4.exzilla.com:/home/azuser/ghe7-ssl.crt

Screenshot: Runner machine:

azuser@myghesvr:~$ openssl x509 -noout -text -in /etc/haproxy/ssl.crt
azuser@gherne4:~$ sudo cp ghe7-ssl.crt /usr/local/share/ca-certificates/
azuser@gherne4:~$ ls -l /usr/local/share/ca-certificates
total 4
-rw-r--r-- 1 root root 1618 Feb 13 09:35 ghe7-ssl.crt
azuser@gherne4:~$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs…
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d…
done.
azuser@gherne4:~$

Sample YAML file: m18h/sample-actions-ghe7-self-signed.yaml at master · fujute/m18h (github.com)

Alternative: Disabling TLS certificate verification

## https://docs.github.com/en/actions/hosting-your-own-runners/monitoring-and-troubleshooting-self-hosted-runners#disabling-tls-certificate-verification
##
export GITHUB_ACTIONS_RUNNER_TLS_NO_VERIFY=1
./config.sh --url https://github.com/octo-org/octo-repo --token
./run.sh

See Also:

* Troubleshooting GitHub Actions for your enterprise – GitHub Docs
* https://github.com/actions/runner/issues
* Monitoring and troubleshooting self-hosted runners
* Troubleshooting GitHub Actions for your enterprise

Azure Web App for Containers & Github Action

RESOURCES ” ( The journey through Azure Web Apps | Meetup – 08-March-2021)

Github Workflow:

  • https://docs.microsoft.com/en-us/azure/app-service/deploy-container-github-action?tabs=publish-profile

Configure continuous deployment – Azure App Service | Microsoft Docs

  • https://github.com/Azure/actions-workflow-samples/blob/master/assets/create-secrets-for-GitHub-workflows.md
  • https://github.com/Azure/actions-workflow-samples

App Service & Deployment:

  • https://docs.microsoft.com/en-us/azure/app-service/deploy-best-practices
  • https://docs.microsoft.com/en-us/azure/developer/terraform/provision-infrastructure-using-azure-deployment-slots

Tutorial App Service & Container App:

  • https://docs.microsoft.com/en-us/learn/modules/deploy-run-container-app-service/
  • https://docs.microsoft.com/en-us/azure/app-service/tutorial-multi-container-app
  • https://docs.microsoft.com/en-us/azure/app-service/tutorial-custom-container?pivots=container-linux
  • https://code.visualstudio.com/docs/containers/app-service
  • https://docs.microsoft.com/en-us/azure/devops-project/devops-starter-gh-web-app
  • https://github-actions-hero.now.sh

Reference:

  • https://azure.microsoft.com/en-us/services/app-service/containers/#features
  • https://docs.microsoft.com/en-us/azure/architecture/solution-ideas/articles/dev-test-paas
  • https://docs.microsoft.com/en-us/learn/modules/stage-deploy-app-service-deployment-slots/1-introduction
  • https://docs.microsoft.com/en-us/learn/modules/deploy-run-container-app-service/
  • https://azure.microsoft.com/en-us/services/app-service/containers/


FAQ:

  • https://docs.github.com/en/actions/reference/usage-limits-billing-and-administration
  • https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator

การเตรียมตัวก่อนการเข้าร่วม Developer Workshop – Visual Studio Dev Essentials

เนื่องจากเป็นการอบรมเชิงปฏิบัติ ผมแนะนำสิ่งที่ต้องเตรียมก่อนเข้าอบรมดังต่อไปนี้นะครับ

  1. สมัครสมาชิก ( ฟรี ) โดยใช้ email ที่เป็น @outlook.com หรือ @hotmail.com ที่ https://www.visualstudio.com/dev-essentials/ ซึ่งหลังจากสมัครเรียบร้อยแล้ว ที่ web Browser จะมีหน้าตาประมาณนี้ครับ

Visual Studio Dev Essentials

Continue reading การเตรียมตัวก่อนการเข้าร่วม Developer Workshop – Visual Studio Dev Essentials

ข้อมูลประกอบการอบรมเชิงปฏิบัติ WUNCA35

Topics: การอบรมเชิงปฏิบัติ การประยุกต์ใช้ Cloud Computing สำหรับงานวิจัย และการเรียนการสอน
Date: 21-July-2017
Venue : http://wunca.uni.net.th/wunca35/
Agenda:
9:00 – 10:30 The fundamental concepts of cloud computing and how to apply them
10:30 – 10:45 Break
10:45 – 11:45 Using Node.js to build a back-end application
11:45 – 13:00 Lunch
13:00 – 14:30 How to deploy application to a cloud hosting platform with persistent data
14:30 – 14:45 Break
14:45 – 15:45 Data Science and Machine Learning
15:45 – 16:00 Wrap-up

Prerequisite : การเตรียมตัวก่อนเข้าอบรม

  1. สมัครสมาชิก ( ฟรี ) โดยใช้ email ที่เป็น @outlook.com หรือ @hotmail.com ที่ https://www.visualstudio.com/dev-essentials/ ซึ่งหลังจากสมัครเรียนร้อยแล้ว ที่ web Browser จะมีหน้าตาประมาณนี้ครับ

Continue reading ข้อมูลประกอบการอบรมเชิงปฏิบัติ WUNCA35