Code Monkey home page Code Monkey logo

dti_ais's Introduction

AIS COURSE

Morten la Cour

Table of Content

  1. Prerequisites
  2. Logic Apps
  3. Azure Functions
  4. Service Bus
  5. Relay
  6. Event Grid
  7. API Management
  8. Deployment
  9. Deployment2
  10. Security
  11. Data Factory
  12. Pricing
  13. Final Project
  14. Kubernetes
  15. KeyVault Reference
  16. Powershell commands
  17. Links
  18. Kusto
  19. Redis
  20. Devops
  21. Web App
  22. Web Api
  23. Get Token
  24. App Insight
  25. Virtual Machine

API Walkthrough

URl: http://postnumbers.westeurope.azurecontainer.io/Service.asmx

payload

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<Body>
		<GetCity xmlns="http://tempuri.org/">
    		<postnumber>8000</postnumber>
    	</GetCity>
	</Body>
</Envelope>

Exam study

https://docs.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#ValidateJWT

https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core

Prerequisites

Wifi

TEKNOLOGISK-GUEST
.....

Your user (substitute xx with number given by instructor)

Install Chocolatey

In Powershell (Administrator)

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Powershell might need to be reopened

Install Powershell Core

choco install powershell-core -y

Install everything

choco install az.powershell -y
choco install azure-cli -y
choco install azure-functions-core-tools -y
choco install vscode -y
choco install postman -y
choco install notepadplusplus -y
choco install dotnet-sdk -y

Update all (Not needed now)

## Check, run in "old" powershell if powershell-core needs update
choco upgrade all --noop

choco upgrade all -y

Service Bus Explorer

https://github.com/paolosalvatori/ServiceBusExplorer/releases

Logon to Azure in Powershell

Connect-AzAccount
Select-AzSubscription -SubscriptionId .......
Select-AzContext [Tab for all available logins]

Register Nuget.org

dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org

Back to top

Deployment 2

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageName" : { "type" : "string" },
        "location" : {"type" : "string","defaultValue": "[resourceGroup().location]" },
        "sku" : { "type" : "string", "defaultValue": "Standard_GRS" }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2021-09-01",
            "name": "[parameters('storageName')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "[parameters('sku')]"
            },
            "kind": "StorageV2"
        }
    ]
}
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageName" : { "value": "thestupidstoragetest" },
        "sku" : { "value" : "Standard_LRS" }
    }
}
az deployment group create --resource-group $rgName --template-file .\Templates\storageAccount.json --parameters .\Parameters\Prod\storageAccount.json

Back to top

Logic Apps

1 Trigger x Actions

An action

{
	"inputs" : {}, //""
	"type" : "",
	"runAfter : { "ActionName" : [ "Succeeded" ] } //First action : {}
}

Logic App Action Language

this is @{logic app language} bla bla -> Code only inside {}

@outputs('action')

Get the raw output of Action @outputs('name of action') -> Action must be a previous step

Get the body of the json @body('actionName') === @outputs('actionName')['body']

The the content (headers/payload) of the trigger @triggerOutputs() @triggerBody() === @triggerOutputs()['body']

Back to top

Response

"Response": {
                "inputs": {
                    "body": "nnnnn",
                    "statusCode": 200
                },
                "runAfter": {},
                "type": "Response"
            }

Azure Functions

### Set up nuget.org if not already set up
dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org

### Create Isolated Function App
func init myisolatedfunctions --worker-runtime dotnetIsolated --target-framework net7.0

### Inside Function App folder open VS code
code .

### Create Http Trigger Function
func new --name MyFirstHttpTrigger --template HttpTrigger

### Run function app
func start

Deployment

Cli Deployment

## Login az
az login --use-device-code



### Deploy arm template with parameter file (change names and folder location if needed)

az deployment group create --resource-group ais2022 --template-file .\storageAccount.json --parameters .\parameters\prod\storageAccount.json


Arm template

{
	"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
	"contentVersion": "1.0.0.0",
	"parameters" : {
		"accountName" : { "type" : "string" },
		"skuName" : { "type" : "string", "defaultValue" : "Standard_LRS"},
		"skuTier" : { "type" : "string", "defaultValue" : "Standard"},
		"kind" : 	{ "type": "string", "defaultValue" : "StorageV2" },
		"location" : { "type" : "string", "defaultValue" : "[resourceGroup().location]"}
	},
	"resources": [
		{
			"type": "Microsoft.Storage/storageAccounts",
			"apiVersion": "2021-06-01",
			"name": "[parameters('accountName')]",
			"location": "[parameters('location')]",
			"sku": {
                "name": "[parameters('skuName')]",
                "tier": "[parameters('skuTier')]"
            },
			"kind": "[parameters('kind')]"
		}
	]
}

parameter file

{
	"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
	"contentVersion": "1.0.0.0",
	"parameters": {
		"accountName": {
			"value": "mystooooragprod"
		},
		"skuName": {
			"value": "Standard_GRS"
		},
		"skuTier": {
			"value": "Standard"
		}
	}
}

Bicep

Install bicep az

az bicep install

## Confirm install
az bicep version

A simple sample

targetScope = 'resourceGroup'

param accountName string
param location string = resourceGroup().location

param skuName string = 'Standard_LRS'
param kind string = 'StorageV2'

resource account 'Microsoft.Storage/storageAccounts@2021-06-01' = {
  name: accountName
  location: location
  sku: {
    name: skuName
  }
  kind: kind
}

Deploy

az deployment group create --resource-group ais2022 --template-file .\storageAccount.bicep --parameters .\parameters\prod\storageAccount.json

Log Analytics and Logic App bicep samples

solution.bicep

targetScope = 'resourceGroup'

param appName string
param env string


// Log Analytics
var logAnalyticsName = 'log-${appName}-${env}'
module logana 'LogAnalytics.bicep' = {
  name: 'logana'
  params: {
    logAnalyticsName: logAnalyticsName
  }
}

//Logic App
var logicAppName = 'myloganalyticflow'

module logicapp 'logicapp.bicep' = {
  name: 'logicapp'
  params: {
    logicAppName: logicAppName
    logAnalyticsId: logana.outputs.id
  }
}


Log Analytics


targetScope = 'resourceGroup'

param logAnalyticsName string
param location string = resourceGroup().location




resource loganalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
  name: logAnalyticsName
  location: location
}

output id string = loganalytics.id
output customerId string = loganalytics.properties.customerId



Logic App


targetScope = 'resourceGroup'

param logicAppName string
param location string = resourceGroup().location

param logAnalyticsId string

resource logicapp 'Microsoft.Logic/workflows@2019-05-01' = {
  name: logicAppName
  location: location
  properties: {
    definition: {
      '$schema' : 'https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#'
      contentVersion: '1.0.0.0'
      actions: {
        GetRequest: {
          inputs: '@triggerBody()'
          type: 'Compose'
          runAfter: {}
        }
      }
      triggers: {
        http: {
          inputs: {
            schema: {}
          }
          type: 'Request'
          kind: 'Http'
        }
      }
    }
  }
}


//Logic App Diagnostic Settings
resource diagnosticSettings 'Microsoft.Logic/workflows/providers/diagnosticSettings@2021-05-01-preview' = {
  name: '${logicAppName}/Microsoft.Insights/diag'
  dependsOn: [ 
    logicapp 
  ]
  properties: {
    workspaceId: logAnalyticsId
    logs: [
      {
        category: 'WorkflowRuntime'
        enabled: true
      }
    ]
    metrics: [
      {
        category: 'AllMetrics'
        enabled: true
      }
    ]
  }
}


Back to top

Storage Account Deployment

Clear-Host;
$rgName = "dtiarm";

New-AzResourceGroup -Name $rgName -Location "westeurope";

New-AzResourceGroupDeployment -ResourceGroupName $rgName `
    -Mode Incremental -TemplateFile .\create_storage_account.json `
    -TemplateParameterFile .\parameter2.json;




template

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageName": { "type": "string", "maxLength": 24 },
        "sku" : { "type" : "string", "defaultValue": "Standard_LRS"},
        "location" : { "type" : "string", "defaultValue": "[resourceGroup().location]"}
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2021-04-01",
            "name": "[parameters('storageName')]",
            "location": "westeurope",
            "sku": {
                "name": "[parameters('sku')]",
                "tier": "Standard"
            },
            "kind": "StorageV2",
            "properties": {
                "accessTier": "Hot"
            }
        }
    ]
}

Parameters

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "storageName": {
        "value": "dtifirststorage"
      }
    }
  }

Back to top

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "workflowName" : { "type" : "string" },
        "responseText" : { "type" : "string" },
        "location" : { "type" : "string", "defaultValue": "[resourceGroup().location]" }
    },
    "resources": [
        {
            "type": "Microsoft.Logic/workflows",
            "apiVersion": "2017-07-01",
            "name" : "[parameters('workflowName')]",
            "location": "[parameters('location')]",
            "properties" : {
                "definition": {
                    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
                    "contentVersion": "1.0.0.0",
                    "triggers" : {
                        "manual": {
                            "inputs": {
                                "method": "Get",
                                "schema": {}
                            },
                            "kind": "Http",
                            "type": "Request"
                        }
                    },
                    "actions" : {
                        "ComposeIt" : {
                            "inputs" : "[parameters('responseText')]",
                            "type" : "Compose",
                            "runAfter" : {}
                        },
                        "Reponse" : {
                            "inputs" : { "statusCode" : 200, "body" : "@outputs('ComposeIt')" },
                            "type" : "Response",
                            "runAfter" : { "ComposeIt" : [ "Succeeded" ] }
                        }
                    }
                }
            }

        }
]
  }

Deploy Arm Template from Powershell

New-AzResourceGroupDeployment -ResourceGroupName [resourceGroupName] -TemplateFile C:\teaching\dti_ais\armtemplate.json -Verbose      

Arm template parameter file

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "nameOfParameter" : { "value" : "Morten1" }
       
     }
  }

Back to top

Event Grid

  • Create Event Grid Topic

  • Get Url

  • Get Key

    • Set header "aeg-sas-key: key"
  • call endpoint with the following json

[
    {
    "id" : "123456",
    "subject" : "morten.txt",
    "eventType" : "FileCreated",
    "eventTime" : "2021-10-13",
    "data" : {
        "orderSize" : 18,
        "orderId" : "127",
        "customer" : "AVK"
    }
},
    {
    "id" : "123456",
    "subject" : "morten.txt",
    "eventType" : "FileCreated",
    "eventTime" : "2021-10-13",
    "data" : {
        "orderSize" : 180,
        "orderId" : "127",
        "customer" : "AVK"
    }
}
]
  • Create Two Logic Apps (Code may need to have names and path's changed)
Clear-Host;
$rgName = "dtiais2021";

# New-AzResourceGroup -Name $rgName -Location "westeurope";

$result = New-AzResourceGroupDeployment -ResourceGroupName $rgName `
    -Mode Incremental -TemplateFile .\eventgrid_logic_app.json `
    -TemplateParameterFile .\Parameters\Test\eventgrid_logicapp_small_orders.json;


# $result;


Retrieve Logic App URL after deployment

$result.Outputs["logicAppUrl"].Value
$result.Outputs["logicAppUrl"].Value | Set-Clipboard 

Parameters Create both small and large Logic App, so two param files will be needed

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "logicapp_name": {
        "value": "Process_Large_Orders"
      }
    }
  }
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "logicapp_name": { "type": "string" }
    },
    "variables": {
        "logicappVersion" : "2017-07-01"
    },
    "resources": [
        {
            "type": "Microsoft.Logic/workflows",
            "apiVersion": "[variables('logicappVersion')]",
            "name": "[parameters('logicapp_name')]",
            "location": "westeurope",
            "properties": {
                "state": "Enabled",
                "definition": {
                    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {},
                    "triggers": {
                        "manual": {
                            "type": "Request",
                            "splitOn" : "@triggerBody()",
                            "kind": "Http",
                            "inputs": {
                                "schema": {},
                                "method" : "POST"
                            }
                        }
                    },
                    "actions": {
                        "Compose": {
                            "runAfter": {},
                            "type": "Compose",
                            "inputs": "trtr"
                        }
                    },
                    "outputs": {

                     }
                },
                "parameters": {}
            }
        }
    ],
    "outputs": {
        "logicAppUrl": {
            "type": "string",
            "value": "[listCallbackURL(concat(resourceId('Microsoft.Logic/workflows/', parameters('logicapp_name')), '/triggers/manual'), '2017-07-01').value]"
         }
    }
}
  • Create subscription with LA endpoint url as webhook
  • (Experiment with filters on the subscriptions)

Back to top

Api Management

Sequence

outbound Operation before base,
Outbound Api before base,
Outbound Product before base,
Outbound Service before base,
Outbound Service after base,
Outbound Product after base,
Outbound Api after base,
outbound Operation after base

CORS

Place under policy (All API's)

<inbound>
        <cors>
            <allowed-origins>
                <origin>*</origin>
            </allowed-origins>
            <allowed-methods>
                <method>GET</method>
                <method>POST</method>
                <method>PUT</method>
                <method>DELETE</method>
                <method>HEAD</method>
                <method>OPTIONS</method>
                <method>PATCH</method>
                <method>TRACE</method>
            </allowed-methods>
            <allowed-headers>
                <header>*</header>
            </allowed-headers>
            <expose-headers>
                <header>*</header>
            </expose-headers>
        </cors>
    </inbound>

Call Old SOAP Service

Url: https://postnumbers.azurewebsites.net/Service.asmx Method: Post Headers:

SOAPAction: 	http://tempuri.org/GetCity
Content-Type: 	text/xml

Body:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
	<Body>
		<GetCity xmlns="http://tempuri.org/">
    		<postnumber>8200</postnumber>
    	</GetCity>
	</Body>
</Envelope>
  1. Create a blank API, with the Web Service Url
  2. Add an operation (GetCity) GET -> /city/{postnumber}
  3. Call the API operation https://[name].azure-api.net/postnumbers/city/{postnumber}

PostNumber = 5000 You will get a 401 Access Denied

api-key: ...;

500 Internal Error Trace will tell that https://postnumbers.azurewebsites.net/Service.asmx/city/5000 was called

  1. Set the following policies on operation level
 <inbound>
        <base />
        <rewrite-uri template="?op=GetCity" copy-unmatched-params="false" />
        <set-method>POST</set-method>
        <set-header name="Content-Type" exists-action="override">
            <value>text/xml</value>
        </set-header>
        <set-body template="liquid">
			<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
        <Body>
		      <GetCity xmlns="http://tempuri.org/">
            <postnumber>8200</postnumber>
    	    </GetCity>
	      </Body>
			</Envelope>
		</set-body>
</inbound>
  1. Read the Template Parameter instead of the hard-coded value
<pPostNumber>{{context.Request.MatchedParameters["postnumber"]}}</pPostNumber>
  1. Change outbound policies* NOT USED !!
 <outbound>
        <base />
        <xsl-transform>
			<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:source="http://tempuri.org/" exclude-result-prefixes="source">
				<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
				<xsl:template match="/">
					<Response>
						<xsl:value-of select="//source:GetCityResult" />
					</Response>
				</xsl:template>
			</xsl:stylesheet>
		</xsl-transform>
        <xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="true" />
    </outbound>
  1. Alter xslt to prettify JSON NOT USED!!
<Response value="{//source:GetCityResult}" />

Back to Top

Pricing

https://azure.microsoft.com/en-us/pricing/calculator/

Back to top

Final Project

<Order xmlns="http://dti.dk">
<Id>17</Id>
<Item>765</Item>
<Qty>17</Qty>
</Order>

Extract Blob Path and name from subject

 "Compose": {
                "inputs": "@{split(triggerBody()['subject'],'/')[4]}/@{split(triggerBody()['subject'],'/')[6]}",
                "runAfter": {},
                "type": "Compose"
            }

Split On

                "kind": "Http",
                "splitOn" : "@triggerBody()",
                "type": "Request"

                

Function Transform XML

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Xml;
using System.Xml.Xsl;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log, string myInputBlob)
{
 

    string xml = await new StreamReader(req.Body).ReadToEndAsync();
    string xslt = myInputBlob;

    string responseMessage = TransformXML(xml: xml, xsl: xslt);

            return new OkObjectResult(responseMessage);
}

        public static string TransformXML(string xml, string xsl, bool Text = false)
        {
            StringReader sr_xml;
            StringReader sr_xsl;
            sr_xml = new StringReader(xml);
            sr_xsl = new StringReader(xsl);
            XslCompiledTransform trans = new XslCompiledTransform();

            XmlReaderSettings readerSettings = new XmlReaderSettings();

            readerSettings.DtdProcessing = DtdProcessing.Ignore;

            XmlReader xml_reader = XmlReader.Create(sr_xml, readerSettings);
            XmlReader xsl_reader = XmlReader.Create(sr_xsl, readerSettings);
            XsltSettings set = new XsltSettings();
            set.EnableScript = true;
            set.EnableDocumentFunction = true;
            trans.Load(xsl_reader, set, new XmlUrlResolver());
            StringWriter sw = new StringWriter();
            XmlWriter xw = XmlWriter.Create(sw, trans.OutputSettings);
            trans.Transform(xml_reader, xw);
            return sw.ToString();
        }
{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "myInputBlob",
      "type": "blob",
      "path": "xslt/CustomerOrder_to_InternalOrder.xslt",
      "connection": "AzureWebJobsStorage",
      "direction": "in"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ]
}

XSLT file

Storage: create container named xslt

CustomerOrder_to_InternalOrder.xslt

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:source="http://dti.dk" exclude-result-prefixes="source" xmlns:target="http://internal">

<xsl:template match="source:Order">
   <target:CompanyOrder>
<OrderId>
<xsl:value-of select="source:Id" />
</OrderId>
<ItemNo>
<xsl:value-of select="source:Item" />
</ItemNo>
<Quantity>
<xsl:value-of select="source:Qty" />
</Quantity>
</target:CompanyOrder>
</xsl:template>

</xsl:stylesheet>

Back to top

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sqlserver-deployment
spec:
  selector:
    matchLabels:
      app: sqlserver
  replicas: 2
  template:
    metadata:
      labels:
        app: sqlserver
    spec:
      containers:
      - name: sqlserver
        image: mcr.microsoft.com/mssql/server:2019-latest
        imagePullPolicy: Never
        ports:
        - containerPort: 1433
        env:
        - name: MSSQL_PID
          value: "Express"
        - name: ACCEPT_EULA
          value: "Y"
        - name: SA_PASSWORD
          value: "Hyllew001"
---
apiVersion: v1
kind: Service
metadata:
  name: sqlserver-front
spec:
  type: LoadBalancer
  ports:
  - port: 8821
    targetPort: 1433
  selector:
    app: sqlserver

kubectl apply -f .\kuber_real_website.yaml

kubectl delete -f .\kuber_real_website.yaml

kubectl get all

kubectl config get-contexts
kubectl config use-context docker-desktop

## Connect to Azure Kuber

az aks get-credentials --resource-group kube2204 --name kube220401

Back to top

KeyVault Reference

## KEY VAULT REFERENCE IN FUNCTION APP

$rgName = "vault20402";

az group create -n $rgName -l westeurope;

az monitor log-analytics workspace create -g $rgName -n "loga-$rgName";

 $logaId = az monitor log-analytics workspace show -g $rgName -n "loga-$rgName" | ConvertFrom-Json | Select-Object -ExpandProperty id
 
 az monitor app-insights component create -a "app-$rgName" -l westeurope -g $rgName --workspace $logaId;
 
 az storage account create -g $rgName -n "store$($rgName)";
 
 az keyvault create -l westeurope -n "kv-$rgName" -g $rgName --no-wait
 az keyvault create -l westeurope -n "kv-vault20401" -g $rgName

 
az functionapp create -g $rgName --consumption-plan-location westeurope `
    --runtime dotnet-isolated --runtime-version 5.0 --functions-version 3 `
         --name "funcapp-$rgName" --storage-account "store$($rgName)" `
         --app-insights "app-$rgName"
		 
		 az functionapp create -g $rgName --consumption-plan-location westeurope `
    --runtime dotnet --runtime-version 3.1 --functions-version 3 `
         --name "funcapp-$rgName" --storage-account "store$($rgName)" `
         --app-insights "app-$rgName" --no-wait
		 
## No identity

az functionapp identity show -g $rgName -n "funcapp-$rgName"

az functionapp identity assign -g $rgName -n "funcapp-$rgName"

$principalId = az functionapp identity show -g $rgName -n "funcapp-$rgName" | ConvertFrom-Json | Select-Object -ExpandProperty principalId


## Add Secret

az keyvault secret set --name "vaultsecret" --vault-name "kv1-$rgName"  --value "Private Secret2"


Add Security Policty to Vault

az keyvault set-policy -n "kv1-$rgName" --secret-permissions get --object-id $principalId

$appSetting = "[email protected](SecretUri=https://kv1-$rgName.vault.azure.net/secrets/MortenSecret/)";
az functionapp config appsettings set -g $rgName -n "funcapp-$rgName" --settings "'" + $appSetting + "'"


az functionapp config appsettings set -g $rgName -n "funcapp-$rgName" --settings '"

[email protected](SecretUri=https://kv1-vault20401.vault.azure.net/secrets/mortensecret)"'

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
            string responseMessage = System.Environment.GetEnvironmentVariable("mortensecret");
            return new OkObjectResult(responseMessage);
}



az group delete -n $rgName --yes --no-wait

Back to top

Powershell Commands

$url = "https://prod-132.westeurope.logic.azure.com:443/workflows/0d2338d7a97d4ba2ae77e48f58066c38/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=XC_bl4p91RyrfWyuB8zfszYPWkqo8u_0jPPtkfy7x4U";
Invoke-WebRequest $url -Method Post -body "{ ""location"" : ""copenhagen"" }" -Headers @{ "Content-Type" = "application/json" }

Back to top

Links

Logic app Expressions

Back to top

Kusto

Setup Function

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string numberString = req.Query["number"];
log.LogInformation("the number was: {number}",numberString);
//log.LogInformation($"the number was: {numberString}");
    int number = int.Parse(numberString);
    

            return new OkObjectResult($"The number {number} squared is {number * number}");
}

All Requests


AppRequests
| where TimeGenerated > ago(2h)
| where Success == false
| project TimeGenerated, Name, Success, DurationMs, PerformanceBucket, OperationId
| order by TimeGenerated desc

Traces

AppTraces
| where OperationId  == 'operationid'
| project TimeGenerated, Message, SeverityLevel
| order by TimeGenerated asc

Exceptions


AppExceptions
| where OperationId  == 'operationid'
| project TimeGenerated, OuterMessage, InnermostMessage
| order by TimeGenerated asc

Success (Piechart)


AppRequests
| where TimeGenerated > ago(2h)
| summarize count() by tostring(Success)
| render piechart 

Executions by time (and success)


AppRequests
| where TimeGenerated > ago(2h)
| summarize count() by bin(TimeGenerated, 5m), tostring(Success)
| render barchart 


Back to top

Redis

dotnet add package StackExchange.Redis
// See https://aka.ms/new-console-template for more information
using StackExchange.Redis;

Console.WriteLine("Hello, World!");

string connectionString = "tekno.redis.cache.windows.net:6380,password=........=,ssl=True,abortConnect=False";

using var cache = ConnectionMultiplexer.Connect(connectionString);
IDatabase db = cache.GetDatabase();

//Ping pong
var result = await db.ExecuteAsync("ping");

System.Console.WriteLine(result);

//Cache the value
string value = "secret!!";

await db.StringSetAsync("thetype:id",value);

//Retrieve the value
var thefinalResult = await db.StringGetAsync("thetype:id");

System.Console.WriteLine($"The cached value was: {thefinalResult}");

Back to top

Devops

CLI List Pipeline runs

az pipelines runs list --org https://dev.azure.com/integration-it --project the400temp -o jsonc --query "[].{time:finishTime,id:id,reason:reason,user:requestedFor.displayName}"
trigger:
- master

variables:
  sub: 'testsubscription'  

pool:
  vmImage: ubuntu-latest


steps:
- task: AzureCLI@2
  displayName: Azure CLI
  inputs:
    azureSubscription: 'intitsubscription'
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
      az group create -n rg-thedevopsgroup -l westeurope

Back to top

Web App

  1. Create a WebApp
dotnet dev-certs https -t

dotnet new webapp -o [thename]

properties->launchsettings.
 line 15       "applicationUrl": "https://localhost:xxxx;http://localhost:5267",

cd 

dotnet run

Get the https url


dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
dotnet add package Microsoft.Identity.Web;
dotnet add package Microsoft.Identity.Web.UI;

  1. Create App Registration in Entra (entra.microsoft.com)

Under Redirect URI (optional)

Save

Authentication (in App Reg) -> Implicit -> ID Tokens

Visual Studio Code (App)

In appsettings

,  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "...",
    "ClientId": "...",
    "CallbackPath": "/signin-oidc"
  }

Program.cs

using Microsoft.Identity.Web;

builder.Services.AddRazorPages();

builder
    .Services
    .AddMicrosoftIdentityWebAppAuthentication(builder.Configuration);

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy.
    options.FallbackPolicy = options.DefaultPolicy;
});


....


app.UseAuthentication(); //Insert this
app.UseAuthorization();

dotnet run -> Login (Existing browser NOT PROMPTED!!) -> Incagnito

In Shared/ _LoginPartial.cshtml

@using System.Security.Principal

<ul class="navbar-nav">
@if (User.Identity?.IsAuthenticated == true)
{
        <span class="navbar-text text-dark">Hello @User.Identity?.Name!</span>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a>
        </li>
}
else
{
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
        </li>
}

Shared/_Layout.cshtml (line 28)

                    </ul>
                    <partial name="_LoginPartial" />
                </div>

Back to top

Web Api

Create Project

dotnet new webapi -o secureapi
cd secureapi
dotnet add package Microsoft.Identity.Web

Add Code

using Microsoft.Identity.Web;

builder
    .Services
    .AddMicrosoftIdentityWebApiAuthentication(builder.Configuration);
    
  

app.UseAuthentication();
app.UseAuthorization();


//Controllers
[ApiController]
[Authorize]
[Route("[controller]")]


[HttpGet(Name = "GetWeatherForecast")]
[Authorize(Roles = "writer")]

appsettings.json

Audience ONLY needed if not using MS' suggested value

  "AllowedHosts": "*",
  "AzureAd" : {
    "ClientId" : "..",
    "TenantId" : "..",
    "Instance": "https://login.microsoftonline.com/",
    "Audience" : ".."
  }

Test

/weatherforecast

Get Token

https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token

Content-Type: application/x-www-form-urlencoded

Body: grant_type=client_credentials&client_id=..&client_secret=..&scope=../.default

Back to top

App Insight

$rgName = "rg-204-monitor";
$appName =  "204monitor";
$location = "westeurope";

az group create --name $rgName --location $location;


$workspaceJson = az monitor log-analytics workspace create `
	--resource-group $rgName `
	--workspace-name "log-$($appName)" `
	--location $location;
	
$workspace = $workspaceJson | ConvertFrom-Json;
$workspace.id;



$appInsightJson = az monitor app-insights component create `
	--app "appi-$($appName)" `
	--location $location `
	--resource-group $rgName `
	--application-type web `
	--kind web `
	--workspace $workspace.id
	;
	
$appInsight = $appInsightJson | ConvertFrom-Json;
$appInsight.id;


$appInsight.instrumentationKey | Set-Clipboard;
dotnet add package Microsoft.ApplicationInsights.AspNetCore;

builder.Services.AddApplicationInsightsTelemetry();
  "AllowedHosts": "*",
  "ApplicationInsights": {
    "InstrumentationKey": "...."
  }

Virtual Machine

Clear-Host;


$resource="https://management.azure.com/"


## $clientId = "84a354c6-2249-43d8-90c6-55b3d5ccffe1";


## User Managed Identity
$url = "http://169.254.169.254/metadata/identity/oauth2/token?resource=$resource&client_id=$clientId&api-version=2018-02-01";

## System Managed Identity
$url = "http://169.254.169.254/metadata/identity/oauth2/token?resource=$resource&api-version=2018-02-01";


$response = $null;
$response = Invoke-WebRequest -Method Get -Uri $url -Headers @{ "metadata" = "true" };
$response;

$token = $response.Content | ConvertFrom-Json | Select-Object -ExpandProperty access_token;
$expires = $response.Content | ConvertFrom-Json | Select-Object -ExpandProperty expires_on;

$token;
$token | Set-Clipboard;
$expires;

Back to top

dti_ais's People

Contributors

xemmel avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.