-webappname=mywebapp$RANDOM
-
-# Create a resource group.
-az group create --location westeurope --name myResourceGroup
-
-# Create an App Service plan in `FREE` tier.
-az appservice plan create --name $webappname --resource-group myResourceGroup --sku FREE
-
-# Create a web app.
-az webapp create --name $webappname --resource-group myResourceGroup --plan $webappname
-
-# Configure continuous deployment from Visual Studio Team Services.
-# --git-token parameter is required only once per Azure account (Azure remembers token).
-az webapp deployment source config --name $webappname --resource-group myResourceGroup \
---repo-url $gitrepo --branch master --git-token $token
-
-# Copy the result of the following command into a browser to see the web app.
-echo http://$webappname.azurewebsites.net
diff --git a/app-service/integrate-with-app-gateway/integrate-with-app-gateway.sh b/app-service/integrate-with-app-gateway/integrate-with-app-gateway.sh
new file mode 100644
index 00000000..e039ac5e
--- /dev/null
+++ b/app-service/integrate-with-app-gateway/integrate-with-app-gateway.sh
@@ -0,0 +1,57 @@
+#/bin/bash
+# Passed validation in Cloud Shell on 4/25/2022
+
+#
+# Integrate App Service with Application Gateway
+#
+# This sample script creates an Azure App Service web app,
+# an Azure Virtual Network and an Application Gateway.
+# It then restricts the traffic for the web app to only
+# originate from the Application Gateway subnet.
+#
+# set -e # exit if error
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-app-service-rg-$randomIdentifier"
+tag="integrate-with-app-gateway.sh"
+vNet="msdocs-app-service-vnet-$randomIdentifier"
+subnet="msdocs-app-service-subnet-$randomIdentifier"
+appServicePlan="msdocs-app-service-plan-$randomIdentifier"
+webapp="msdocs-web-app-$randomIdentifier"
+appGateway="msdocs-app-gateway-$randomIdentifier"
+publicIpAddress="msdocs-public-ip-$randomIdentifier"
+
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create network resources
+az network vnet create --resource-group $resourceGroup --name $vNet --location "$location" --address-prefix 10.0.0.0/16 --subnet-name $subnet --subnet-prefix 10.0.1.0/24
+
+az network public-ip create --resource-group $resourceGroup --location "$location" --name $publicIpAddress --dns-name $webapp --sku Standard --zone 1
+
+# Create an App Service plan in `S1` tier
+echo "Creating $appServicePlan"
+az appservice plan create --name $appServicePlan --resource-group $resourceGroup --sku S1
+
+# Create a web app.
+echo "Creating $webapp"
+az webapp create --name $webapp --resource-group $resourceGroup --plan $appServicePlan
+
+appFqdn=$(az webapp show --name $webapp --resource-group $resourceGroup --query defaultHostName -o tsv)
+
+# Create an Application Gateway
+az network application-gateway create --resource-group $resourceGroup --name $appGateway --location "$location" --vnet-name $vNet --subnet $subnet --min-capacity 2 --sku Standard_v2 --http-settings-cookie-based-affinity Disabled --frontend-port 80 --http-settings-port 80 --http-settings-protocol Http --public-ip-address $publicIpAddress --servers $appFqdn --priority 1
+
+az network application-gateway http-settings update --resource-group $resourceGroup --gateway-name $appGateway --name appGatewayBackendHttpSettings --host-name-from-backend-pool
+
+# Apply Access Restriction to Web App
+az webapp config access-restriction add --resource-group $resourceGroup --name $webapp --priority 200 --rule-name gateway-access --subnet $subnet --vnet-name $vNet
+
+# Get the App Gateway Fqdn
+az network public-ip show --resource-group $resourceGroup --name $publicIpAddress --query {AppGatewayFqdn:dnsSettings.fqdn} --output table
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/app-service/monitor-with-logs/monitor-with-logs.sh b/app-service/monitor-with-logs/monitor-with-logs.sh
index bf46d95f..674328c8 100644
--- a/app-service/monitor-with-logs/monitor-with-logs.sh
+++ b/app-service/monitor-with-logs/monitor-with-logs.sh
@@ -1,23 +1,44 @@
#/bin/bash
+# Passed validation in Cloud Shell on 4/25/2022
-# Variables
-appName="AppServiceMonitor$random"
-location="WestUS"
+#
+# Monitor an App Service app with web server logs
+#
+# This sample script creates a resource group,
+# App Service plan, and app, and configures the
+# app to enable web server logs. It then downloads
+# the log files for review.
+#
+# set -e # exit if error
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-app-service-rg-$randomIdentifier"
+tag="monitor-with-logs.sh"
+appServicePlan="msdocs-app-service-plan-$randomIdentifier"
+webapp="msdocs-web-app-$randomIdentifier"
-# Create a Resource Group
-az group create --name myResourceGroup --location $location
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
# Create an App Service Plan
-az appservice plan create --name AppServiceMonitorPlan --resource-group myResourceGroup --location $location
+echo "Creating $appServicePlan"
+az appservice plan create --name $appServicePlan --resource-group $resourceGroup
# Create a Web App and save the URL
-url=$(az webapp create --name $appName --plan AppServiceMonitorPlan --resource-group myResourceGroup --query defaultHostName | sed -e 's/^"//' -e 's/"$//')
+echo "Creating $webapp"
+url=$(az webapp create --name $webapp --resource-group $resourceGroup --plan $appServicePlan --query defaultHostName | sed -e 's/^"//' -e 's/"$//')
# Enable all logging options for the Web App
-az webapp log config --name $appName --resource-group myResourceGroup --application-logging true --detailed-error-messages true --failed-request-tracing true --web-server-logging filesystem
+az webapp log config --name $webapp --resource-group $resourceGroup --application-logging azureblobstorage --detailed-error-messages true --failed-request-tracing true --web-server-logging filesystem
# Create a Web Server Log
curl -s -L $url/404
# Download the log files for review
-az webapp log download --name $webappname --resource-group myResourceGroup
\ No newline at end of file
+az webapp log download --name $webapp --resource-group $resourceGroup
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/app-service/scale-geographic/scale-geographic.sh b/app-service/scale-geographic/scale-geographic.sh
index bb3b46a9..f8b8adb2 100644
--- a/app-service/scale-geographic/scale-geographic.sh
+++ b/app-service/scale-geographic/scale-geographic.sh
@@ -1,26 +1,47 @@
#/bin/bash
+# Passed validation in Cloud Shell on 4/25/2022
-# Variables
-trafficManagerDnsName="myDnsName$random"
-app1Name="AppServiceTM1$random"
-app2Name="AppServiceTM2$random"
-location1="WestUS"
-location2="EastUS"
+#
+# Scale an App Service app worldwide with a high-availability architecture
+#
+# This sample script creates a resource group, two App Service plans,
+# two apps, a traffic manager profile, and two traffic manager endpoints.
+# Once the exercise is complete, you have a high-available architecture,
+# which provides global availability of your app based on the lowest network latency.
+#
+# set -e # exit if error
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-app-service-rg-$randomIdentifier"
+tag="scale-geographic.sh"
+appServicePlan="msdocs-app-service-plan-$randomIdentifier"
+trafficManagerDns="msdocs-dns-$randomIdentifier"
+app1Name="msdocs-appServiceTM1-$randomIdentifier"
+app2Name="msdocs-appServiceTM2-$randomIdentifier"
+location1="West US"
+location2="East US"
-# Create a Resource Group
-az group create --name myResourceGroup --location $location1
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
# Create a Traffic Manager Profile
-az network traffic-manager profile create --name $trafficManagerDnsName-tmp --resource-group myResourceGroup --routing-method Performance --unique-dns-name $trafficManagerDnsName
+echo "Creating $trafficManagerDNS"
+az network traffic-manager profile create --name $trafficManagerDns-tmp --resource-group $resourceGroup --routing-method Performance --unique-dns-name $trafficManagerDns
# Create App Service Plans in two Regions
-az appservice plan create --name $app1Name-Plan --resource-group myResourceGroup --location $location1 --sku S1
-az appservice plan create --name $app2Name-Plan --resource-group myResourceGroup --location $location2 --sku S1
+az appservice plan create --name $app1Name-Plan --resource-group $resourceGroup --location "$location1" --sku S1
+az appservice plan create --name $app2Name-Plan --resource-group $resourceGroup --location "$location2" --sku S1
# Add a Web App to each App Service Plan
-site1=$(az webapp create --name $app1Name --plan $app1Name-Plan --resource-group myResourceGroup --query id --output tsv)
-site2=$(az webapp create --name $app2Name --plan $app2Name-Plan --resource-group myResourceGroup --query id --output tsv)
+site1=$(az webapp create --name $app1Name --plan $app1Name-Plan --resource-group $resourceGroup --query id --output tsv)
+site2=$(az webapp create --name $app2Name --plan $app2Name-Plan --resource-group $resourceGroup --query id --output tsv)
# Assign each Web App as an Endpoint for high-availabilty
-az network traffic-manager endpoint create -n $app1Name-$location1 --profile-name $trafficManagerDnsName-tmp -g myResourceGroup --type azureEndpoints --target-resource-id $site1
-az network traffic-manager endpoint create -n $app2Name-$location2 --profile-name $trafficManagerDnsName-tmp -g myResourceGroup --type azureEndpoints --target-resource-id $site2
\ No newline at end of file
+az network traffic-manager endpoint create -n $app1Name-"$location1" --profile-name $trafficManagerDns-tmp -g $resourceGroup --type azureEndpoints --target-resource-id $site1
+az network traffic-manager endpoint create -n $app2Name-"$location2" --profile-name $trafficManagerDns-tmp -g $resourceGroup --type azureEndpoints --target-resource-id $site2
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/app-service/scale-manual/scale-manual.sh b/app-service/scale-manual/scale-manual.sh
index ce83b249..ab5824ac 100644
--- a/app-service/scale-manual/scale-manual.sh
+++ b/app-service/scale-manual/scale-manual.sh
@@ -1,17 +1,37 @@
#/bin/bash
+# Passed validation in Cloud Shell on 4/25/2022
-# Variables
-appName="AppServiceManualScale$random"
-location="WestUS"
+#
+# Scale an App Service app manually
+#
+# This sample script creates a resource group,
+# an App Service plan, and an app. It then scales
+# the App Service plan from a single instance to multiple instances.
+#
+# set -e # exit if error
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-app-service-rg-$randomIdentifier"
+tag="scale-manual.sh"
+appServicePlan="msdocs-app-service-plan-$randomIdentifier"
+webapp="msdocs-web-app-$randomIdentifier"
-# Create a Resource Group
-az group create --name myResourceGroup --location $location
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
-# Create App Service Plans
-az appservice plan create --name AppServiceManualScalePlan --resource-group myResourceGroup --location $location --sku B1
+# Create an App Service plan in Basic tier
+echo "Creating $appServicePlan"
+az appservice plan create --name $appServicePlan --resource-group $resourceGroup --location "$location" --sku B1
-# Add a Web App
-az webapp create --name $appName --plan AppServiceManualScalePlan --resource-group myResourceGroup
+# Create a web app.
+echo "Creating $webapp"
+az webapp create --name $webapp --resource-group $resourceGroup --plan $appServicePlan
# Scale Web App to 2 Workers
-az appservice plan update --number-of-workers 2 --name AppServiceManualScalePlan --resource-group myResourceGroup
\ No newline at end of file
+az appservice plan update --number-of-workers 2 --name $appServicePlan --resource-group $resourceGroup
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/application-gateway/create-vmss/create-vmss-waf.sh b/application-gateway/create-vmss/create-vmss-waf.sh
new file mode 100644
index 00000000..f4de60bb
--- /dev/null
+++ b/application-gateway/create-vmss/create-vmss-waf.sh
@@ -0,0 +1,86 @@
+# Create a resource group
+az group create --name myResourceGroupAG --location eastus
+
+# Create network resources
+az network vnet create \
+ --name myVNet \
+ --resource-group myResourceGroupAG \
+ --location eastus \
+ --address-prefix 10.0.0.0/16 \
+ --subnet-name myAGSubnet \
+ --subnet-prefix 10.0.1.0/24
+az network vnet subnet create \
+ --name myBackendSubnet \
+ --resource-group myResourceGroupAG \
+ --vnet-name myVNet \
+ --address-prefix 10.0.2.0/24
+az network public-ip create \
+ --resource-group myResourceGroupAG \
+ --name myAGPublicIPAddress
+
+# Create the application gateway with WAF
+az network application-gateway create \
+ --name myAppGateway \
+ --location eastus \
+ --resource-group myResourceGroupAG \
+ --vnet-name myVNet \
+ --subnet myAGSubnet \
+ --capacity 2 \
+ --sku WAF_Medium \
+ --http-settings-cookie-based-affinity Disabled \
+ --frontend-port 80 \
+ --http-settings-port 80 \
+ --http-settings-protocol Http \
+ --public-ip-address myAGPublicIPAddress
+az network application-gateway waf-config set \
+ --enabled true \
+ --gateway-name myAppGateway \
+ --resource-group myResourceGroupAG \
+ --firewall-mode Detection \
+ --rule-set-version 3.0
+
+# Create a virtual machine scale set
+az vmss create \
+ --name myvmss \
+ --resource-group myResourceGroupAG \
+ --image Ubuntu2204 \
+ --admin-username azureuser \
+ --admin-password Azure123456! \
+ --instance-count 2 \
+ --vnet-name myVNet \
+ --subnet myBackendSubnet \
+ --vm-sku Standard_DS2 \
+ --upgrade-policy-mode Automatic \
+ --app-gateway myAppGateway \
+ --backend-pool-name appGatewayBackendPool
+
+# Install NGINX
+az vmss extension set \
+ --publisher Microsoft.Azure.Extensions \
+ --version 2.0 \
+ --name CustomScript \
+ --resource-group myResourceGroupAG \
+ --vmss-name myvmss \
+ --settings '{ "fileUris": ["https://raw.githubusercontent.com/Azure/azure-docs-powershell-samples/master/application-gateway/iis/install_nginx.sh"], "commandToExecute": "./install_nginx.sh" }'
+
+# Create a storage account
+az storage account create \
+ --name myagstore1 \
+ --resource-group myResourceGroupAG \
+ --location eastus \
+ --sku Standard_LRS \
+ --encryption blob
+
+# Configure diagnostics
+appgwid=$(az network application-gateway show --name myAppGateway --resource-group myResourceGroupAG --query id -o tsv)
+storeid=$(az storage account show --name myagstore1 --resource-group myResourceGroupAG --query id -o tsv)
+az monitor diagnostic-settings create --name appgwdiag --resource $appgwid \
+ --logs '[ { "category": "ApplicationGatewayAccessLog", "enabled": true, "retentionPolicy": { "days": 30, "enabled": true } }, { "category": "ApplicationGatewayPerformanceLog", "enabled": true, "retentionPolicy": { "days": 30, "enabled": true } }, { "category": "ApplicationGatewayFirewallLog", "enabled": true, "retentionPolicy": { "days": 30, "enabled": true } } ]' \
+ --storage-account $storeid
+
+# Get the IP address
+az network public-ip show \
+ --resource-group myResourceGroupAG \
+ --name myAGPublicIPAddress \
+ --query [ipAddress] \
+ --output tsv
diff --git a/application-gateway/create-vmss/create-vmss.sh b/application-gateway/create-vmss/create-vmss.sh
new file mode 100644
index 00000000..c1d02280
--- /dev/null
+++ b/application-gateway/create-vmss/create-vmss.sh
@@ -0,0 +1,65 @@
+# Create a resource group
+az group create --name myResourceGroupAG --location eastus
+
+# Create network resources
+az network vnet create \
+ --name myVNet \
+ --resource-group myResourceGroupAG \
+ --location eastus \
+ --address-prefix 10.0.0.0/16 \
+ --subnet-name myAGSubnet \
+ --subnet-prefix 10.0.1.0/24
+az network vnet subnet create \
+ --name myBackendSubnet \
+ --resource-group myResourceGroupAG \
+ --vnet-name myVNet \
+ --address-prefix 10.0.2.0/24
+az network public-ip create \
+ --resource-group myResourceGroupAG \
+ --name myAGPublicIPAddress
+
+# Create the application gateway
+az network application-gateway create \
+ --name myAppGateway \
+ --location eastus \
+ --resource-group myResourceGroupAG \
+ --vnet-name myVNet \
+ --subnet myAGsubnet \
+ --capacity 2 \
+ --sku Standard_Medium \
+ --http-settings-cookie-based-affinity Disabled \
+ --frontend-port 80 \
+ --http-settings-port 80 \
+ --http-settings-protocol Http \
+ --public-ip-address myAGPublicIPAddress
+
+# Create a virtual machine scale set
+az vmss create \
+ --name myvmss \
+ --resource-group myResourceGroupAG \
+ --image Ubuntu2204 \
+ --admin-username azureuser \
+ --admin-password Azure123456! \
+ --instance-count 2 \
+ --vnet-name myVNet \
+ --subnet myBackendSubnet \
+ --vm-sku Standard_DS2 \
+ --upgrade-policy-mode Automatic \
+ --app-gateway myAppGateway \
+ --backend-pool-name appGatewayBackendPool
+
+# Install NGINX
+az vmss extension set \
+ --publisher Microsoft.Azure.Extensions \
+ --version 2.0 \
+ --name CustomScript \
+ --resource-group myResourceGroupAG \
+ --vmss-name myvmss \
+ --settings '{ "fileUris": ["https://raw.githubusercontent.com/davidmu1/samplescripts/master/install_nginx.sh"], "commandToExecute": "./install_nginx.sh" }'
+
+# Get the IP address
+az network public-ip show \
+ --resource-group myResourceGroupAG \
+ --name myAGPublicIPAddress \
+ --query [ipAddress] \
+ --output tsv
\ No newline at end of file
diff --git a/azure-cli/create-azure-resources-at-scale/bash/create-azure-resources-at-scale.sh b/azure-cli/create-azure-resources-at-scale/bash/create-azure-resources-at-scale.sh
new file mode 100644
index 00000000..0f713c18
--- /dev/null
+++ b/azure-cli/create-azure-resources-at-scale/bash/create-azure-resources-at-scale.sh
@@ -0,0 +1,190 @@
+#!/bin/bash
+# Passed validation in Azure Cloud Shell on 5/28/2024
+
+#
+# Variable block
+
+# Replace these three variable values with actual values
+subscriptionID=00000000-0000-0000-0000-00000000
+csvFileLocation="myFilePath\myFileName.csv"
+logFileLocation="myFilePath\myLogName.txt"
+
+# Variable values that contain a prefix can be replaced with the prefix of your choice.
+# These prefixes have a random ID appended to them in the script.
+# Variable values without a prefix will be overwritten by the contents of your CSV file.
+location=""
+createRG=""
+newRgName="msdocs-rg-"
+existingRgName=""
+
+createVnet=""
+vnetName="msdocs-vnet-"
+subnetName="msdocs-subnet-"
+vnetAddressPrefix=""
+subnetAddressPrefixes=""
+
+vmName="msdocs-vm-"
+vmImage=""
+publicIpSku=""
+adminUser=""
+adminPassword="msdocs-PW-@"
+
+# Set your Azure subscription
+az account set --subscription $subscriptionID
+#
+
+#
+# Verify CSV columns are being read correctly
+
+# Take a look at the CSV contents
+cat $csvFileLocation
+
+# Validate select CSV row values
+while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
+do
+ # Generate a random ID
+ let "randomIdentifier=$RANDOM*$RANDOM"
+
+ # Return the values for the first data row
+ # Change the $resourceNo to check different scenarios in your CSV
+ if [ "$resourceNo" = "1" ]; then
+ echo "resourceNo = $resourceNo"
+ echo "location = $location"
+ echo "randomIdentifier = $randomIdentifier"
+ echo ""
+
+ echo "RESOURCE GROUP INFORMATION:"
+ echo "createRG = $createRG"
+ if [ "$createRG" = "TRUE" ]; then
+ echo "newRGName = $newRgName$randomIdentifier"
+ else
+ echo "exsitingRgName = $existingRgName"
+ fi
+ echo ""
+
+ echo "VNET INFORMATION:"
+ echo "createVnet = $createVnet"
+ if [ "$createVnet" = "TRUE" ]; then
+ echo "vnetName = $vnetName$randomIdentifier"
+ echo "subnetName = $subnetName$randomIdentifier"
+ echo "vnetAddressPrefix = $vnetAddressPrefix"
+ echo "subnetAddressPrefixes = $subnetAddressPrefixes"
+ fi
+ echo ""
+
+ echo "VM INFORMATION:"
+ echo "vmName = $vmName$randomIdentifier"
+ echo "vmImage = $vmImage"
+ echo "vmSku = $publicIpSku"
+ if [ `expr length "$adminUser"` == "1" ]; then
+ echo "SSH keys will be generated."
+ else
+ echo "vmAdminUser = $adminUser"
+ echo "vmAdminPassword = $adminPassword$randomIdentifier"
+ fi
+ fi
+# skip the header line
+done < <(tail -n +2 $csvFileLocation)
+#
+
+#
+# Validate script logic
+
+# Create the log file
+echo "SCRIPT LOGIC VALIDATION.">$logFileLocation
+
+# Loop through each row in the CSV file
+while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
+do
+ # Generate a random ID
+ let "randomIdentifier=$RANDOM*$RANDOM"
+
+ # Log resource number and random ID
+ echo "resourceNo = $resourceNo">>$logFileLocation
+ echo "randomIdentifier = $randomIdentifier">>$logFileLocation
+
+ # Check if a new resource group should be created
+ if [ "$createRG" == "TRUE" ]; then
+ echo "Will create RG $newRgName$randomIdentifier.">>$logFileLocation
+ existingRgName=$newRgName$randomIdentifier
+ fi
+
+ # Check if a new virtual network should be created, then create the VM
+ if [ "$createVnet" == "TRUE" ]; then
+ echo "Will create VNet $vnetName$randomIdentifier in RG $existingRgName.">>$logFileLocation
+ echo "Will create VM $vmName$randomIdentifier in Vnet $vnetName$randomIdentifier in RG $existingRgName.">>$logFileLocation
+ else
+ echo "Will create VM $vmName$randomIdentifier in RG $existingRgName.">>$logFileLocation
+ fi
+# Skip the header line.
+done < <(tail -n +2 $csvFileLocation)
+
+# Clear the console and display the log file
+Clear
+cat $logFileLocation
+#
+
+#
+# Create Azure resources
+
+# Create the log file
+echo "CREATE AZURE RESOURCES.">$logFileLocation
+
+# Loop through each CSV row
+while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
+do
+ # Generate a random ID
+ let "randomIdentifier=$RANDOM*$RANDOM"
+
+ # Log resource number, random ID and display start time
+ echo "resourceNo = $resourceNo">>$logFileLocation
+ echo "randomIdentifier = $randomIdentifier">>$logFileLocation
+ echo "Starting creation of resourceNo $resourceNo at $(date +"%Y-%m-%d %T")."
+
+ # Check if a new resource group should be created
+ if [ "$createRG" == "TRUE" ]; then
+ echo "Creating RG $newRgName$randomIdentifier at $(date +"%Y-%m-%d %T").">>$logFileLocation
+ az group create --location $location --name $newRgName$randomIdentifier >>$logFileLocation
+ existingRgName=$newRgName$randomIdentifier
+ echo " RG $newRgName$randomIdentifier creation complete"
+ fi
+
+ # Check if a new virtual network should be created, then create the VM
+ if [ "$createVnet" == "TRUE" ]; then
+ echo "Creating VNet $vnetName$randomIdentifier in RG $existingRgName at $(date +"%Y-%m-%d %T").">>$logFileLocation
+ az network vnet create \
+ --name $vnetName$randomIdentifier \
+ --resource-group $existingRgName \
+ --address-prefix $vnetAddressPrefix \
+ --subnet-name $subnetName$randomIdentifier \
+ --subnet-prefixes $subnetAddressPrefixes >>$logFileLocation
+ echo " VNet $vnetName$randomIdentifier creation complete"
+
+ echo "Creating VM $vmName$randomIdentifier in Vnet $vnetName$randomIdentifier in RG $existingRgName at $(date +"%Y-%m-%d %T").">>$logFileLocation
+ az vm create \
+ --resource-group $existingRgName \
+ --name $vmName$randomIdentifier \
+ --image $vmImage \
+ --vnet-name $vnetName$randomIdentifier \
+ --subnet $subnetName$randomIdentifier \
+ --public-ip-sku $publicIpSku \
+ --generate-ssh-keys >>$logFileLocation
+ echo " VM $vmName$randomIdentifier creation complete"
+ else
+ echo "Creating VM $vmName$randomIdentifier in RG $existingRgName at $(date +"%Y-%m-%d %T").">>$logFileLocation
+ az vm create \
+ --resource-group $existingRgName \
+ --name $vmName$randomIdentifier \
+ --image $vmImage \
+ --public-ip-sku $publicIpSku \
+ --admin-username $adminUser\
+ --admin-password $adminPassword$randomIdentifier >>$logFileLocation
+ echo " VM $vmName$randomIdentifier creation complete"
+ fi
+# skip the header line
+done < <(tail -n +2 $csvFileLocation)
+
+# Clear the console (optional) and display the log file
+# clear
+cat $logFileLocation
+#
diff --git a/azure-cli/create-azure-resources-at-scale/create-azure-resources-at-scale-metadata.csv b/azure-cli/create-azure-resources-at-scale/create-azure-resources-at-scale-metadata.csv
new file mode 100644
index 00000000..6b6df179
--- /dev/null
+++ b/azure-cli/create-azure-resources-at-scale/create-azure-resources-at-scale-metadata.csv
@@ -0,0 +1,5 @@
+resourceNo,location,createRG,exstingRgName,createVnet,vnetAddressPrefix,subnetAddressPrefixes,vmImage,publicIpSku,Adminuser
+1,eastus,TRUE,,TRUE,10.0.0.0/16,10.0.0.0/24,Ubuntu2204,standard,
+2,eastus2,TRUE,,FALSE,,,Debian11,standard,alex-smith
+3,southcentralus,FALSE,msdocs-rg-671528884,FALSE,,,Ubuntu2204,standard,jan-smith
+[empty line for Bash]
\ No newline at end of file
diff --git a/azure-cli/create-azure-resources-at-scale/powershell/create-azure-resources-at-scale.ps1 b/azure-cli/create-azure-resources-at-scale/powershell/create-azure-resources-at-scale.ps1
new file mode 100644
index 00000000..090cec97
--- /dev/null
+++ b/azure-cli/create-azure-resources-at-scale/powershell/create-azure-resources-at-scale.ps1
@@ -0,0 +1,224 @@
+# Run this script in Azure Cloud Shell's PowerShell environment, or PowerShell 7
+# Passed validation in Azure Cloud Shell on 5/28/2024
+
+#
+# Variable block
+
+# Replace these three variable values with actual values
+$subscriptionID = "00000000-0000-0000-0000-00000000"
+$csvFileLocation = "myFilePath\myFileName.csv"
+$logFileLocation = "myFilePath\myLogName.txt"
+
+# Variable values that contain a prefix can be replaced with the prefix of your choice.
+# These prefixes have a random ID appended to them in the script.
+# Variable values without a prefix will be overwritten by the contents of your CSV file.
+$location=""
+$createRG=""
+$newRgName="msdocs-rg-"
+$existingRgName=""
+
+$createVnet=""
+$vnetName="msdocs-vnet-"
+$subnetName="msdocs-subnet-"
+$vnetAddressPrefix=""
+$subnetAddressPrefixes=""
+
+$vmName="msdocs-vm-"
+$vmImage=""
+$publicIpSku=""
+$adminUser=""
+$adminPassword="msdocs-PW-@"
+
+# Set your azure subscription
+az account set --subscription $subscriptionID
+
+# Import your CSV data
+$data = Import-Csv $csvFileLocation -delimiter ","
+#
+
+#
+# Verify CSV columns are being read correctly
+
+# Take a look at the CSV contents
+# The returned table is restricted by the width of your terminal window
+$data | Format-Table
+
+# Validate select CSV row values
+foreach ($row in $data) {
+ $resourceNo = $row.resourceNo
+ $location = $row.location
+ $createRG = $row.createRG
+ $existingRgName = $row.existingRgName
+ $createVnet = $row.createVnet
+ $vnetAddressPrefix = $row.vnetAddressPrefix
+ $subnetAddressPrefixes = $row.subnetAddressPrefixes
+ $vmImage = $row.vmImage
+ $publicIpSku = $row.publicIpSku
+ $adminUser = $row.adminUser
+
+ # Generate a random ID
+ $randomIdentifier = (New-Guid).ToString().Substring(0,8)
+
+ # Return the values for the first data row
+ # Change the $resourceNo to check different scenarios in your CSV
+ if ($resourceNo -eq "1") {
+ Write-Host "resourceNo = $resourceNo"
+ Write-Host "location = $location"
+ Write-Host "randomIdentifier = $randomIdentifier"
+ Write-Host ""
+
+ Write-Host "RESOURCE GROUP INFORMATION:"
+ Write-Host "createRG = $createRG"
+ if ($createRG -eq "TRUE") {
+ Write-Host "newRGName = $newRgName$randomIdentifier"
+ }
+ else {
+ Write-Host "exsitingRgName = $existingRgName"
+ }
+ Write-Host ""
+
+ Write-Host "VNET INFORMATION:"
+ Write-Host "createVnet = $createVnet"
+ if ($createVnet -eq "TRUE") {
+ Write-Host "vnetName = $vnetName$randomIdentifier"
+ Write-Host "subnetName = $subnetName$randomIdentifier"
+ Write-Host "vnetAddressPrefix = $vnetAddressPrefix"
+ Write-Host "subnetAddressPrefixes = $subnetAddressPrefixes"
+ }
+ Write-Host ""
+
+ Write-Host "VM INFORMATION:"
+ Write-Host "vmName = $vmName$randomIdentifier"
+ Write-Host "vmImage = $vmImage"
+ Write-Host "vmSku= $publicIpSku"
+ if ($adminUser -ne "") {
+ Write-Host "vmAdminUser = $adminUser"
+ Write-Host "vmAdminPassword = $adminPassword$randomIdentifier"
+ }
+ else {
+ Write-Host "SSH keys will be generated."
+ }
+ }
+ }
+#
+
+#
+# Validate script logic
+
+# Create the log file
+"SCRIPT LOGIC VALIDATION." | Out-File -FilePath $logFileLocation
+
+# Loop through each row in the CSV file
+foreach ($row in $data) {
+ $resourceNo = $row.resourceNo
+ $location = $row.location
+ $createRG = $row.createRG
+ $existingRgName = $row.existingRgName
+ $createVnet = $row.createVnet
+ $vnetAddressPrefix = $row.vnetAddressPrefix
+ $subnetAddressPrefixes = $row.subnetAddressPrefixes
+ $vmImage = $row.vmImage
+ $publicIpSku = $row.publicIpSku
+ $adminUser = $row.adminUser
+
+ # Generate a random ID
+ $randomIdentifier = (New-Guid).ToString().Substring(0,8)
+
+ # Log resource number and random ID
+ "" | Out-File -FilePath $logFileLocation -Append
+ "resourceNo = $resourceNo" | Out-File -FilePath $logFileLocation -Append
+ "randomIdentifier = $randomIdentifier" | Out-File -FilePath $logFileLocation -Append
+
+ # Check if a new resource group should be created
+ if ($createRG -eq "TRUE") {
+ "Will create RG $newRgName$randomIdentifier." | Out-File -FilePath $logFileLocation -Append
+ $existingRgName = "$newRgName$randomIdentifier"
+ }
+
+ # Check if a new virtual network should be created, then create the VM
+ if ($createVnet -eq "TRUE") {
+ "Will create VNet $vnetName$randomIdentifier in RG $existingRgName." | Out-File -FilePath $logFileLocation -Append
+ "Will create VM $vmName$randomIdentifier in VNet $vnetName$randomIdentifier in RG $existingRgName." | Out-File -FilePath $logFileLocation -Append
+ } else {
+ "Will create VM $vmName$randomIdentifier in RG $existingRgName." | Out-File -FilePath $logFileLocation -Append
+ }
+}
+
+# Display the log file
+Get-Content -Path $logFileLocation
+#
+
+#
+# Create Azure resources
+
+# Create the log file
+"CREATE AZURE RESOURCES." | Out-File -FilePath $logFileLocation
+
+# Loop through each CSV row
+foreach ($row in $data) {
+ $resourceNo = $row.resourceNo
+ $location = $row.location
+ $createRG = $row.createRG
+ $existingRgName = $row.existingRgName
+ $createVnet = $row.createVnet
+ $vnetAddressPrefix = $row.vnetAddressPrefix
+ $subnetAddressPrefixes = $row.subnetAddressPrefixes
+ $vmImage = $row.vmImage
+ $publicIpSku = $row.publicIpSku
+ $adminUser = $row.adminUser
+
+ # Generate a random ID
+ $randomIdentifier = (New-Guid).ToString().Substring(0,8)
+
+ # Log resource number, random ID and display start time
+ "" | Out-File -FilePath $logFileLocation -Append
+ "resourceNo = $resourceNo" | Out-File -FilePath $logFileLocation -Append
+ "randomIdentifier = $randomIdentifier" | Out-File -FilePath $logFileLocation -Append
+ Write-Host "Starting creation of resourceNo $resourceNo at $(Get-Date -format 'u')."
+
+ # Check if a new resource group should be created
+ if ($createRG -eq "TRUE") {
+ "Creating RG $newRgName$randomIdentifier at $(Get-Date -format 'u')." | Out-File -FilePath $logFileLocation -Append
+ az group create --location $location --name $newRgName$randomIdentifier | Out-File -FilePath $logFileLocation -Append
+ $existingRgName = "$newRgName$randomIdentifier"
+ Write-Host " RG $newRgName$randomIdentifier creation complete."
+ }
+
+ # Check if a new virtual network should be created, then create the VM
+ if ($createVnet -eq "TRUE") {
+ "Creating VNet $vnetName$randomIdentifier in RG $existingRgName at $(Get-Date -format 'u')." | Out-File -FilePath $logFileLocation -Append
+ az network vnet create `
+ --name $vnetName$randomIdentifier `
+ --resource-group $existingRgName `
+ --address-prefix $vnetAddressPrefix `
+ --subnet-name $subnetName$randomIdentifier `
+ --subnet-prefixes $subnetAddressPrefixes | Out-File -FilePath $logFileLocation -Append
+ Write-Host " VNet $vnetName$randomIdentifier creation complete."
+
+ "Creating VM $vmName$randomIdentifier in Vnet $vnetName$randomIdentifier in RG $existingRgName at $(Get-Date -format 'u')." | Out-File -FilePath $logFileLocation -Append
+ az vm create `
+ --resource-group $existingRgName `
+ --name $vmName$randomIdentifier `
+ --image $vmImage `
+ --vnet-name $vnetName$randomIdentifier `
+ --subnet $subnetName$randomIdentifier `
+ --public-ip-sku $publicIpSku `
+ --generate-ssh-keys | Out-File -FilePath $logFileLocation -Append
+ Write-Host " VM $vmName$randomIdentifier creation complete."
+ } else {
+ "Creating VM $vmName$randomIdentifier in RG $existingRgName at $(Get-Date -format 'u')." | Out-File -FilePath $logFileLocation -Append
+ az vm create `
+ --resource-group $existingRgName `
+ --name $vmName$randomIdentifier `
+ --image $vmImage `
+ --public-ip-sku $publicIpSku `
+ --admin-username $adminUser `
+ --admin-password $adminPassword$randomIdentifier | Out-File -FilePath $logFileLocation -Append
+ Write-Host " VM $vmName$randomIdentifier creation complete."
+ }
+}
+
+# Clear the console (optional) and display the log file
+# Clear-Host
+Get-Content -Path $logFileLocation
+#
diff --git a/azure-cli/modify-azure-resources-at-scale/bash/modify-azure-resources-at-scale.sh b/azure-cli/modify-azure-resources-at-scale/bash/modify-azure-resources-at-scale.sh
new file mode 100644
index 00000000..45eb4293
--- /dev/null
+++ b/azure-cli/modify-azure-resources-at-scale/bash/modify-azure-resources-at-scale.sh
@@ -0,0 +1 @@
+# Place holder for new script
diff --git a/azure-cli/modify-azure-resources-at-scale/powershell/modify-azure-resources-at-scale.sh b/azure-cli/modify-azure-resources-at-scale/powershell/modify-azure-resources-at-scale.sh
new file mode 100644
index 00000000..8d1c02ea
--- /dev/null
+++ b/azure-cli/modify-azure-resources-at-scale/powershell/modify-azure-resources-at-scale.sh
@@ -0,0 +1 @@
+# placeholder for new script
diff --git a/azure-front-door/deploy-custom-domain/README.md b/azure-front-door/deploy-custom-domain/README.md
new file mode 100644
index 00000000..d107de32
--- /dev/null
+++ b/azure-front-door/deploy-custom-domain/README.md
@@ -0,0 +1,43 @@
+# Azure Front Door: Deploy custom domain
+
+Deploy a Custom Domain name and TLS certificate on an Azure Front Door front-end.
+
+Script provided for this sample:
+
+* [deploy-custom-domain.sh](deploy-custom-domain.sh)
+
+## Deploy custom domain name
+
+Fully automated provisioning of Azure Front Door with custom domain name (hosted by Azure DNS) and TLS cert.
+
+### Pre-requisites
+
+1. [Host your domain in Azure DNS] and create a public zone.
+
+### Getting started
+
+To deploy this sample, review and change hardcoded variables if required. Then execute:
+
+```bash
+AZURE_DNS_ZONE_NAME=www.contoso.com AZURE_DNS_ZONE_RESOURCE_GROUP=contoso-rg ./deploy-custom-apex-domain.sh
+```
+
+The script will:
+
+1. Create a resource group
+1. Create a storage account to host a SPA
+1. Enable SPA hosting on storage account
+1. Upload a "Hello world!" `index.html` file
+1. Create a Front Door profile
+1. Create a DNS alias for the Apex that resolves to the Front Door
+1. Create a CNAME for the `adverify` hostname
+1. Create a Front Door front-end endpoint for the custom domain
+1. Add route from custom domain frontend to SPA origin
+1. Add a routing rule to redirect HTTP -> HTTPS
+1. Enable HTTPS with Front Door managed cert
+
+
+
+[Deploying a static site using AZ CLI]: https://www.davepaquette.com/archive/2020/05/10/deploying-a-static-site-to-azure-using-the-az-cli.aspx
+[Add certificates in Key Vault]:https://docs.microsoft.com/azure/key-vault/certificates/create-certificate-signing-request?tabs=azure-portal#add-certificates-in-key-vault-issued-by-non-partnered-cas
+[Host your domain in Azure DNS]:https://docs.microsoft.com/azure/dns/dns-delegate-domain-azure-dns
diff --git a/azure-front-door/deploy-custom-domain/deploy-custom-domain.sh b/azure-front-door/deploy-custom-domain/deploy-custom-domain.sh
new file mode 100755
index 00000000..f4395999
--- /dev/null
+++ b/azure-front-door/deploy-custom-domain/deploy-custom-domain.sh
@@ -0,0 +1,121 @@
+#!/bin/bash
+
+# exit on error
+set -e
+
+# See ./README.md for notes
+# Please use latest version of AZ CLI
+# Azure DNS public zone must already exist for domain name
+
+#
+# Deploy a Custom Domain name and TLS certificate at the apex (root) on an Azure Front Door front-end.
+
+# VARIABLES
+# Change these hardcoded values if required
+
+let "randomIdentifier=$RANDOM*$RANDOM"
+
+# Use resource group environment variable if set
+if [ "$RESOURCE_GROUP" == '' ];
+ then
+ resourceGroup="msdocs-frontdoor-rg-$randomIdentifier"
+ else
+ resourceGroup="${RESOURCE_GROUP}"
+fi
+
+location='AustraliaEast'
+tag='deploy-custom-domain'
+
+storage="msdocsafd$randomIdentifier"
+
+frontDoor="msdocs-frontdoor-$randomIdentifier"
+frontDoorFrontEnd='www-contoso'
+
+ttl=300
+
+if [ "$AZURE_DNS_ZONE_NAME" == '' ];
+ then
+ echo -e "\033[33mAZURE_DNS_ZONE_NAME environment variable is not set. Front Door will be created but custom frontend will not be configured because custom domain name not provided. Try:\n\n AZURE_DNS_ZONE_NAME=www.contoso.com AZURE_DNS_ZONE_RESOURCE_GROUP=contoso-dns-rg ./deploy-custom-apex-domain.sh\n\nSee Readme for details.\033[0m"
+ else
+ if [ "$AZURE_DNS_ZONE_RESOURCE_GROUP" == '' ];
+ then
+ # write error text
+ echo -e "\033[31mAZURE_DNS_ZONE_RESOURCE_GROUP environment variable is not set. Provide the resource group for the Azure DNS Zone. Try:\n\n AZURE_DNS_ZONE_NAME=www.contoso.com AZURE_DNS_ZONE_RESOURCE_GROUP=contoso-dns-rg ./deploy-custom-apex-domain.sh\n\nSee Readme for details.\033[0m"
+
+ # write stderr and exit
+ >&2 echo "AZURE_DNS_ZONE_RESOURCE_GROUP environment variable is not set."
+ exit 1
+ fi
+fi
+
+# Resource group
+az group create -n $resourceGroup -l $location --tags $tag
+
+
+# STORAGE ACCOUNT
+az storage account create -n $storage -g $resourceGroup -l $location --sku Standard_LRS --kind StorageV2
+
+# Make Storage Account a SPA
+az storage blob service-properties update --account-name $storage --static-website \
+ --index-document 'index.html' --404-document 'index.html'
+
+# Upload index.html
+az storage blob upload --account-name $storage -f ./index.html -c '$web' -n 'index.html' --content-type 'text/html'
+
+# Get the URL to use as the origin URL on the Front Door backend
+spaFQUrl=$( az storage account show -n $storage --query 'primaryEndpoints.web' -o tsv )
+
+# Remove 'https://' and trailing '/'
+spaUrl=${spaFQUrl/https:\/\//} ; spaUrl=${spaUrl/\//}
+
+
+# FRONT DOOR
+frontDoorId=$( az network front-door create -n $frontDoor -g $resourceGroup --tags $tag --accepted-protocols Http Https --backend-address $spaUrl --query 'id' -o tsv )
+
+
+if [ "$AZURE_DNS_ZONE_NAME" != '' ];
+ then
+
+ # AZURE DNS
+ # Apex hostname on contoso.com
+ # Create an Alias DNS recordset
+ az network dns record-set a create -n "@" -g $AZURE_DNS_ZONE_RESOURCE_GROUP --zone-name $AZURE_DNS_ZONE_NAME --target-resource $frontDoorId --ttl $ttl
+
+ # Create the domain verify CNAME
+ az network dns record-set cname set-record -g $AZURE_DNS_ZONE_RESOURCE_GROUP --zone-name $AZURE_DNS_ZONE_NAME --record-set-name "afdverify" --cname "afdverify.$frontDoor.azurefd.net" --ttl $ttl
+
+
+ # FRONT DOOR FRONT END
+ # Create a frontend for the custom domain
+ az network front-door frontend-endpoint create --front-door-name $frontDoor --host-name $AZURE_DNS_ZONE_NAME \
+ --name $frontDoorFrontEnd -g $resourceGroup --session-affinity-enabled 'Disabled'
+
+ # Update the default routing rule to include the new frontend
+ az network front-door routing-rule update --front-door-name $frontDoor -n 'DefaultRoutingRule' -g $resourceGroup \
+ --caching 'Enabled' --accepted-protocols 'Https' \
+ --frontend-endpoints 'DefaultFrontendEndpoint' $frontDoorFrontEnd
+
+ # Create http redirect to https routing rule
+ az network front-door routing-rule create -f $frontDoor -g $resourceGroup -n 'httpRedirect' \
+ --frontend-endpoints $frontDoorFrontEnd --accepted-protocols 'Http' --route-type 'Redirect' \
+ --patterns '/*' --redirect-protocol 'HttpsOnly'
+
+ # Update the default routing rule to include the new frontend
+ az network front-door routing-rule update --front-door-name $frontDoor -n 'DefaultRoutingRule' -g $resourceGroup \
+ --caching 'Enabled' --frontend-endpoints 'DefaultFrontendEndpoint' $frontDoorFrontEnd
+
+
+ # Enable HTTPS. This command will return quickly but provisioning can take up to an hour to complete
+ az network front-door frontend-endpoint enable-https \
+ --front-door-name $frontDoor -n $frontDoorFrontEnd -g $resourceGroup
+fi
+
+#
+
+echo "https://$frontDoor.azurefd.net"
+echo "http://$AZURE_DNS_ZONE_NAME"
+echo "https://$AZURE_DNS_ZONE_NAME"
+echo "$spaFQUrl"
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-front-door/deploy-custom-domain/index.html b/azure-front-door/deploy-custom-domain/index.html
new file mode 100644
index 00000000..6b91ef9e
--- /dev/null
+++ b/azure-front-door/deploy-custom-domain/index.html
@@ -0,0 +1,7 @@
+
+
+ Hello World!
+ Azure Front Door with Custom Domain and HTTPS
+ Azure-Samples/azure-cli-samples/azure-front-door/deploy-custom-domain
+
+
\ No newline at end of file
diff --git a/azure-functions/configure-custom-domain/configure-custom-domain.sh b/azure-functions/configure-custom-domain/configure-custom-domain.sh
deleted file mode 100644
index abd0c71a..00000000
--- a/azure-functions/configure-custom-domain/configure-custom-domain.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-
-fqdn=
-storageName=myfuncdomainstore
-functionAppName=myfuncdomain
-
-# Create a resource resourceGroupName
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create an azure storage account
-az storage account create \
- --name $storageName \
- --location westeurope \
- --resource-group myResourceGroup
-
-# Create an App Service plan in Basic tier (minimum required by custom domains).
-az appservice plan create \
- --name FunctionAppWithAppServicePlan \
- --resource-group myResourceGroup \
- --location westeurope \
- --sku B1
-
-# Create a Function App
-az functionapp create \
- --name $functionAppName \
- --storage-account $storageName \
- --plan FunctionAppWithAppServicePlan \
- --resource-group myResourceGroup
-
-echo "Configure an A record that maps $fqdn to $functionAppName.azurewebsites.net"
-read -p "Press [Enter] key when ready ..."
-
-# Before continuing, go to your DNS configuration UI for your custom domain and follow the
-# instructions at https://aka.ms/appservicecustomdns to configure an A record
-# and point it your web app's default domain name.
-
-# Map your prepared custom domain name to the function app.
-az appservice web config hostname add \
- --webapp $functionAppName \
- --resource-group myResourceGroup \
- --name $fqdn
-
-echo "You can now browse to http://$fqdn"
diff --git a/azure-functions/configure-ssl-certificate/configure-ssl-certificate.sh b/azure-functions/configure-ssl-certificate/configure-ssl-certificate.sh
deleted file mode 100644
index f417d829..00000000
--- a/azure-functions/configure-ssl-certificate/configure-ssl-certificate.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-
-fqdn=
-pfxPath=
-pfxPassword=
-storageName=myfuncsslstore
-functionAppName=myfuncssl
-
-# Create a resource resourceGroupName
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create an azure storage account
-az storage account create \
- --name $storageName \
- --location westeurope \
- --resource-group myResourceGroup
-
-# Create an App Service plan in Basic tier (minimum required by custom domains).
-az appservice plan create
- --name FunctionAppWithAppServicePlan \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku B1
-
-# Create a Function App
-az functionapp create \
- --name $functionAppName \
- --storage-account $storageName \
- --plan FunctionAppWithAppServicePlan \
- --resource-group myResourceGroup
-
-echo "Configure an A record that maps $fqdn to $functionAppName.azurewebsites.net"
-read -p "Press [Enter] key when ready ..."
-
-# Before continuing, go to your DNS configuration UI for your custom domain and follow the
-# instructions at https://aka.ms/appservicecustomdns to configure an A record
-# and point it your web app's default domain name.
-
-# Map your prepared custom domain name to the function app.
-az functionapp config hostname add \
- --webapp $functionAppName \
- --resource-group myResourceGroup \
- --name $fqdn
-
-# Upload the SSL certificate and get the thumbprint.
-thumprint=$(az functionapp config ssl upload --certificate-file $pfxPath \
---certificate-password $pfxPassword --name $functionAppName --resource-group myResourceGroup \
---query thumbprint --output tsv)
-
-# Binds the uploaded SSL certificate to the function app.
-az functionapp config ssl bind \
- --certificate-thumbprint $thumbprint
- --ssl-type SNI \
- --name $functionAppName \
- --resource-group myResourceGroup
-
-echo "You can now browse to https://$fqdn"
\ No newline at end of file
diff --git a/azure-functions/create-function-app-app-service-plan/create-function-app-app-service-plan.sh b/azure-functions/create-function-app-app-service-plan/create-function-app-app-service-plan.sh
index f945422f..505a63d5 100644
--- a/azure-functions/create-function-app-app-service-plan/create-function-app-app-service-plan.sh
+++ b/azure-functions/create-function-app-app-service-plan/create-function-app-app-service-plan.sh
@@ -1,26 +1,37 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
-# Create a resource resourceGroupName
-az group create \
- --name myResourceGroup \
- --location westeurope
+#
+# Function app and storage account names must be unique.
-# Create an azure storage account
-az storage account create \
- --name myappsvcpstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="create-function-app-consumption"
+storage="msdocsaccount$randomIdentifier"
+appServicePlan="msdocs-app-service-plan-$randomIdentifier"
+functionApp="msdocs-serverless-function-$randomIdentifier"
+skuStorage="Standard_LRS"
+skuPlan="B1"
+functionsVersion="4"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an Azure storage account in the resource group.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
# Create an App Service plan
-az appservice plan create \
- --name myappserviceplan \
- --resource-group myResourceGroup \
- --location westeurope
+echo "Creating $appServicePlan"
+az functionapp plan create --name $appServicePlan --resource-group $resourceGroup --location "$location" --sku $skuPlan
# Create a Function App
-az functionapp create \
- --name myappsvcpfunc \
- --storage-account myappsvcpstore \
- --plan myappserviceplan \
- --resource-group myResourceGroup
\ No newline at end of file
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --storage-account $storage --plan $appServicePlan --resource-group $resourceGroup --functions-version $functionsVersion
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/create-function-app-connect-to-cosmos-db/create-function-app-connect-to-cosmos-db.sh b/azure-functions/create-function-app-connect-to-cosmos-db/create-function-app-connect-to-cosmos-db.sh
index e1697fac..a070de0b 100644
--- a/azure-functions/create-function-app-connect-to-cosmos-db/create-function-app-connect-to-cosmos-db.sh
+++ b/azure-functions/create-function-app-connect-to-cosmos-db/create-function-app-connect-to-cosmos-db.sh
@@ -1,44 +1,46 @@
#!/bin/bash
-# create a resource group with location
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# create a storage account
-az storage account create \
- --name funccosmosdbstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
-
-# create a new function app, assign it to the resource group you have just created
-az functionapp create \
- --name myfunccosmosdb \
- --resource-group myResourceGroup \
- --storage-account funccosmosdbstore \
- --consumption-plan-location westeurope
-
-# create cosmosdb database, name must be lowercase.
-az cosmosdb create \
- --name myfunccosmosdb \
- --resource-group myResourceGroup
-
-# Retrieve cosmosdb connection string
-endpoint=$(az cosmosdb show \
- --name myfunccosmosdb \
- --resource-group myResourceGroup \
- --query documentEndpoint \
- --output tsv)
-
-key=$(az cosmosdb list-keys \
- --name myfunccosmosdb \
- --resource-group myResourceGroup \
- --query primaryMasterKey \
- --output tsv)
-
-# configure function app settings to use cosmosdb connection string
-az functionapp config appsettings set \
- --name myfunccosmosdb \
- --resource-group myResourceGroup \
- --setting CosmosDB_Endpoint=$endpoint CosmosDB_Key=$key
\ No newline at end of file
+# Passed validation in Cloud Shell on 3/24/2022
+
+#
+# Function app and storage account names must be unique.
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="create-function-app-connect-to-cosmos-db"
+storage="msdocsaccount$randomIdentifier"
+functionApp="msdocs-serverless-function-$randomIdentifier"
+skuStorage="Standard_LRS"
+functionsVersion="4"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a storage account for the function app.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
+
+# Create a serverless function app in the resource group.
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --resource-group $resourceGroup --storage-account $storage --consumption-plan-location "$location" --functions-version $functionsVersion
+
+# Create an Azure Cosmos DB database account using the same function app name.
+echo "Creating $functionApp"
+az cosmosdb create --name $functionApp --resource-group $resourceGroup
+
+# Get the Azure Cosmos DB connection string.
+endpoint=$(az cosmosdb show --name $functionApp --resource-group $resourceGroup --query documentEndpoint --output tsv)
+echo $endpoint
+
+key=$(az cosmosdb keys list --name $functionApp --resource-group $resourceGroup --query primaryMasterKey --output tsv)
+echo $key
+
+# Configure function app settings to use the Azure Cosmos DB connection string.
+az functionapp config appsettings set --name $functionApp --resource-group $resourceGroup --setting CosmosDB_Endpoint=$endpoint CosmosDB_Key=$key
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/create-function-app-connect-to-storage/create-function-app-connect-to-storage-account.sh b/azure-functions/create-function-app-connect-to-storage/create-function-app-connect-to-storage-account.sh
index f57e32b8..3180df13 100644
--- a/azure-functions/create-function-app-connect-to-storage/create-function-app-connect-to-storage-account.sh
+++ b/azure-functions/create-function-app-connect-to-storage/create-function-app-connect-to-storage-account.sh
@@ -1,30 +1,37 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
-# create a resource group with location
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# create a storage account
-az storage account create \
- --name myfuncstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
-
-# create a new function app, assign it to the resource group you have just created
-az functionapp create \
- --name myfuncstorage \
- --resource-group myResourceGroup \
- --storage-account myfuncstore \
- --consumption-plan-location westeurope
-
-# Retreive the Storage Account connection string
-connstr=$(az storage account show-connection-string --name myfuncstore --resource-group myResourceGroup --query connectionString --output tsv)
-
-# update function app settings to connect to storage account
-az functionapp config appsettings set \
- --name myfuncstorage \
- --resource-group myResourceGroup \
- --settings StorageConStr=$connstr
+#
+# Function app and storage account names must be unique.
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="create-function-app-connect-to-storage-account"
+storage="msdocsaccount$randomIdentifier"
+functionApp="msdocs-serverless-function-$randomIdentifier"
+skuStorage="Standard_LRS"
+functionsVersion="4"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an Azure storage account in the resource group.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
+
+# Create a serverless function app in the resource group.
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --resource-group $resourceGroup --storage-account $storage --consumption-plan-location "$location" --functions-version $functionsVersion
+
+# Get the storage account connection string.
+connstr=$(az storage account show-connection-string --name $storage --resource-group $resourceGroup --query connectionString --output tsv)
+
+# Update function app settings to connect to the storage account.
+az functionapp config appsettings set --name $functionApp --resource-group $resourceGroup --settings StorageConStr=$connstr
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/create-function-app-consumption-python/create-function-app-consumption-python.sh b/azure-functions/create-function-app-consumption-python/create-function-app-consumption-python.sh
new file mode 100644
index 00000000..e3615976
--- /dev/null
+++ b/azure-functions/create-function-app-consumption-python/create-function-app-consumption-python.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
+
+#
+# Function app and storage account names must be unique.
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="create-function-app-consumption-python"
+storage="msdocsaccount$randomIdentifier"
+functionApp="msdocs-serverless-python-function-$randomIdentifier"
+skuStorage="Standard_LRS"
+functionsVersion="4"
+pythonVersion="3.9" #Allowed values: 3.7, 3.8, and 3.9
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an Azure storage account in the resource group.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
+
+# Create a serverless python function app in the resource group.
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --storage-account $storage --consumption-plan-location "$location" --resource-group $resourceGroup --os-type Linux --runtime python --runtime-version $pythonVersion --functions-version $functionsVersion
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/create-function-app-consumption/create-function-app-consumption.sh b/azure-functions/create-function-app-consumption/create-function-app-consumption.sh
index 46bae60a..414d4f15 100644
--- a/azure-functions/create-function-app-consumption/create-function-app-consumption.sh
+++ b/azure-functions/create-function-app-consumption/create-function-app-consumption.sh
@@ -1,18 +1,31 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
-# Create resource group
-az group create --name myResourceGroup --location westeurope
+#
+# Function app and storage account names must be unique.
-# Create an azure storage account
-az storage account create \
- --name myconsumptionstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="create-function-app-consumption"
+storage="msdocsaccount$randomIdentifier"
+functionApp="msdocs-serverless-function-$randomIdentifier"
+skuStorage="Standard_LRS"
+functionsVersion="4"
-# Create Function App
-az functionapp create \
- --name myconsumptionfunc \
- --storage-account myconsumptionstore \
- --consumption-plan-location westeurope \
- --resource-group myResourceGroup
\ No newline at end of file
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an Azure storage account in the resource group.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
+
+# Create a serverless function app in the resource group.
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --storage-account $storage --consumption-plan-location "$location" --resource-group $resourceGroup --functions-version $functionsVersion
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/create-function-app-premium-plan/create-function-app-premium-plan.sh b/azure-functions/create-function-app-premium-plan/create-function-app-premium-plan.sh
new file mode 100644
index 00000000..cb62bbe6
--- /dev/null
+++ b/azure-functions/create-function-app-premium-plan/create-function-app-premium-plan.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
+
+#
+# Function app and storage account names must be unique.
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="create-function-app-premium-plan"
+storage="msdocsaccount$randomIdentifier"
+premiumPlan="msdocs-premium-plan-$randomIdentifier"
+functionApp="msdocs-function-$randomIdentifier"
+skuStorage="Standard_LRS" # Allowed values: Standard_LRS, Standard_GRS, Standard_RAGRS, Standard_ZRS, Premium_LRS, Premium_ZRS, Standard_GZRS, Standard_RAGZRS
+skuPlan="EP1"
+functionsVersion="4"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an Azure storage account in the resource group.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
+
+# Create a Premium plan
+echo "Creating $premiumPlan"
+az functionapp plan create --name $premiumPlan --resource-group $resourceGroup --location "$location" --sku $skuPlan
+
+# Create a Function App
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --storage-account $storage --plan $premiumPlan --resource-group $resourceGroup --functions-version $functionsVersion
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/deploy-function-app-with-function-github-continuous/deploy-function-app-with-function-github-continuous.sh b/azure-functions/deploy-function-app-with-function-github-continuous/deploy-function-app-with-function-github-continuous.sh
index 7d591d62..f5c08e08 100644
--- a/azure-functions/deploy-function-app-with-function-github-continuous/deploy-function-app-with-function-github-continuous.sh
+++ b/azure-functions/deploy-function-app-with-function-github-continuous/deploy-function-app-with-function-github-continuous.sh
@@ -1,29 +1,40 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
-gitrepo=
-token=
+#
-# Enable authenticated git deployment
-az functionapp deployment source update-token \
- --git-token $token
+# Function app and storage account names must be unique.
+let "randomIdentifier=$RANDOM*$RANDOM"
+location=eastus
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="deploy-function-app-with-function-github"
+storage="msdocs$randomIdentifier"
+skuStorage="Standard_LRS"
+functionApp=mygithubfunc$randomIdentifier
+functionsVersion="4"
+runtime="node"
+# Public GitHub repository containing an Azure Functions code project.
+gitrepo=https://github.com/Azure-Samples/functions-quickstart-javascript
+## Enable authenticated git deployment in your subscription when using a private repo.
+#token=
+#az functionapp deployment source update-token \
+# --git-token $token
# Create a resource group.
-az group create \
- --name myResourceGroup \
- --location westeurope
+echo "Creating $resourceGroup in ""$location""..."
+az group create --name $resourceGroup --location "$location" --tags $tag
-# Create an azure storage account
-az storage account create \
- --name funcghcontstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
+# Create an Azure storage account in the resource group.
+echo "Creating $storage"
+az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
-# Create Function App
-az functionapp create \
- --name funcgithubcontinuous \
- --storage-account funcghcontstore \
- --consumption-plan-location westeurope \
- --resource-group myResourceGroup \
- --deployment-source-url $gitrepo \
- --deployment-source-branch master
\ No newline at end of file
+# Create a function app with source files deployed from the specified GitHub repo.
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --storage-account $storage --consumption-plan-location "$location" --resource-group $resourceGroup --deployment-source-url $gitrepo --deployment-source-branch main --functions-version $functionsVersion --runtime $runtime
+
+# Connect to function application
+curl -s "https://${functionApp}.azurewebsites.net/api/httpexample?name=Azure"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-functions/deploy-function-app-with-function-github/deploy-function-app-with-function-github.sh b/azure-functions/deploy-function-app-with-function-github/deploy-function-app-with-function-github.sh
deleted file mode 100644
index c149d0e3..00000000
--- a/azure-functions/deploy-function-app-with-function-github/deploy-function-app-with-function-github.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-gitrepo=
-
-# Create resource group
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create an azure storage account
-az storage account create \
- --name myfuncghstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
-
-# Create Function App
-az functionapp create \
- --name myfuncgithub \
- --storage-account myfuncghstore \
- --consumption-plan-location westeurope \
- --resource-group myResourceGroup
-
-# Deploy from GitHub
-az functionapp deployment source config \
- --name myfuncgithub \
- --resource-group myResourceGroup \
- --repo-url $gitrepo \
- --branch master \
- --manual-integration
\ No newline at end of file
diff --git a/azure-functions/deploy-function-app-with-function-vsts/deploy-function-app-with-function-vsts.sh b/azure-functions/deploy-function-app-with-function-vsts/deploy-function-app-with-function-vsts.sh
deleted file mode 100644
index 0a97e73a..00000000
--- a/azure-functions/deploy-function-app-with-function-vsts/deploy-function-app-with-function-vsts.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-#gitrepo=
-#token=
-
-gitrepo=https://cfowler.visualstudio.com/DefaultCollection/_git/Function-Quickstart
-token=7ckdjsfqzhkurd4fbqbkbfri3gvy6od22fsubpg73m2joovxuvha
-
-# Create a resource group
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create an azure storage account
-az storage account create \
- --name funcvstsstore \
- --location westeurope \
- --resource-group myResourceGroup \
- --sku Standard_LRS
-
-# Create a function app.
-az functionapp create \
- --name myfuncvsts \
- --storage-account funcvstsstore \
- --consumption-plan-location westeurope \
- --resource-group myResourceGroup
-
-az functionapp deployment source config \
- --name myfuncvsts \
- --resource-group myResourceGroup \
- --repo-url $gitrepo \
- --branch master \
- --git-token $token
\ No newline at end of file
diff --git a/azure-functions/functions-cli-mount-files-storage-linux/functions-cli-mount-files-storage-linux.sh b/azure-functions/functions-cli-mount-files-storage-linux/functions-cli-mount-files-storage-linux.sh
new file mode 100644
index 00000000..5c9384d7
--- /dev/null
+++ b/azure-functions/functions-cli-mount-files-storage-linux/functions-cli-mount-files-storage-linux.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/24/2022
+
+#
+# Function app and storage account names must be unique.
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="eastus"
+resourceGroup="msdocs-azure-functions-rg-$randomIdentifier"
+tag="functions-cli-mount-files-storage-linux"
+export AZURE_STORAGE_ACCOUNT="msdocsstorage$randomIdentifier"
+functionApp="msdocs-serverless-function-$randomIdentifier"
+skuStorage="Standard_LRS"
+functionsVersion="4"
+pythonVersion="3.9" #Allowed values: 3.7, 3.8, and 3.9
+share="msdocs-fileshare-$randomIdentifier"
+directory="msdocs-directory-$randomIdentifier"
+shareId="msdocs-share-$randomIdentifier"
+mountPath="/mounted-$randomIdentifier"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an Azure storage account in the resource group.
+echo "Creating $AZURE_STORAGE_ACCOUNT"
+az storage account create --name $AZURE_STORAGE_ACCOUNT --location "$location" --resource-group $resourceGroup --sku $skuStorage
+
+# Set the storage account key as an environment variable.
+export AZURE_STORAGE_KEY=$(az storage account keys list -g $resourceGroup -n $AZURE_STORAGE_ACCOUNT --query '[0].value' -o tsv)
+
+# Create a serverless function app in the resource group.
+echo "Creating $functionApp"
+az functionapp create --name $functionApp --storage-account $AZURE_STORAGE_ACCOUNT --consumption-plan-location "$location" --resource-group $resourceGroup --os-type Linux --runtime python --runtime-version $pythonVersion --functions-version $functionsVersion
+
+# Work with Storage account using the set env variables.
+# Create a share in Azure Files.
+echo "Creating $share"
+az storage share create --name $share
+
+# Create a directory in the share.
+echo "Creating $directory in $share"
+az storage directory create --share-name $share --name $directory
+
+# Create webapp config storage account
+echo "Creating $AZURE_STORAGE_ACCOUNT"
+az webapp config storage-account add \
+--resource-group $resourceGroup \
+--name $functionApp \
+--custom-id $shareId \
+--storage-type AzureFiles \
+--share-name $share \
+--account-name $AZURE_STORAGE_ACCOUNT \
+--mount-path $mountPath \
+--access-key $AZURE_STORAGE_KEY
+
+# List webapp storage account
+az webapp config storage-account list --resource-group $resourceGroup --name $functionApp
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-signalr/create-signalr-service-and-group/create-signalr-service-and-group.sh b/azure-signalr/create-signalr-service-and-group/create-signalr-service-and-group.sh
new file mode 100644
index 00000000..a03192e5
--- /dev/null
+++ b/azure-signalr/create-signalr-service-and-group/create-signalr-service-and-group.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/30/2022
+
+#
+# Create a SignalR Service
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azure-signalr-rg-$randomIdentifier"
+tag="create-signal-service-and-group"
+signalRSvc=msdocs-signalr-svc-$randomIdentifier
+signalRSku="Standard_S1"
+unitCount="1"
+serviceMode="Default"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create the Azure SignalR Service resource
+echo "Creating $signalRSvc"
+az signalr create \
+ --name $signalRSvc \
+ --resource-group $resourceGroup \
+ --sku $signalRSku \
+ --unit-count $unitCount \
+ --service-mode $serviceMode
+
+# Get the SignalR primary connection string
+primaryConnectionString=$(az signalr key list --name $signalRSvc \
+ --resource-group $resourceGroup --query primaryConnectionString -o tsv)
+
+echo "$primaryConnectionString"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/azure-signalr/create-signalr-with-app-service-github-oauth/create-signalr-with-app-service-github-oauth.sh b/azure-signalr/create-signalr-with-app-service-github-oauth/create-signalr-with-app-service-github-oauth.sh
new file mode 100644
index 00000000..f443fb7a
--- /dev/null
+++ b/azure-signalr/create-signalr-with-app-service-github-oauth/create-signalr-with-app-service-github-oauth.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+#========================================================================
+#=== Update these values based on your desired deployment username ===
+#=== and password. ===
+#========================================================================
+deploymentUser=
+deploymentUserPassword=
+
+#========================================================================
+#=== Update these values based on your GitHub OAuth App registration. ===
+#========================================================================
+GitHubClientId=
+GitHubClientSecret=
+
+
+# Generate a unique suffix for the service name
+let randomNum=$RANDOM*$RANDOM
+
+# Generate unique names for the SignalR service, resource group,
+# app service, and app service plan
+SignalRName=SignalRTestSvc$randomNum
+#resource name must be lowercase
+mySignalRSvcName=${SignalRName,,}
+myResourceGroupName=$SignalRName"Group"
+myWebAppName=SignalRTestWebApp$randomNum
+myAppSvcPlanName=$myAppSvcName"Plan"
+
+# Create resource group
+az group create --name $myResourceGroupName --location eastus
+
+# Create the Azure SignalR Service resource
+az signalr create \
+ --name $mySignalRSvcName \
+ --resource-group $myResourceGroupName \
+ --sku Standard_S1 \
+ --unit-count 1 \
+ --service-mode Default
+
+# Create an App Service plan.
+az appservice plan create --name $myAppSvcPlanName --resource-group $myResourceGroupName --sku FREE
+
+# Create the Web App
+az webapp create --name $myWebAppName --resource-group $myResourceGroupName --plan $myAppSvcPlanName
+
+# Get the SignalR primary connection string
+primaryConnectionString=$(az signalr key list --name $mySignalRSvcName \
+ --resource-group $myResourceGroupName --query primaryConnectionString -o tsv)
+
+# Add an app setting to the web app for the SignalR connection
+az webapp config appsettings set --name $myWebAppName --resource-group $myResourceGroupName \
+ --settings "Azure:SignalR:ConnectionString=$primaryConnectionString"
+
+# Add app settings to use with GitHub authentication
+az webapp config appsettings set --name $myWebAppName --resource-group $myResourceGroupName \
+ --settings "GitHubClientId=$GitHubClientId"
+az webapp config appsettings set --name $myWebAppName --resource-group $myResourceGroupName \
+ --settings "GitHubClientSecret=$GitHubClientSecret"
+
+# Add the desired deployment user name and password
+az webapp deployment user set --user-name $deploymentUser --password $deploymentUserPassword
+
+# Configure Git deployment and note the deployment URL in the output
+az webapp deployment source config-local-git --name $myWebAppName --resource-group $myResourceGroupName \
+ --query [url] -o tsv
diff --git a/azure-signalr/create-signalr-with-app-service/create-signalr-with-app-service.sh b/azure-signalr/create-signalr-with-app-service/create-signalr-with-app-service.sh
new file mode 100644
index 00000000..af72e17a
--- /dev/null
+++ b/azure-signalr/create-signalr-with-app-service/create-signalr-with-app-service.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/30/2022
+
+#
+# Create a SignalR Service with an App Service
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azure-signalr-rg-$randomIdentifier"
+tag="create-signal-service-with-app-service"
+signalRSvc="msdocs-signalr-svc-$randomIdentifier"
+webApp="msdocs-web-app-signalr-$randomIdentifier"
+appSvcPlan="msdocs-app-svc-plan-$randomIdentifier"
+signalRSku="Standard_S1"
+unitCount="1"
+serviceMode="Default"
+planSku="Free"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create the Azure SignalR Service resource
+echo "Creating $signalRSvc"
+az signalr create \
+ --name $signalRSvc \
+ --resource-group $resourceGroup \
+ --sku $signalRSku \
+ --unit-count $unitCount \
+ --service-mode $serviceMode
+
+# Create an App Service plan.
+echo "Creating $appSvcPlan"
+az appservice plan create --name $appSvcPlan --resource-group $resourceGroup --sku $planSku
+
+# Create the Web App
+echo "Creating $webApp"
+az webapp create --name $webApp --resource-group $resourceGroup --plan $appSvcPlan
+
+# Get the SignalR primary connection string
+primaryConnectionString=$(az signalr key list --name $signalRSvc \
+ --resource-group $resourceGroup --query primaryConnectionString -o tsv)
+echo $primaryConnectionString
+
+# Add an app setting to the web app for the SignalR connection
+az webapp config appsettings set --name $webApp --resource-group $resourceGroup \
+ --settings "AzureSignalRConnectionString=$primaryConnectionString"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/add-application/add-application.sh b/batch/add-application/add-application.sh
index e31b00fd..a3adc0b8 100644
--- a/batch/add-application/add-application.sh
+++ b/batch/add-application/add-application.sh
@@ -1,30 +1,35 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 5/24/2022
-# Authenticate CLI session.
-az login
+#
+# Add an application to an Azure Batch account
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+[[ "$RESOURCE_GROUP" == '' ]] && resourceGroup="msdocs-batch-rg-$randomIdentifier" || resourceGroup="${RESOURCE_GROUP}"
+tag="add-application"
+storageAccount="msdocsstorage$randomIdentifier"
+batchAccount="msdocsbatch$randomIdentifier"
+
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create a general-purpose storage account in your resource group.
+echo "Creating $storageAccount"
+az storage account create --resource-group $resourceGroup --name $storageAccount --location "$location" --sku Standard_LRS
+
+# Create a Batch account.
+echo "Creating $batchAccount"
+az batch account create --name $batchAccount --storage-account $storageAccount --resource-group $resourceGroup --location "$location"
+
+# Authenticate against the account directly for further CLI interaction.
+az batch account login --name $batchAccount --resource-group $resourceGroup --shared-key-auth
# Create a new application.
-az batch application create \
- --resource-group myresourcegroup \
- --name mybatchaccount \
- --application-id myapp \
- --display-name "My Application"
-
-# An application can reference multiple application executable packages
-# of different versions. The executables and any dependencies will need
-# to be zipped up for the package. Once uploaded, the CLI will attempt
-# to activate the package so that it's ready for use.
-az batch application package create \
- --resource-group myresourcegroup \
- --name mybatchaccount \
- --application-id myapp \
- --package-file my-application-exe.zip \
- --version 1.0
-
-# We will update our application to assign the newly added application
-# package as the default version.
-az batch application set \
- --resource-group myresourcegroup \
- --name mybatchaccount \
- --application-id myapp \
- --default-version 1.0
\ No newline at end of file
+az batch application create --resource-group $resourceGroup --name $batchAccount --application-name "MyApplication"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/create-account/create-account-user-subscription.sh b/batch/create-account/create-account-user-subscription.sh
index 355c0187..73c46e14 100644
--- a/batch/create-account/create-account-user-subscription.sh
+++ b/batch/create-account/create-account-user-subscription.sh
@@ -1,41 +1,43 @@
+# test 5-29
#!/bin/bash
+# Passed validation in Cloud Shell on 5/24/2022
-# Authenticate CLI session.
-az login
+#
+# Create a Batch account in user subscription mode
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+[[ "$RESOURCE_GROUP" == '' ]] && resourceGroup="msdocs-batch-rg-$randomIdentifier" || resourceGroup="${RESOURCE_GROUP}"
+tag="create-account-user-subscription"
+keyVault="msdocskeyvault$randomIdentifier"
+batchAccount="msdocsbatch$randomIdentifier"
# Allow Azure Batch to access the subscription (one-time operation).
-az role assignment create --assignee MicrosoftAzureBatch --role contributor
-
-# Create a resource group.
-az group create --name myresourcegroup --location westeurope
-
-# A Batch account that will allocate pools in the user's subscription must be configured
-# with a Key Vault located in the same region. Let's create this first.
-az keyvault create \
- --resource-group myresourcegroup \
- --name mykevault \
- --location westeurope \
- --enabled-for-deployment true \
- --enabled-for-disk-encryption true \
- --enabled-for-template-deployment true
-
-# We will add an access-policy to the Key Vault to allow access by the Batch Service.
-az keyvault set-policy \
- --resource-group myresourcegroup \
- --name mykevault \
- --spn ddbf3205-c6bd-46ae-8127-60eb93363864 \
- --key-permissions all \
- --secret-permissions all
-
-# Now we can create the Batch account, referencing the Key Vault either by name (if they
+az role assignment create --assignee ddbf3205-c6bd-46ae-8127-60eb93363864 --role contributor
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create an Azure Key Vault. A Batch account that allocates pools in the user's subscription
+# must be configured with a Key Vault located in the same region.
+echo "Creating $keyVault"
+az keyvault create --resource-group $resourceGroup --name $keyVault --location "$location" --enabled-for-deployment true --enabled-for-disk-encryption true --enabled-for-template-deployment true
+
+# Add an access policy to the Key Vault to allow access by the Batch Service.
+az keyvault set-policy --resource-group $resourceGroup --name $keyVault --spn ddbf3205-c6bd-46ae-8127-60eb93363864 --key-permissions all --secret-permissions all
+
+# Create the Batch account, referencing the Key Vault either by name (if they
# exist in the same resource group) or by its full resource ID.
-az batch account create \
- --resource-group myresourcegroup \
- --name mybatchaccount \
- --location westeurope \
- --keyvault mykevault
-
-# We can now authenticate directly against the account for further CLI interaction.
-# Note that Batch accounts that allocate pools in the user's subscription must be
+echo "Creating $batchAccount"
+az batch account create --resource-group $resourceGroup --name $batchAccount --location "$location" --keyvault $keyVault
+
+# Authenticate directly against the account for further CLI interaction.
+# Batch accounts that allocate pools in the user's subscription must be
# authenticated via an Azure Active Directory token.
-az batch account login -g myresourcegroup -n mybatchaccount
+az batch account login -g $resourceGroup -n $batchAccount
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/create-account/create-account.sh b/batch/create-account/create-account.sh
index 564386d5..9669b618 100644
--- a/batch/create-account/create-account.sh
+++ b/batch/create-account/create-account.sh
@@ -1,27 +1,44 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 5/24/2022
-# Authenticate CLI session.
-az login
+#
+# Create a Batch account in Batch service mode
-# Create a resource group.
-az group create --name myresourcegroup --location westeurope
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+[[ "$RESOURCE_GROUP" == '' ]] && resourceGroup="msdocs-batch-rg-$randomIdentifier" || resourceGroup="${RESOURCE_GROUP}"
+tag="create-account"
+batchAccount="msdocsbatch$randomIdentifier"
+storageAccount="msdocsstorage$randomIdentifier"
-# Create a Batch account.
-az batch account create -g myresourcegroup -n mybatchaccount -l westeurope
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
-# Now we can display the details of our created account.
-az batch account show -g myresourcegroup -n mybatchaccount
+# Create a Batch account
+echo "Creating $batchAccount"
+az batch account create --resource-group $resourceGroup --name $batchAccount --location "$location"
-# Let's add a storage account reference to the Batch account for use as 'auto-storage'
-# for applications. We'll start by creating the storage account.
-az storage account create -g myresourcegroup -n mystorageaccount -l westeurope --sku Standard_LRS
+# Display the details of the created account.
+az batch account show --resource-group $resourceGroup --name $batchAccount
-# And then update the Batch account with the either the name (if they exist in
+# Add a storage account reference to the Batch account for use as 'auto-storage'
+# for applications. Start by creating the storage account.
+echo "Creating $storageAccount"
+az storage account create --resource-group $resourceGroup --name $storageAccount --location "$location" --sku Standard_LRS
+
+# Update the Batch account with the either the name (if they exist in
# the same resource group) or the full resource ID of the storage account.
-az batch account set -g myresourcegroup -n mybatchaccount --storage-account mystorageaccount
+echo "Adding $storageAccount to $batchAccount"
+az batch account set --resource-group $resourceGroup --name $batchAccount --storage-account $storageAccount
+
+# View the access keys to the Batch Account for future client authentication.
+az batch account keys list --resource-group $resourceGroup --name $batchAccount
-# We can view the access keys to the Batch Account for future client authentication.
-az batch account keys list -g myresourcegroup -n mybatchaccount
+# Authenticate against the account directly for further CLI interaction.
+az batch account login --resource-group $resourceGroup --name $batchAccount --shared-key-auth
+#
-# Or we can authenticate against the account directly for further CLI interaction.
-az batch account login -g myresourcegroup -n mybatchaccount --shared-key-auth
\ No newline at end of file
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/manage-pool/manage-pool-linux.sh b/batch/manage-pool/manage-pool-linux.sh
index c41654a2..5a64a0f6 100644
--- a/batch/manage-pool/manage-pool-linux.sh
+++ b/batch/manage-pool/manage-pool-linux.sh
@@ -1,38 +1,48 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 5/24/2022
+
+#
+# Create and manage a Linux pool in Azure Batch
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+[[ "$RESOURCE_GROUP" == '' ]] && resourceGroup="msdocs-batch-rg-$randomIdentifier" || resourceGroup="${RESOURCE_GROUP}"
+tag="manage-pool-linux"
+batchAccount="msdocsbatch$randomIdentifier"
+
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create a Batch account.
+echo "Creating $batchAccount"
+az batch account create --resource-group $resourceGroup --name $batchAccount --location "$location"
# Authenticate Batch account CLI session.
-az batch account login -g myresource group -n mybatchaccount
+az batch account login --resource-group $resourceGroup --name $batchAccount --shared-key-auth
# Retrieve a list of available images and node agent SKUs.
-az batch pool node-agent-skus list
+az batch pool supported-images list --query "[?contains(imageReference.offer,'ubuntuserver') && imageReference.publisher == 'canonical'].{Offer:imageReference.offer, Publisher:imageReference.publisher, Sku:imageReference.sku, nodeAgentSkuId:nodeAgentSkuId}[-1]" --output tsv
# Create a new Linux pool with a virtual machine configuration. The image reference
# and node agent SKUs ID can be selected from the ouptputs of the above list command.
# The image reference is in the format: {publisher}:{offer}:{sku}:{version} where {version} is
-# optional and will default to 'latest'.
-az batch pool create \
- --id mypool-linux \
- --vm-size Standard_A1 \
- --image canonical:ubuntuserver:16.04.0-LTS \
- --node-agent-sku-id batch.node.ubuntu 16.04
-
-# Now let's resize the pool to start up some VMs.
+# optional and defaults to 'latest'."
+
+az batch pool create --id mypool-linux --vm-size Standard_A1 --image canonical:ubuntuserver:18_04-lts-gen2 --node-agent-sku-id "batch.node.ubuntu 18.04"
+
+# Resize the pool to start some VMs.
az batch pool resize --pool-id mypool-linux --target-dedicated 5
-# We can check the status of the pool to see when it has finished resizing.
+# Check the status of the pool to see when it has finished resizing.
az batch pool show --pool-id mypool-linux
# List the compute nodes running in a pool.
az batch node list --pool-id mypool-linux
-# If a particular node in the pool is having issues, it can be rebooted or reimaged.
-# The ID of the node can be retrieved with the list command above.
-# A typical node ID will be in the format 'tvm-xxxxxxxxxx_1-'.
-az batch node reboot --pool-id mypool-linux --node-id tvm-123_1-20170316t000000z
-
-# Alternatively, one or more compute nodes can be deleted from the pool, and any
-# work already assigned to it can be re-allocated to another node.
-az batch node delete \
- --pool-id mypool-linux \
- --node-list tvm-123_1-20170316t000000z tvm-123_2-20170316t000000z \
- --node-deallocation-option requeue
+# returns [] if no compute nodes are running
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/manage-pool/manage-pool-windows.sh b/batch/manage-pool/manage-pool-windows.sh
index e277fab9..1a06522b 100644
--- a/batch/manage-pool/manage-pool-windows.sh
+++ b/batch/manage-pool/manage-pool-windows.sh
@@ -1,36 +1,55 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 5/24/2022
-# Authenticate Batch account CLI session.
-az batch account login -g myresourcegroup -n mybatchaccount
+#
+# Create and manage a Windows pool in Azure Batch
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+[[ "$RESOURCE_GROUP" == '' ]] && resourceGroup="msdocs-batch-rg-$randomIdentifier" || resourceGroup="${RESOURCE_GROUP}"
+tag="manage-pool-windows"
+storageAccount="msdocsstorage$randomIdentifier"
+batchAccount="msdocsbatch$randomIdentifier"
+
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create a general-purpose storage account in your resource group.
+echo "Creating $storageAccount"
+az storage account create --resource-group $resourceGroup --name $storageAccount --location "$location" --sku Standard_LRS
-# We want to add an application package reference to the pool, so first
-# we'll list the available applications.
-az batch application summary list
+# Create a Batch account.
+echo "Creating $batchAccount"
+az batch account create --name $batchAccount --storage-account $storageAccount --resource-group $resourceGroup --location "$location"
+
+# Authenticate Batch account CLI session.
+az batch account login --resource-group $resourceGroup --name $batchAccount --shared-key-auth
# Create a new Windows cloud service platform pool with 3 Standard A1 VMs.
-# The pool has an application package reference (taken from the output of the
-# above command) and a start task that will copy the application files to a shared directory.
-az batch pool create \
- --id mypool-windows \
- --os-family 4 \
- --target-dedicated 3 \
- --vm-size small \
- --start-task-command-line "cmd /c xcopy %AZ_BATCH_APP_PACKAGE_MYAPP% %AZ_BATCH_NODE_SHARED_DIR%" \
- --start-task-wait-for-success \
- --application-package-references myapp
-
-# We can add some metadata to the pool.
+# The pool has a start task that runs a basic shell command. Typically a
+# start task copies application files to the pool nodes.
+az batch pool create --id mypool-windows --os-family 4 --target-dedicated 3 --vm-size small --start-task-command-line "cmd /c dir /s" --start-task-wait-for-success
+
+# --application-package-references myapp
+# You can specify an application package reference when the pool is created or you can add it later.
+# https://docs.microsoft.com/azure/batch/batch-application-packages.
+
+# Add some metadata to the pool.
az batch pool set --pool-id mypool-windows --metadata IsWindows=true VMSize=StandardA1
-# Let's change the pool to enable automatic scaling of compute nodes.
+# Change the pool to enable automatic scaling of compute nodes.
# This autoscale formula specifies that the number of nodes should be adjusted according
# to the number of active tasks, up to a maximum of 10 compute nodes.
-az batch pool autoscale enable \
- --pool-id mypool-windows \
- --auto-scale-formula "$averageActiveTaskCount = avg($ActiveTasks.GetSample(TimeInterval_Minute * 15));$TargetDedicated = min(10, $averageActiveTaskCount);"
+az batch pool autoscale enable --pool-id mypool-windows --auto-scale-formula '$averageActiveTaskCount = avg($ActiveTasks.GetSample(TimeInterval_Minute * 15));$TargetDedicated = min(10, $averageActiveTaskCount);'
-# We can monitor the resizing of the pool.
+# Monitor the resizing of the pool.
az batch pool show --pool-id mypool-windows
-# Once we no longer require the pool to automatically scale, we can disable it.
-az batch pool autoscale disable --pool-id mypool-windows
\ No newline at end of file
+# Disable autoscaling when we no longer require the pool to automatically scale.
+az batch pool autoscale disable --pool-id mypool-windows
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/run-job/run-job.sh b/batch/run-job/run-job.sh
index b289e6b4..9cf50f21 100644
--- a/batch/run-job/run-job.sh
+++ b/batch/run-job/run-job.sh
@@ -1,32 +1,42 @@
+# test
#!/bin/bash
+# Passed validation in Cloud Shell on 5/24/2022
-# Authenticate Batch account CLI session.
-az batch account login -g myresource group -n mybatchaccount
+#
+# Run a job and tasks with Azure Batch
-# Create a new job to encapsulate the tasks that we want to add.
-# We'll assume a pool has already been created with the ID 'mypool' - for more information
-# see the sample script for managing pools.
-az batch job create --id myjob --pool-id mypool
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+[[ "$RESOURCE_GROUP" == '' ]] && resourceGroup="msdocs-batch-rg-$randomIdentifier" || resourceGroup="${RESOURCE_GROUP}"
+tag="run-job"
+storageAccount="msdocsstorage$randomIdentifier"
+batchAccount="msdocsbatch$randomIdentifier"
+
+# Create a resource group.
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create a general-purpose storage account in your resource group.
+echo "Creating $storageAccount"
+az storage account create --resource-group $resourceGroup --name $storageAccount --location "$location" --sku Standard_LRS
-# Now we will add tasks to the job.
-# We'll assume an application package has already been uploaded with the ID 'myapp' - for
-# more information see the sample script for adding applications.
-az batch task create \
- --job-id myjob \
- --task-id task1 \
- --application-package-references myapp#1.0
- --command-line "cmd /c %AZ_BATCH_APP_PACKAGE_MYAPP#1.0%\\myapp.exe"
+# Create a Batch account.
+echo "Creating $batchAccount"
+az batch account create --name $batchAccount --storage-account $storageAccount --resource-group $resourceGroup --location "$location"
-# If we want to add many tasks at once - this can be done by specifying the tasks
-# in a JSON file, and passing it into the command. See tasks.json for formatting.
-az batch task create --job-id myjob --json-file tasks.json
+# Authenticate against the account directly for further CLI interaction.
+az batch account login --name $batchAccount --resource-group $resourceGroup --shared-key-auth
-# Now that all the tasks are added - we can update the job so that it will automatically
-# be marked as completed once all the tasks are finished.
-az batch job set --job-id myjob --on-all-tasks-complete terminateJob
+# Create a new Linux pool with a virtual machine configuration.
+az batch pool create --id mypool --vm-size Standard_A1 --target-dedicated 2 --image canonical:ubuntuserver:18_04-lts-gen2 --node-agent-sku-id "batch.node.ubuntu 18.04"
+
+# Create a new job to encapsulate the tasks that are added.
+az batch job create --id myjob --pool-id mypool
-# Monitor the status of the job.
-az batch job show --job-id myjob
+# Add tasks to the job. Here the task is a basic shell command.
+az batch task create --job-id myjob --task-id task1 --command-line "/bin/bash -c 'printenv AZ_BATCH_TASK_WORKING_DIR'"
+#
-# Monitor the status of a task.
-az batch task show --job-id myjob --task-id task1
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/batch/run-job/tasks.json b/batch/run-job/tasks.json
index 65845118..c7af6eb0 100644
--- a/batch/run-job/tasks.json
+++ b/batch/run-job/tasks.json
@@ -1,7 +1,7 @@
[{
"id": "task2",
"displayName": "displayName2",
- "commandLine": "cmd /c dir /s",
+ "commandLine": "/bin/bash -c 'printenv AZ_BATCH_TASK_WORKING_DIR'",
"constraints": {
"maxWallClockTime": "P1D",
"maxTaskRetryCount": 2
@@ -20,7 +20,7 @@
{
"id": "task3",
"displayName": "displayName3",
- "commandLine": "cmd /c dir /s",
+ "commandLine": "/bin/bash -c 'printenv AZ_BATCH_TASK_WORKING_DIR'",
"constraints": {
"maxWallClockTime": "P1D",
"maxTaskRetryCount": 2
@@ -29,7 +29,7 @@
{
"id": "task4",
"displayName": "displayName4",
- "commandLine": "cmd /c dir /s",
+ "commandLine": "/bin/bash -c 'printenv AZ_BATCH_TASK_WORKING_DIR'",
"environmentSettings": [
{
"name": "env1",
diff --git a/container-instances/container-instances-nat-gateway-custom.sh b/container-instances/container-instances-nat-gateway-custom.sh
new file mode 100644
index 00000000..1409ea14
--- /dev/null
+++ b/container-instances/container-instances-nat-gateway-custom.sh
@@ -0,0 +1,98 @@
+#/bin/bash
+# Passed validation in Cloud Shell on 10/29/2024
+# Code blocks for ../container-instances/container-instances-nat-gateway-custom.sh
+#
+# Configure a NAT gateway for static IP address for outbound traffic from a container group
+# set -e # exit if error
+# Variable block
+#
+# Function to display usage
+usage() {
+ echo "Usage: $0 -resourcegroup -location "
+ exit 1
+}
+
+# Parse command-line arguments
+while [[ "$#" -gt 0 ]]; do
+ case $1 in
+ -resourcegroup) resourceGroup="$2"; shift ;;
+ -location) location="$2"; shift ;;
+ *) echo "Unknown parameter passed: $1"; usage ;;
+ esac
+ shift
+done
+
+# Check if required arguments are provided
+if [ -z "$resourceGroup" ] || [ -z "$location" ]; then
+ usage
+fi
+#
+#
+# Check if resource group already exists
+if az group show --name $resourceGroup &> /dev/null; then
+ echo "Resource group $resourceGroup already exists."
+else
+ # Create resource group
+ az group create --name $resourceGroup --location $location
+fi
+#
+#
+az container create \
+ --name appcontainer \
+ --resource-group $resourceGroup \
+ --image mcr.microsoft.com/azuredocs/aci-helloworld \
+ --vnet aci-vnet \
+ --vnet-address-prefix 10.0.0.0/16 \
+ --subnet aci-subnet \
+ --subnet-address-prefix 10.0.0.0/24
+#
+#
+az network public-ip create \
+ --name myPublicIP \
+ --resource-group $resourceGroup \
+ --sku standard \
+ --zone 1 \
+ --allocation static
+#
+#
+ngPublicIp="$(az network public-ip show \
+ --name myPublicIP \
+ --resource-group $resourceGroup \
+ --query ipAddress --output tsv)"
+#
+#
+az network nat gateway create \
+ --resource-group $resourceGroup \
+ --name myNATgateway \
+ --public-ip-addresses myPublicIP \
+ --idle-timeout 10
+#
+#
+az network vnet subnet update \
+ --resource-group $resourceGroup \
+ --vnet-name aci-vnet \
+ --name aci-subnet \
+ --nat-gateway myNATgateway
+#
+#
+az container create \
+ --resource-group $resourceGroup \
+ --name testegress \
+ --image mcr.microsoft.com/azuredocs/aci-helloworld \
+ --command-line "curl -s http://checkip.dyndns.org" \
+ --restart-policy OnFailure \
+ --vnet aci-vnet \
+ --subnet aci-subnet
+#
+#
+az container logs \
+ --resource-group $resourceGroup \
+ --name testegress
+#
+#
+echo $ngPublicIp
+#
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/container-instances/egress-ip-address.sh b/container-instances/egress-ip-address.sh
new file mode 100644
index 00000000..ce7313ef
--- /dev/null
+++ b/container-instances/egress-ip-address.sh
@@ -0,0 +1,148 @@
+#/bin/bash
+# Passed validation in Cloud Shell on 4/30/2022
+# Code blocks for ../container-instances/container-instances-egress-ip-address.md
+#
+# Configure a single public IP address for outbound and inbound traffic to a container group
+# set -e # exit if error
+# Variable block
+#
+resourceGroup=resourceGroup$RANDOM
+#
+#
+az group create --name $resourceGroup --location eastus
+#
+#
+az container create \
+ --name appcontainer \
+ --resource-group $resourceGroup \
+ --image mcr.microsoft.com/azuredocs/aci-helloworld \
+ --vnet aci-vnet \
+ --vnet-address-prefix 10.0.0.0/16 \
+ --subnet aci-subnet \
+ --subnet-address-prefix 10.0.0.0/24
+#
+#
+aciPrivateIp="$(az container show --name appcontainer \
+ --resource-group $resourceGroup \
+ --query ipAddress.ip --output tsv)"
+#
+#
+az network vnet subnet create \
+ --name AzureFirewallSubnet \
+ --resource-group $resourceGroup \
+ --vnet-name aci-vnet \
+ --address-prefix 10.0.1.0/26
+#
+#
+az extension add --name azure-firewall
+#
+#
+az network firewall create \
+ --name myFirewall \
+ --resource-group $resourceGroup \
+ --location eastus
+
+az network public-ip create \
+ --name fw-pip \
+ --resource-group $resourceGroup \
+ --location eastus \
+ --allocation-method static \
+ --sku standard
+
+az network firewall ip-config create \
+ --firewall-name myFirewall \
+ --name FW-config \
+ --public-ip-address fw-pip \
+ --resource-group $resourceGroup \
+ --vnet-name aci-vnet
+#
+#
+az network firewall update \
+ --name myFirewall \
+ --resource-group $resourceGroup
+#
+#
+fwPrivateIp="$(az network firewall ip-config list \
+ --resource-group $resourceGroup \
+ --firewall-name myFirewall \
+ --query "[].privateIpAddress" --output tsv)"
+#
+#
+fwPublicIp="$(az network public-ip show \
+ --name fw-pip \
+ --resource-group $resourceGroup \
+ --query ipAddress --output tsv)"
+#
+#
+az network route-table create \
+ --name Firewall-rt-table \
+ --resource-group $resourceGroup \
+ --location eastus \
+ --disable-bgp-route-propagation true
+#
+#
+az network route-table route create \
+ --resource-group $resourceGroup \
+ --name DG-Route \
+ --route-table-name Firewall-rt-table \
+ --address-prefix 0.0.0.0/0 \
+ --next-hop-type VirtualAppliance \
+ --next-hop-ip-address $fwPrivateIp
+#
+#
+az network vnet subnet update \
+ --name aci-subnet \
+ --resource-group $resourceGroup \
+ --vnet-name aci-vnet \
+ --address-prefixes 10.0.0.0/24 \
+ --route-table Firewall-rt-table
+#
+#
+az network firewall nat-rule create \
+ --firewall-name myFirewall \
+ --collection-name myNATCollection \
+ --action dnat \
+ --name myRule \
+ --protocols TCP \
+ --source-addresses '*' \
+ --destination-addresses $fwPublicIp \
+ --destination-ports 80 \
+ --resource-group $resourceGroup \
+ --translated-address $aciPrivateIp \
+ --translated-port 80 \
+ --priority 200
+#
+#
+az network firewall application-rule create \
+ --collection-name myAppCollection \
+ --firewall-name myFirewall \
+ --name Allow-CheckIP \
+ --protocols Http=80 Https=443 \
+ --resource-group $resourceGroup \
+ --target-fqdns checkip.dyndns.org \
+ --source-addresses 10.0.0.0/24 \
+ --priority 200 \
+ --action Allow
+#
+#
+echo $fwPublicIp
+#
+#
+az container create \
+ --resource-group $resourceGroup \
+ --name testegress \
+ --image mcr.microsoft.com/azuredocs/aci-tutorial-sidecar \
+ --command-line "curl -s http://checkip.dyndns.org" \
+ --restart-policy OnFailure \
+ --vnet aci-vnet \
+ --subnet aci-subnet
+#
+#
+az container logs \
+ --resource-group $resourceGroup \
+ --name testegress
+#
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/container-instances/nat-gateway-arm-template.json b/container-instances/nat-gateway-arm-template.json
new file mode 100644
index 00000000..82de79d0
--- /dev/null
+++ b/container-instances/nat-gateway-arm-template.json
@@ -0,0 +1,183 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "location": {
+ "type": "string",
+ "defaultValue": "eastus",
+ "metadata": {
+ "description": "Location for all resources."
+ }
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "Name of the resource group."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Resources/resourceGroups",
+ "apiVersion": "2021-04-01",
+ "location": "[parameters('location')]",
+ "name": "[parameters('resourceGroupName')]",
+ "properties": {}
+ },
+ {
+ "type": "Microsoft.Network/publicIPAddresses",
+ "apiVersion": "2021-02-01",
+ "name": "myPublicIP",
+ "location": "[parameters('location')]",
+ "sku": {
+ "name": "Standard",
+ "tier": "Regional"
+ },
+ "properties": {
+ "publicIPAllocationMethod": "Static"
+ }
+ },
+ {
+ "type": "Microsoft.Network/natGateways",
+ "apiVersion": "2021-02-01",
+ "name": "myNATgateway",
+ "location": "[parameters('location')]",
+ "sku": {
+ "name": "Standard"
+ },
+ "properties": {
+ "publicIpAddresses": [
+ {
+ "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'myPublicIP')]"
+ }
+ ],
+ "idleTimeoutInMinutes": 10
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Network/publicIPAddresses', 'myPublicIP')]"
+ ]
+ },
+ {
+ "type": "Microsoft.Network/virtualNetworks",
+ "apiVersion": "2021-02-01",
+ "name": "aci-vnet",
+ "location": "[parameters('location')]",
+ "properties": {
+ "addressSpace": {
+ "addressPrefixes": ["10.0.0.0/16"]
+ },
+ "subnets": [
+ {
+ "name": "aci-subnet",
+ "properties": {
+ "addressPrefix": "10.0.0.0/24",
+ "natGateway": {
+ "id": "[resourceId('Microsoft.Network/natGateways', 'myNATgateway')]"
+ },
+ "delegations": [
+ {
+ "name": "aciDelegation",
+ "properties": {
+ "serviceName": "Microsoft.ContainerInstance/containerGroups"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Network/natGateways', 'myNATgateway')]"
+ ]
+ },
+ {
+ "type": "Microsoft.Network/networkProfiles",
+ "apiVersion": "2021-02-01",
+ "name": "aci-network-profile",
+ "location": "[parameters('location')]",
+ "properties": {
+ "containerNetworkInterfaceConfigurations": [
+ {
+ "name": "aci-nic-config",
+ "properties": {
+ "ipConfigurations": [
+ {
+ "name": "aci-ip-config",
+ "properties": {
+ "subnet": {
+ "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'aci-vnet', 'aci-subnet')]"
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Network/virtualNetworks', 'aci-vnet')]"
+ ]
+ },
+ {
+ "type": "Microsoft.ContainerInstance/containerGroups",
+ "apiVersion": "2021-03-01",
+ "name": "appcontainer",
+ "location": "[parameters('location')]",
+ "properties": {
+ "containers": [
+ {
+ "name": "appcontainer",
+ "properties": {
+ "image": "mcr.microsoft.com/azuredocs/aci-helloworld",
+ "resources": {
+ "requests": {
+ "cpu": 1,
+ "memoryInGb": 1.5
+ }
+ }
+ }
+ }
+ ],
+ "osType": "Linux",
+ "restartPolicy": "OnFailure",
+ "networkProfile": {
+ "id": "[resourceId('Microsoft.Network/networkProfiles', 'aci-network-profile')]"
+ }
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Network/networkProfiles', 'aci-network-profile')]"
+ ]
+ },
+ {
+ "type": "Microsoft.ContainerInstance/containerGroups",
+ "apiVersion": "2021-03-01",
+ "name": "testegress",
+ "location": "[parameters('location')]",
+ "properties": {
+ "containers": [
+ {
+ "name": "testegress",
+ "properties": {
+ "image": "mcr.microsoft.com/azuredocs/aci-helloworld",
+ "command": ["curl", "-s", "http://checkip.dyndns.org"],
+ "resources": {
+ "requests": {
+ "cpu": 1,
+ "memoryInGb": 1.5
+ }
+ }
+ }
+ }
+ ],
+ "osType": "Linux",
+ "restartPolicy": "OnFailure",
+ "networkProfile": {
+ "id": "[resourceId('Microsoft.Network/networkProfiles', 'aci-network-profile')]"
+ }
+ },
+ "dependsOn": [
+ "[resourceId('Microsoft.Network/networkProfiles', 'aci-network-profile')]"
+ ]
+ }
+ ]
+ }
diff --git a/container-instances/nat-gateway.sh b/container-instances/nat-gateway.sh
new file mode 100644
index 00000000..93a4c383
--- /dev/null
+++ b/container-instances/nat-gateway.sh
@@ -0,0 +1,73 @@
+#/bin/bash
+# Passed validation in Cloud Shell on 4/30/2022
+# Code blocks for ../container-instances/container-instances-nat-gateway.md
+#
+# Configure a NAT gateway for static IP address for outbound traffic from a container group
+# set -e # exit if error
+# Variable block
+#
+resourceGroup=resourceGroup$RANDOM
+#
+#
+az group create --name $resourceGroup --location eastus
+#
+#
+az container create \
+ --name appcontainer \
+ --resource-group $resourceGroup \
+ --image mcr.microsoft.com/azuredocs/aci-helloworld \
+ --vnet aci-vnet \
+ --vnet-address-prefix 10.0.0.0/16 \
+ --subnet aci-subnet \
+ --subnet-address-prefix 10.0.0.0/24
+#
+#
+az network public-ip create \
+ --name myPublicIP \
+ --resource-group $resourceGroup \
+ --sku standard \
+ --zone 1 \
+ --allocation static
+#
+#
+ngPublicIp="$(az network public-ip show \
+ --name myPublicIP \
+ --resource-group $resourceGroup \
+ --query ipAddress --output tsv)"
+#
+#
+az network nat gateway create \
+ --resource-group $resourceGroup \
+ --name myNATgateway \
+ --public-ip-addresses myPublicIP \
+ --idle-timeout 10
+#
+#
+az network vnet subnet update \
+ --resource-group $resourceGroup \
+ --vnet-name aci-vnet \
+ --name aci-subnet \
+ --nat-gateway myNATgateway
+#
+#
+az container create \
+ --resource-group $resourceGroup \
+ --name testegress \
+ --image mcr.microsoft.com/azuredocs/aci-tutorial-sidecar \
+ --command-line "curl -s http://checkip.dyndns.org" \
+ --restart-policy OnFailure \
+ --vnet aci-vnet \
+ --subnet aci-subnet
+#
+#
+az container logs \
+ --resource-group $resourceGroup \
+ --name testegress
+#
+#
+echo $ngPublicIp
+#
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
\ No newline at end of file
diff --git a/container-registry/create-registry/create-registry-service-principal-assign-role.sh b/container-registry/create-registry/create-registry-service-principal-assign-role.sh
new file mode 100644
index 00000000..82dc240f
--- /dev/null
+++ b/container-registry/create-registry/create-registry-service-principal-assign-role.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/13/2022
+
+#
+# Create resource group and container registry
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-container-registry-rg-$randomIdentifier"
+tag="create-registry-service-principal-assign-role"
+servicePrincipal="msdocs-acr-service-principal-$randomIdentifier" # Must be unique within your AD tenant
+containerRegistry="msdocscontainerregistry$randomIdentifier"
+registrySku="Basic"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Create a container registry
+az acr create --resource-group $resourceGroup --name $containerRegistry --sku $registrySku
+
+# Create service principal with rights scoped to the registry
+#
+#!/bin/bash
+# This script requires Azure CLI version 2.25.0 or later. Check version with `az --version`.
+
+# Modify for your environment.
+# ACR_NAME: The name of your Azure Container Registry
+# SERVICE_PRINCIPAL_NAME: Must be unique within your AD tenant
+ACR_NAME=$containerRegistry
+SERVICE_PRINCIPAL_NAME=$servicePrincipal
+
+# Obtain the full registry ID
+ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query "id" --output tsv)
+# echo $registryId
+
+# Create the service principal with rights scoped to the registry.
+# Default permissions are for docker pull access. Modify the '--role'
+# argument value as desired:
+# acrpull: pull only
+# acrpush: push and pull
+# owner: push, pull, and assign roles
+PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query "password" --output tsv)
+USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)
+
+# Output the service principal's credentials; use these in your services and
+# applications to authenticate to the container registry.
+echo "Service principal ID: $USER_NAME"
+echo "Service principal password: $PASSWORD"
+#
+SERVICE_PRINCIPAL_ID=$USER_NAME
+# Use an existing service principal
+#
+#!/bin/bash
+# Modify for your environment. The ACR_NAME is the name of your Azure Container
+# Registry, and the SERVICE_PRINCIPAL_ID is the service principal's 'appId' or
+# one of its 'servicePrincipalNames' values.
+ACR_NAME=$containerRegistry
+SERVICE_PRINCIPAL_ID=$servicePrincipal
+
+# Populate value required for subsequent command args
+ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)
+
+# Assign the desired role to the service principal. Modify the '--role' argument
+# value as desired:
+# acrpull: pull only
+# acrpush: push and pull
+# owner: push, pull, and assign roles
+az role assignment create --assignee $SERVICE_PRINCIPAL_ID --scope $ACR_REGISTRY_ID --role acrpull
+#
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/cassandra/autoscale.sh b/cosmosdb/cassandra/autoscale.sh
new file mode 100644
index 00000000..9a67e7b6
--- /dev/null
+++ b/cosmosdb/cassandra/autoscale.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Cassandra keyspace and table with autoscale
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="autoscale-casandra-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+keySpace="keyspace1-$randomIdentifier"
+table="table1-$randomIdentifier"
+maxThroughput=1000 #minimum = 1000
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Cassandra API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableCassandra --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False
+
+# Create a Cassandra Keyspace
+echo "Create $keySpace"
+az cosmosdb cassandra keyspace create --account-name $account --resource-group $resourceGroup --name $keySpace
+
+# Define the schema for the table
+schema=$(cat << EOF
+{
+ "columns": [
+ {"name": "columna","type": "uuid"},
+ {"name": "columnb","type": "int"},
+ {"name": "columnc","type": "text"}
+ ],
+ "partitionKeys": [
+ {"name": "columna"}
+ ],
+ "clusterKeys": [
+ { "name": "columnb", "orderBy": "asc" }
+ ]
+}
+EOF
+)
+# Persist schema to json file
+echo "$schema" > "schema-$randomIdentifier.json"
+
+# Create the Cassandra table
+echo "Creating $table"
+az cosmosdb cassandra table create --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --max-throughput $maxThroughput --schema @schema-$randomIdentifier.json
+
+# Clean up temporary schema file
+rm -f "schema-$randomIdentifier.json"
+#
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/cassandra/create.sh b/cosmosdb/cassandra/create.sh
new file mode 100644
index 00000000..b7cbedf7
--- /dev/null
+++ b/cosmosdb/cassandra/create.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Cassandra keyspace and table
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation="South Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="create-casandra-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+keySpace="keyspace1"
+table="table1"
+maxThroughput=4000 #minimum = 4000
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Cassandra API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableCassandra --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --locations regionName="$failoverLocation" failoverPriority=1 isZoneRedundant=False
+
+# Create a Cassandra Keyspace
+echo "Create $keySpace"
+az cosmosdb cassandra keyspace create --account-name $account --resource-group $resourceGroup --name $keySpace
+
+# Define the schema for the table
+printf '
+{
+ "columns": [
+ {"name": "columna","type": "uuid"},
+ {"name": "columnb","type": "int"},
+ {"name": "columnc","type": "text"}
+ ],
+ "partitionKeys": [
+ {"name": "columna"}
+ ],
+ "clusterKeys": [
+ { "name": "columnb", "orderBy": "asc" }
+ ]
+}' > "schema-$randomIdentifier.json"
+
+# Create the Cassandra table
+echo "Creating $table"
+az cosmosdb cassandra table create --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --max-throughput $maxThroughput --schema @schema-$randomIdentifier.json
+
+# Clean up temporary schema file
+rm -f "schema-$randomIdentifier.json"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/cassandra/lock.sh b/cosmosdb/cassandra/lock.sh
new file mode 100644
index 00000000..00aacd13
--- /dev/null
+++ b/cosmosdb/cassandra/lock.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+# Tested after running the "create.sh" script
+
+#
+# Resource lock operations for a Cassandra keyspace and table
+
+# Subscription owner permissions required for this script
+
+# Run this script after running
+# "https://docs.microsoft.com/azure/cosmos-db/scripts/cli/cassandra/create#sample-script"
+
+# Variable block
+# Use values from prerequisite script or from your environment
+# resourceGroup="your resource group name"
+# account="your account name"
+# keySpace="your keyspace name"
+# table="your table name"
+
+lockType="CanNotDelete" # CanNotDelete or ReadOnly
+keySpaceParent="databaseAccounts/$account"
+tableParent="databaseAccounts/$account/cassandraKeyspaces/$keySpace"
+keySpaceLock="$keySpace-Lock"
+tableLock="$table-Lock"
+
+# Create a delete lock on keyspace
+echo "Creating lock $lockType on $keySpaceLock"
+az lock create --name $keySpaceLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/cassandraKeyspaces --lock-type $lockType --parent $keySpaceParent --resource $keySpace
+
+# Create a delete lock on table
+echo "Creating $lockType lock on $table"
+az lock create --name $tableLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/tables --lock-type $lockType --parent $tableParent --resource $table
+
+# List all locks on a Cosmos account
+echo "Listing locks on $account"
+az lock list --resource-group $resourceGroup --resource-name $account --namespace Microsoft.DocumentDB --resource-type databaseAccounts
+
+# Delete lock on keyspace
+echo "Deleting $keySpaceLock on $keySpace"
+lockid=$(az lock show --name $keySpaceLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/cassandraKeyspaces --resource $keySpace --parent $keySpaceParent --output tsv --query id)
+az lock delete --ids $lockid
+
+# Delete lock on table
+echo "Deleting $tableLock on $table"
+lockid=$(az lock show --name $tableLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/tables --resource-name $table --parent $tableParent --output tsv --query id)
+az lock delete --ids $lockid
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/cassandra/serverless.sh b/cosmosdb/cassandra/serverless.sh
new file mode 100644
index 00000000..883b2c43
--- /dev/null
+++ b/cosmosdb/cassandra/serverless.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Cassandra serverless account, keyspace and table
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="serverless-casandra-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+keySpace="keyspace1"
+table="table1"
+maxThroughput=4000 #minimum = 4000
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Cassandra API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableCassandra EnableServerless --locations regionName="$location" failoverPriority=0 isZoneRedundant=False
+
+# Create a Cassandra Keyspace
+echo "Create $keySpace"
+az cosmosdb cassandra keyspace create --account-name $account --resource-group $resourceGroup --name $keySpace
+
+# Define the schema for the table
+printf '
+{
+ "columns": [
+ {"name": "columna","type": "uuid"},
+ {"name": "columnb","type": "int"},
+ {"name": "columnc","type": "text"}
+ ],
+ "partitionKeys": [
+ {"name": "columna"}
+ ],
+ "clusterKeys": [
+ { "name": "columnb", "orderBy": "asc" }
+ ]
+}' > "schema-$randomIdentifier.json"
+
+# Create the Cassandra table
+echo "Creating $table"
+az cosmosdb cassandra table create --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --schema @schema-$randomIdentifier.json
+
+# Clean up temporary schema file
+rm -f "schema-$randomIdentifier.json"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/cassandra/throughput.sh b/cosmosdb/cassandra/throughput.sh
new file mode 100644
index 00000000..4b0fa6c8
--- /dev/null
+++ b/cosmosdb/cassandra/throughput.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Throughput operations for a Cassandra keyspace and table
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="serverless-casandra-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+keySpace="keyspace1"
+table="table1"
+originalThroughput=400
+updateThroughput=500
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location"
+
+# Create a Cosmos account for Cassandra API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableCassandra
+
+# Create Cassandra keyspace
+echo "Creating $keySpace with $originalThroughput"
+az cosmosdb cassandra keyspace create --account-name $account --resource-group $resourceGroup --name $keySpace --throughput $originalThroughput
+
+# Define the schema for the table
+printf '
+{
+ "columns": [
+ {"name": "columnA","type": "uuid"},
+ {"name": "columnB","type": "text"}
+ ],
+ "partitionKeys": [{"name": "columnA"}]
+}' > "schema-$randomIdentifier.json"
+
+# Create the Cassandra table
+echo "Creating $table with $originalThroughput"
+az cosmosdb cassandra table create --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --throughput $originalThroughput --schema @schema-$randomIdentifier.json
+
+# Clean up temporary schema file
+rm -f "schema-$randomIdentifier.json"
+
+# Throughput operations for Cassandra API keyspace
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned keyspace throughput
+az cosmosdb cassandra keyspace throughput show --account-name $account --resource-group $resourceGroup --name $keySpace --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable keyspace throughput
+minimumThroughput=$(az cosmosdb cassandra keyspace throughput show --account-name $account --resource-group $resourceGroup --name $keySpace --query resource.minimumThroughput -o tsv)
+
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update keyspace throughput
+echo "Updating $keyspace throughput to $updateThroughput"
+az cosmosdb cassandra keyspace throughput update --account-name $account --resource-group $resourceGroup --name $keySpace --throughput $updateThroughput
+
+# Migrate the keyspace from standard (manual) throughput to autoscale throughput
+az cosmosdb cassandra keyspace throughput migrate --account-name $account --resource-group $resourceGroup --name $keySpace --throughput-type "autoscale"
+
+# Retrieve current autoscale provisioned max keyspace throughput
+az cosmosdb cassandra keyspace throughput show --account-name $account --resource-group $resourceGroup --name $keySpace --query resource.autoscaleSettings.maxThroughput -o tsv
+
+# Throughput operations for Cassandra API table
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned table throughput
+az cosmosdb cassandra table throughput show --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable table throughput
+minimumThroughput=$(az cosmosdb cassandra table throughput show --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --query resource.minimumThroughput -o tsv)
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update table throughput
+echo "Updating $table throughput to $updateThroughput"
+az cosmosdb cassandra table throughput update --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --throughput $updateThroughput
+
+# Migrate the table from standard (manual) throughput to autoscale throughput
+az cosmosdb cassandra table throughput migrate --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --throughput-type "autoscale"
+
+# Retrieve the current autoscale provisioned max table throughput
+az cosmosdb cassandra table throughput show --account-name $account --resource-group $resourceGroup --keyspace-name $keySpace --name $table --query resource.autoscaleSettings.maxThroughput -o tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/common/convert-to-autoscale.sh b/cosmosdb/common/convert-to-autoscale.sh
new file mode 100644
index 00000000..c7bd0c7b
--- /dev/null
+++ b/cosmosdb/common/convert-to-autoscale.sh
@@ -0,0 +1,197 @@
+#!/bin/bash
+
+# Passed validation in Cloud Shell on 7/25/2024
+
+#
+# Azure Cosmos DB users can migrate from standard provisioned to autoscale
+# throughput and back again. Most users can benefit from autoscale throughput
+# to save on costs and avoid over-provisioning. This script migrates all
+# provisioned throughput to autoscale throughput for all Cosmos DB accounts
+# in the current subscription for NoSQL, MongoDB, Cassandra, Gremlin, and Table
+# database and container level resources in the accounts.
+
+
+# These can remain commented out if running in Azure Cloud Shell
+#az login
+#az account set -s {your subscription id}
+
+throughtput=0
+
+# Get the list of resource groups in the current subscription
+resourceGroups=$(az group list --query "[].name" -o tsv)
+
+# Loop through every resource group in the subscription
+for resourceGroup in $resourceGroups; do
+ echo "Processing resource group: $resourceGroup"
+
+ # Get the list of Cosmos DB accounts in this resource group
+ accounts=$(az cosmosdb list -g $resourceGroup --query "[].name" -o tsv)
+
+ # Loop through every Cosmos DB account in the resource group
+ for account in $accounts; do
+
+ echo "Processing account: $account"
+
+ # Get the list of SQL databases in this account
+ databases=$(az cosmosdb sql database list -g $resourceGroup -a $account --query "[].name" -o tsv)
+
+ # Loop through SQL databases in the account
+ for database in $databases; do
+ throughput=$(az cosmosdb sql database throughput show -g $resourceGroup -a $account -n $database --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$database has throughput, attempting to migrate to autoscale"
+ # Migrate the database to autoscale throughput
+ az cosmosdb sql database throughput migrate -g $resourceGroup -a $account -n $database -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for database: $database in Cosmos DB account $account"
+ fi
+ else
+ echo "$database does not have throughput"
+ fi
+
+ # Loop through SQL containers in the database
+ containers=$(az cosmosdb sql container list -g $resourceGroup -a $account -d $database --query "[].name" -o tsv)
+
+ for container in $containers; do
+ throughput=$(az cosmosdb sql container throughput show -g $resourceGroup -a $account -d $database -n $container --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$container has throughput, attempting to migrate to autoscale"
+ # Migrate the container to autoscale throughput
+ az cosmosdb sql container throughput migrate -g $resourceGroup -a $account -d $database -n $container -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for container: $container in Cosmos DB account $account and database $database"
+ fi
+ else
+ echo "$container does not have throughput"
+ fi
+ done
+ done
+
+ # Get the list of MongoDB databases in this account
+ databases=$(az cosmosdb mongodb database list -g $resourceGroup -a $account --query "[].name" -o tsv)
+
+ # Loop through MongoDB databases in the account
+ for database in $databases; do
+ throughput=$(az cosmosdb mongodb database throughput show -g $resourceGroup -a $account -n $database --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$database has throughput, attempting to migrate to autoscale"
+ # Migrate the database to autoscale throughput
+ az cosmosdb mongodb database throughput migrate -g $resourceGroup -a $account -n $database -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for database: $database in Cosmos DB account $account"
+ fi
+ else
+ echo "$database does not have throughput"
+ fi
+
+ # Loop through MongoDB collections in the database
+ collections=$(az cosmosdb mongodb collection list -g $resourceGroup -a $account -d $database --query "[].name" -o tsv)
+
+ for collection in $collections; do
+ throughput=$(az cosmosdb mongodb collection throughput show -g $resourceGroup -a $account -d $database -n $collection --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$collection has throughput, attempting to migrate to autoscale"
+ # Migrate the collection to autoscale throughput
+ az cosmosdb mongodb collection throughput migrate -g $resourceGroup -a $account -d $database -n $collection -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for collection: $collection in Cosmos DB account $account and database $database"
+ fi
+ else
+ echo "$collection does not have throughput"
+ fi
+ done
+ done
+
+ # Get the list of Cassandra keyspaces in this account
+ keyspaces=$(az cosmosdb cassandra keyspace list -g $resourceGroup -a $account --query "[].name" -o tsv)
+
+ # Loop through Cassandra keyspaces in the account
+ for keyspace in $keyspaces; do
+ throughput=$(az cosmosdb cassandra keyspace throughput show -g $resourceGroup -a $account -n $keyspace --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$keyspace has throughput, attempting to migrate to autoscale"
+ # Migrate the keyspace to autoscale throughput
+ az cosmosdb cassandra keyspace throughput migrate -g $resourceGroup -a $account -n $keyspace -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for keyspace: $keyspace in Cosmos DB account $account"
+ fi
+ else
+ echo "$keyspace does not have throughput"
+ fi
+
+ # Loop through Cassandra tables in the keyspace
+ tables=$(az cosmosdb cassandra table list -g $resourceGroup -a $account -k $keyspace --query "[].name" -o tsv)
+
+ for table in $tables; do
+ throughput=$(az cosmosdb cassandra table throughput show -g $resourceGroup -a $account -k $keyspace -n $table --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$table has throughput, attempting to migrate to autoscale"
+ # Migrate the table to autoscale throughput
+ az cosmosdb cassandra table throughput migrate -g $resourceGroup -a $account -k $keyspace -n $table -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for table: $table in Cosmos DB account $account and keyspace $keyspace"
+ fi
+ else
+ echo "$table does not have throughput"
+ fi
+ done
+ done
+
+ # Get the list of Gremlin databases in this account
+ databases=$(az cosmosdb gremlin database list -g $resourceGroup -a $account --query "[].name" -o tsv)
+
+ # Loop through Gremlin databases in the account
+ for database in $databases; do
+ throughput=$(az cosmosdb gremlin database throughput show -g $resourceGroup -a $account -n $database --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$database has throughput, attempting to migrate to autoscale"
+ # Migrate the database to autoscale throughput
+ az cosmosdb gremlin database throughput migrate -g $resourceGroup -a $account -n $database -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for database: $database in Cosmos DB account $account"
+ fi
+ else
+ echo "$database does not have throughput"
+ fi
+
+ # Loop through Gremlin graphs in the database
+ graphs=$(az cosmosdb gremlin graph list -g $resourceGroup -a $account -d $database --query "[].name" -o tsv)
+
+ for graph in $graphs; do
+ throughput=$(az cosmosdb gremlin graph throughput show -g $resourceGroup -a $account -d $database -n $graph --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$graph has throughput, attempting to migrate to autoscale"
+ # Migrate the graph to autoscale throughput
+ az cosmosdb gremlin graph throughput migrate -g $resourceGroup -a $account -d $database -n $graph -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for graph: $graph in Cosmos DB account $account and database $database"
+ fi
+ else
+ echo "$graph does not have throughput"
+ fi
+ done
+ done
+
+ # Get the list of Table databases in this account
+ tables=$(az cosmosdb table list -g $resourceGroup -a $account --query "[].name" -o tsv)
+
+ # Loop through Table databases in the account
+ for table in $tables; do
+ throughput=$(az cosmosdb table throughput show -g $resourceGroup -a $account -n $table --query resource.throughput -o tsv)
+ if [ $throughput -gt 0 ]; then
+ echo "$table has throughput, attempting to migrate to autoscale"
+ # Migrate the table to autoscale throughput
+ az cosmosdb table throughput migrate -g $resourceGroup -a $account -n $table -t "autoscale"
+ if [ $? -eq 0 ]; then
+ echo "Successfully migrated throughput for table: $table in Cosmos DB account $account"
+ fi
+ else
+ echo "$table does not have throughput"
+ fi
+ done
+ done
+done
+
+echo "All Done! Enjoy your new autoscale throughput Cosmos DB accounts!"
+
+#
diff --git a/cosmosdb/common/find-free-tier-account.sh b/cosmosdb/common/find-free-tier-account.sh
new file mode 100644
index 00000000..224dbfda
--- /dev/null
+++ b/cosmosdb/common/find-free-tier-account.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 7/7/2022
+
+#
+# Azure Cosmos DB offers one free-tier account per subscription
+# This script will find if you have a free-tier account and output
+# the name of the Cosmos DB account and its resource group
+
+
+# These can remain commented out if running in Azure Cloud Shell
+
+#az login
+#az account set -s {your subscription id}
+
+isFound=0
+
+# Iterate through all the resource groups in the subscription
+for rg in $(az group list --query "[].name" --output tsv)
+do
+
+ echo "Checking resource group: $rg"
+
+ # Return the Cosmos DB account in the resource group marked as free tier
+ ft=$(az cosmosdb list -g $rg --query "[?enableFreeTier].name" --output tsv)
+
+ if [ ${#ft} -gt 0 ]; then
+
+ echo "$ft is a free tier account in resource group: $rg"
+ isFound=1
+ break
+
+ fi
+
+done
+
+if [ $isFound -eq 0 ]; then
+ echo "No Free Tier accounts in subscription"
+fi
+#
diff --git a/cosmosdb/common/ipfirewall-bulk-add.sh b/cosmosdb/common/ipfirewall-bulk-add.sh
new file mode 100644
index 00000000..94ddf45a
--- /dev/null
+++ b/cosmosdb/common/ipfirewall-bulk-add.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+# Passed validation in Cloud Shell on 11/07/2024
+
+#
+# This sample adds IP Addresses in bulk to the IP Firewall Rules for an Azure Cosmos DB account.
+# This script was primarily designed to add Azure Portal middleware IP addresses but can add any IP addresses.
+# It also allows access from other Azure managed services without a fixed IP address (ie. Azure Functions) via
+# the "0.0.0.0" IP Address providing access to your Cosmos accounts from these services.
+# You can also enter custom IP Addresses and CIDR ranges. It can also add your current IP Address.
+# By default this script will add all listed IP Addresses to every account in every
+# resource group in the current subscription. You can also specify a single resource group
+# and one or more Cosmos DB accounts within that resource group to process.
+
+# These can remain commented out if running in Azure Cloud Shell
+#az login
+#az account set -s {your subscription id}
+
+# Azure Public Cloud Portal IP Addresses. All is required. Some specific to database APIs
+all=('13.91.105.215' '4.210.172.107' '13.88.56.148' '40.91.218.243')
+mongoOnly=('20.245.81.54' '40.118.23.126' '40.80.152.199' '13.95.130.121')
+cassandraOnly=('40.113.96.14' '104.42.11.145' '137.117.230.240' '168.61.72.237')
+
+# Combine all the portal IP ranges
+addIpAddresses=("${all[@]}" "${mongoOnly[@]}" "${cassandraOnly[@]}")
+
+# Allow connections from Azure services within Azure datacenters
+azureDataCenters=('0.0.0.0')
+addIpAddresses+=("${azureDataCenters[@]}")
+
+# Allow access custom IP Addresses and CIDR ranges
+# Sample private IP Address and CIDR range
+#custom=('10.0.0.1 10.10.0.0/16')
+#addIpAddresses+=("${custom[@]}")
+
+# Allow access from the current IP Address
+currentIpAddress=$(curl -s ifconfig.me)
+addIpAddresses+=("$currentIpAddress")
+
+# print out how many IP addresses are in the list
+echo "Total IP Addresses to process: ${#addIpAddresses[@]}"
+echo "Adding the following IP Addresses from all Cosmos DB accounts: ${addIpAddresses[@]}"
+
+# Convert the combined array into a comma-delimited string
+IFS=',' # Set the Internal Field Separator to a comma
+addIpAddresses="${addIpAddresses[*]}" # Join the array elements into a single string
+
+# Get the list of resource groups in the current subscription
+resourceGroups=$(az group list --query "[].name" -o tsv)
+
+# Or you can specify a single resource group and process all accounts within it
+# You can also limit to a specific number of accounts within a specific resource group
+# resourceGroups=('myResourceGroup')
+
+
+# Loop through every resource group in the subscription
+for resourceGroup in "${resourceGroups[@]}"; do
+ echo "Processing resource group: $resourceGroup"
+
+ # Get the list of Cosmos DB accounts in this resource group
+ mapfile -t accounts <<< "$(az cosmosdb list -g $resourceGroup --query "[].name" -o tsv)"
+
+ # Limit to one or more Cosmos DB accounts within a specific resource group
+ # Must specify a single resource group above to use this
+ # accounts=('cosmos-account-1' 'cosmos-account-2')
+
+ # Loop through every Cosmos DB account in the resource group or array above
+ for account in "${accounts[@]}"; do
+
+ echo "Processing account: $account"
+
+ # Trim potential leading/trailing whitespace from account
+ account=$(echo "$account" | xargs)
+
+ echo "Updating account: $account with new IP Firewall Rules"
+ echo "Please wait..."
+
+ # This command will update the Cosmos DB account with the new IP Addresses
+ # It can take up to 10 minutes to complete
+ az cosmosdb update -g $resourceGroup -n $account --ip-range-filter $addIpAddresses --only-show-errors --output none
+
+ echo "Update complete for account: $account"
+
+ done
+
+ echo "Resource group: $resourceGroup complete"
+
+done
+
+echo "All Done! Enjoy your new IP Firewall Rules!"
+
+#
\ No newline at end of file
diff --git a/cosmosdb/common/ipfirewall-bulk-remove.sh b/cosmosdb/common/ipfirewall-bulk-remove.sh
new file mode 100644
index 00000000..4d95f134
--- /dev/null
+++ b/cosmosdb/common/ipfirewall-bulk-remove.sh
@@ -0,0 +1,142 @@
+#!/bin/bash
+
+# Passed validation in Cloud Shell on 11/07/2024
+
+#
+# This sample removes IP Addresses in bulk from the IP Firewall Rules for an Azure Cosmos DB account.
+# This script was primarily designed to remove Azure Portal middleware IP addresses but can remove any IP addresses.
+# It also removes access from other Azure managed services without a fixed IP address (ie. Azure Functions) via
+# the "0.0.0.0" IP Address restricting access to your Cosmos accounts from these services.
+# You can also enter custom IP Addresses and CIDR ranges to remove as well.
+# By default this script will add all listed IP Addresses to every account in every
+# resource group in the current subscription. You can also specify a single resource group
+# and one or more Cosmos DB accounts within that resource group to process.
+
+# These can remain commented out if running in Azure Cloud Shell
+#az login
+#az account set -s {your subscription id}
+
+# Portal IP Addresses. Various ranges are used for the Azure Portal, some specific to database APIs.
+# The legacy Portal IP addresses are included here if you want to remove them in bulk from your Cosmos DB accounts
+legacy=('139.217.8.252' '52.244.48.71' '104.42.195.92' '40.76.54.131' '52.176.6.30' '52.169.50.45' '52.187.184.26')
+all=('13.91.105.215' '4.210.172.107' '13.88.56.148' '40.91.218.243')
+mongoOnly=('20.245.81.54' '40.118.23.126' '40.80.152.199' '13.95.130.121')
+cassandraOnly=('40.113.96.14' '104.42.11.145' '137.117.230.240' '168.61.72.237')
+
+# Combine all the portal IP ranges. These can be safely combined. If they don't exist, they won't be removed.
+removeIpAddresses=("${legacy[@]}" "${all[@]}" "${mongoOnly[@]}" "${cassandraOnly[@]}")
+
+# Remove access from managed Azure Services from Azure datacenters
+azureDataCenters=('0.0.0.0')
+removeIpAddresses+=("$azureDataCenters")
+
+# Remove custom IP Addresses and CIDR ranges from the IP Addresses
+# Sample private IP Address and CIDR range
+#custom=('10.0.0.1 10.10.0.0/16')
+#removeIpAddresses+=("${custom[@]}")
+
+# print out how many IP addresses are in the list
+echo "Total IP Addresses to process: ${#removeIpAddresses[@]}"
+echo "Removing the following IP Addresses from all Cosmos DB accounts: ${removeIpAddresses[@]}"
+
+updatedIpAddresses=""
+runUpdate=false
+
+# Get the list of resource groups in the current subscription
+resourceGroups=$(az group list --query "[].name" -o tsv)
+
+# Or you can specify a single resource group and process all accounts within it
+# You can also limit to a specific number of accounts within a specific resource group
+# resourceGroups=('myResourceGroup')
+
+
+# Loop through every resource group in the subscription
+for resourceGroup in "${resourceGroups[@]}"; do
+ echo "Processing resource group: $resourceGroup"
+
+ # Get the list of Cosmos DB accounts in this resource group
+ mapfile -t accounts <<< "$(az cosmosdb list -g $resourceGroup --query "[].name" -o tsv)"
+
+ # Limit to one or more Cosmos DB accounts within a specific resource group
+ # Must specify a single resource group above to use this
+ # accounts=('cosmos-account-1' 'cosmos-account-2')
+
+
+ # Loop through every Cosmos DB account in the resource group or array of specific accounts
+ for account in "${accounts[@]}"; do
+
+ echo "Processing account: $account"
+
+ # Trim any leading/trailing whitespace from account
+ account=$(echo "$account" | xargs)
+
+ # Get the list of current IP Addresses for this Cosmos DB account
+ # Assuming these are newline-separated, convert them into an array
+ mapfile -t currentIpAddresses <<< "$(az cosmosdb show -g $resourceGroup -n $account --query "ipRules[].ipAddressOrRange" -o tsv)"
+
+ echo "Account: $account, has ${#currentIpAddresses[@]} current IP Addresses"
+
+ for currentIpAddress in "${currentIpAddresses[@]}"; do
+ echo "Processing current IP Address: $currentIpAddress"
+ matchFound=false
+
+ # Trim potential leading/trailing whitespace from ipRule
+ currentIpAddress=$(echo "$currentIpAddress" | xargs)
+
+ # Check if the current IP Address is in the Remove IP Addresses array
+ for removeIpAddress in "${removeIpAddresses[@]}"; do
+
+ # Trim potential leading/trailing whitespace from ipRule
+ removeIpAddress=$(echo "$removeIpAddress" | xargs)
+
+ if [[ $currentIpAddress == $removeIpAddress ]]; then
+
+ echo "Match found for IP Address: $currentIpAddress"
+ matchFound=true
+ # If any IPs match, run an update. If none do, don't update the account
+ runUpdate=true
+ break
+ fi
+
+ done
+
+ if [[ $matchFound == false ]]; then
+ # Current IP Address is not in the list of IP Addresses to remove.
+ # Preserve it in the updatedIpAddresses
+ updatedIpAddresses+="$currentIpAddress,"
+ fi
+ done
+
+ # Update the Cosmos DB account with the new list of IP Firewall Rules
+ if [[ $runUpdate == true ]]; then
+
+ # Trim the trailing comma and any carriage return characters from the CSV string
+ updatedIpAddresses=$(echo "$updatedIpAddresses" | sed 's/,$//' | tr -d '\r')
+
+ echo "Updating account: $account with existing IP Addresses not specified to be removed: $updatedIpAddresses"
+ echo "Please wait..."
+
+ # This command will update the Cosmos DB account with the new IP Addresses
+ # It can take up to 10 minutes to complete
+ az cosmosdb update -g $resourceGroup -n $account --ip-range-filter "$updatedIpAddresses" --only-show-errors --output none
+ echo "Update complete for account: $account with new IP Addresses: $updatedIpAddresses"
+
+ else
+
+ echo "No update needed for account: $account"
+
+ fi
+
+ # Reset the variables for the next account
+ updatedIpAddresses=""
+ runUpdate=false
+
+ done
+
+ echo "Resource group: $resourceGroup complete"
+
+done
+
+echo "All Done! Enjoy your new IP Firewall Rules!"
+
+#
diff --git a/cosmosdb/common/ipfirewall.sh b/cosmosdb/common/ipfirewall.sh
new file mode 100644
index 00000000..2bacb640
--- /dev/null
+++ b/cosmosdb/common/ipfirewall.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create an Azure Cosmos Account with IP Firewall
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="ipfirewall-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos DB account with default values and IP Firewall enabled
+# Use appropriate values for --kind or --capabilities for other APIs
+# Replace the values for the ip-range-filter with appropriate values for your environment
+echo "Creating $account for CosmosDB"
+az cosmosdb create --name $account --resource-group $resourceGroup --ip-range-filter '0.0.0.0','255.255.255.255'
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/common/keys.sh b/cosmosdb/common/keys.sh
new file mode 100644
index 00000000..3439216b
--- /dev/null
+++ b/cosmosdb/common/keys.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Account key operations for an Azure Cosmos account
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="keys-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos DB account with default values
+# Use appropriate values for --kind or --capabilities for other APIs
+echo "Creating $account for CosmosDB"
+az cosmosdb create --name $account --resource-group $resourceGroup
+
+# List all account keys
+az cosmosdb keys list --name $account --resource-group $resourceGroup
+
+# List read-only keys
+az cosmosdb keys list --name $account --resource-group $resourceGroup --type read-only-keys
+
+# List connection strings
+az cosmosdb keys list --name $account --resource-group $resourceGroup --type connection-strings
+
+# Regenerate secondary account keys
+# key-kind values: primary, primaryReadonly, secondary, secondaryReadonly
+az cosmosdb keys regenerate --name $account --resource-group $resourceGroup --key-kind secondary
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/common/rbac-bulk-apply.sh b/cosmosdb/common/rbac-bulk-apply.sh
new file mode 100644
index 00000000..0221e77e
--- /dev/null
+++ b/cosmosdb/common/rbac-bulk-apply.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+#
+# This sample applies Data Contributor role in bulk to Azure Cosmos DB accounts
+# This script will apply this role for the current logged in user or
+# a specified managed identity to every Cosmos account within a resource group.
+# You can specify a single resource group with selected or all Cosmos DB accounts.
+# Or you can process all accounts in every resource group in the subscription
+
+# Login to Azure if not already authenticated, select subscription
+# This can be commented out if running in Azure Cloud Shell
+az login
+
+# Get principal Id for a user-assigned managed identity
+miPrincipalId=$(az identity show -g myResourceGroup -n myManagedIdentity --query principalId -o tsv)
+
+# Capture the current user's principal Id and subscription Id
+principalId=$(az ad signed-in-user show --query id -o tsv)
+subscriptionId=$(az account show --query id -o tsv)
+
+# Specify one or more resource groups and process all accounts within it
+# Or specify just one resource group and only specific accounts within that one resource group
+# Comment out to process all accounts in every resource group in the subscription
+resourceGroups=('myResourceGroup1' 'myResourceGroup2')
+
+
+# Or you can process all accounts in every resource group in the subscription
+if [ ${#resourceGroups[@]} -eq 0 ]; then
+ resourceGroups=$(az group list --query "[].name" -o tsv)
+fi
+
+
+# Loop through every resource group
+for resourceGroup in "${resourceGroups[@]}"; do
+ echo "Processing resource group: $resourceGroup"
+
+ # Limit to one or more Cosmos DB accounts within a specific resource group
+ # Or comment out to process all accounts in the resource group
+ #accounts=('cosmos-account-1' 'cosmos-account-2')
+
+
+ # Or you can process all accounts in the resource group
+ if [ ${#accounts[@]} -eq 0 ]; then
+ processAllAccounts=true
+ # Get the list of Cosmos DB accounts in this resource group
+ mapfile -t accounts <<< "$(az cosmosdb list -g $resourceGroup --query "[].name" -o tsv)"
+ fi
+
+ # Loop through every Cosmos DB account in the resource group or array above
+ for account in "${accounts[@]}"; do
+
+ echo "Processing account: $account"
+
+ # Trim potential leading/trailing whitespace from account
+ account=$(echo "$account" | xargs)
+
+ echo "Updating account: $account with RBAC Policy"
+ echo "Please wait..."
+
+ # Apply the RBAC policy to the Cosmos DB account
+ az cosmosdb sql role assignment create \
+ -n "Cosmos DB Built-in Data Contributor" \
+ -g $resourceGroup \
+ -a $account \
+ -p $principalId \
+ -s /"/" \
+ --output none
+
+ # Apply the RBAC policy to the miPrincipalId if it is not null
+ if [ ! -z "$miPrincipalId" ]; then
+ az cosmosdb sql role assignment create \
+ -n "Cosmos DB Built-in Data Contributor" \
+ -g $resourceGroup \
+ -a $account \
+ -p $miPrincipalId \
+ -s /"/" \
+ --output none
+ fi
+
+ echo "Update complete for account: $account"
+
+ done
+
+ # Reset the accounts array if processing all accounts in one or more resource groups
+ if [ $processAllAccounts ]; then
+ accounts=()
+ fi
+
+ echo "Resource group: $resourceGroup complete"
+
+done
+
+echo "All Done! Enjoy your new RBAC enabled Cosmos accounts!"
+
+#
\ No newline at end of file
diff --git a/cosmosdb/common/regions.sh b/cosmosdb/common/regions.sh
new file mode 100644
index 00000000..d727f18e
--- /dev/null
+++ b/cosmosdb/common/regions.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Region replica operations for an Azure Cosmos account
+
+# Note: Azure Comos accounts cannot include updates to regions with changes to other properties in the same operation
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation1="South Central US"
+failoverLocation2="North Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="regions-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos DB account with default values
+# Use appropriate values for --kind or --capabilities for other APIs
+echo "Creating $account for CosmosDB"
+az cosmosdb create --name $account --resource-group $resourceGroup
+
+# Specify region failover locations and priorities
+echo "Adding $failoverLocation1 and $failoverLocation2"
+az cosmosdb update --name $account --resource-group $resourceGroup --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --locations regionName="$failoverLocation1" failoverPriority=1 isZoneRedundant=False --locations regionName="$failoverLocation2" failoverPriority=2 isZoneRedundant=False
+
+# Make failoverLocation2 the next region to fail over to instead of failoverLocation1
+echo "Switching failover priority"
+az cosmosdb failover-priority-change --name $account --resource-group $resourceGroup --failover-policies "$location=0" "$failoverLocation1=2" "$failoverLocation2=1"
+
+# Initiate a manual failover and promote failoverLocation1 as primary write region
+echo "Failing over to $failoverLocation1"
+az cosmosdb failover-priority-change --name $account --resource-group $resourceGroup --failover-policies "$location=2" "$failoverLocation1=0" "$failoverLocation2=1"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/common/service-endpoints-ignore-missing-vnet.sh b/cosmosdb/common/service-endpoints-ignore-missing-vnet.sh
new file mode 100644
index 00000000..f7a985e7
--- /dev/null
+++ b/cosmosdb/common/service-endpoints-ignore-missing-vnet.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Service endpoint operations for an Azure Cosmos account
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="service-endpoints-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+vNet='msdocs-vnet-cosmosdb'
+frontEnd='msdocs-front-end-cosmosdb'
+backEnd='msdocs-back-end-cosmosdb'
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network with a front-end subnet
+echo "Creating $vnet"
+az network vnet create --name $vNet --resource-group $resourceGroup --address-prefix 10.0.0.0/16 --subnet-name $frontEnd --subnet-prefix 10.0.1.0/24
+
+# Create a back-end subnet but without specifying --service-endpoints Microsoft.AzureCosmosDB
+echo "Creating $backend in $vNet"
+az network vnet subnet create --name $backEnd --resource-group $resourceGroup --address-prefix 10.0.2.0/24 --vnet-name $vNet
+
+# Retrieve the value of the service endpoint
+svcEndpoint=$(az network vnet subnet show --resource-group $resourceGroup --name $backEnd --vnet-name $vNet --query 'id' -o tsv)
+
+# Create a Cosmos DB account with default values
+# Use appropriate values for --kind or --capabilities for other APIs
+echo "Creating $account for CosmosDB"
+az cosmosdb create --name $account --resource-group $resourceGroup --enable-virtual-network
+
+# Add the virtual network rule but ignore the missing service endpoint on the subnet
+az cosmosdb network-rule add --name $account --resource-group $resourceGroup --virtual-network $vNet --subnet $svcEndpoint --ignore-missing-vnet-service-endpoint true
+
+# Update vNet update
+az network vnet subnet update --name $backEnd --resource-group $resourceGroup --vnet-name $vNet --service-endpoints Microsoft.AzureCosmosDB
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/common/service-endpoints.sh b/cosmosdb/common/service-endpoints.sh
new file mode 100644
index 00000000..2475e354
--- /dev/null
+++ b/cosmosdb/common/service-endpoints.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Service endpoint operations for an Azure Cosmos account
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="service-endpoints-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+vNet='msdocs-vnet-cosmosdb'
+frontEnd='msdocs-front-end-cosmosdb'
+backEnd='msdocs-back-end-cosmosdb'
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network with a front-end subnet
+echo "Creating $vnet"
+az network vnet create --name $vNet --resource-group $resourceGroup --address-prefix 10.0.0.0/16 --subnet-name $frontEnd --subnet-prefix 10.0.1.0/24
+
+# Create a back-end subnet
+echo "Creating $backend in $vNet"
+az network vnet subnet create --name $backEnd --resource-group $resourceGroup --address-prefix 10.0.2.0/24 --vnet-name $vNet --service-endpoints Microsoft.AzureCosmosDB
+
+# Retrieve the value of the service endpoint
+svcEndpoint=$(az network vnet subnet show --resource-group $resourceGroup --name $backEnd --vnet-name $vNet --query 'id' -o tsv)
+
+# Create a Cosmos DB account with default values and service endpoints
+# Use appropriate values for --kind or --capabilities for other APIs
+echo "Creating $account for CosmosDB"
+az cosmosdb create --name $account --resource-group $resourceGroup --enable-virtual-network true --virtual-network-rules $svcEndpoint
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/create-cosmosdb-account-database/create-cosmosdb-account-database.sh b/cosmosdb/create-cosmosdb-account-database/create-cosmosdb-account-database.sh
deleted file mode 100644
index 60911f2e..00000000
--- a/cosmosdb/create-cosmosdb-account-database/create-cosmosdb-account-database.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-databaseName='docdb-test-database'
-collectionName='docdb-test-collection'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a database
-az cosmosdb database create \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Create a collection
-az cosmosdb collection create \
- --collection-name $collectionName \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
diff --git a/cosmosdb/create-cosmosdb-graph-account/create-cosmosdb-graph-account.sh b/cosmosdb/create-cosmosdb-graph-account/create-cosmosdb-graph-account.sh
deleted file mode 100644
index d1914e73..00000000
--- a/cosmosdb/create-cosmosdb-graph-account/create-cosmosdb-graph-account.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName=docdbgetstarted
-location="South Central US"
-name=docdb-test
-databaseName=docdb-graph-database
-collectionName=docdb-graph-collection
-throughput=400
-zipcode=55104
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a Graph API DocumentDB account
-az documentdb create \
- --name $name \
- --resource-group $resourceGroupName \
- --kind Graph \
- --locations $location \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a Graph API DocumentDB database
-az documentdb add-database \
- --resource-group $resourceGroupName \
- --name $name \
- --dbname $databaseName \
-
-# Create a Graph API DocumentDB collection
-az documentdb add-collection \
- --resource-group $resourceGroupName \
- --name $name \
- --dbname $databaseName \
- --collname $collectionName \
- --throughput $throughput \
- --partitionkey $zipcode
diff --git a/cosmosdb/create-cosmosdb-mongodb-account/create-cosmosdb-mongodb-account.sh b/cosmosdb/create-cosmosdb-mongodb-account/create-cosmosdb-mongodb-account.sh
deleted file mode 100644
index 45948d3a..00000000
--- a/cosmosdb/create-cosmosdb-mongodb-account/create-cosmosdb-mongodb-account.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-databaseName='docdb-mongodb-database'
-collectionName='docdb-mongodb-collection'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a MongoDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind MongoDB \
- --locations "South Central US"=0 "North Central US"=1 \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a database
-az cosmosdb database create \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Create a collection
-az cosmosdb collection create \
- --collection-name $collectionName \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
\ No newline at end of file
diff --git a/cosmosdb/create-cosmosdb-table-account/create-cosmosdb-table-account.sh b/cosmosdb/create-cosmosdb-table-account/create-cosmosdb-table-account.sh
deleted file mode 100644
index 5894fd04..00000000
--- a/cosmosdb/create-cosmosdb-table-account/create-cosmosdb-table-account.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName=docdbgetstarted
-location="South Central US"
-name=docdb-test
-databaseName=docdb-mongodb-database
-collectionName=docdb-mongodb-collection
-throughput=400
-zipcode=55104
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a Tables API DocumentDB account
-az documentdb create \
- --name $name \
- --resource-group $resourceGroupName \
- --kind Tables \
- --locations $location \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a Tables API DocumentDB database
-az documentdb add-database \
- --resource-group $resourceGroupName \
- --name $name \
- --dbname $databaseName
-
-# Create a Tables API DocumentDB collection
-az documentdb add-collection \
- --resource-group $resourceGroupName \
- --name $name \
- --dbname $databaseName \
- --collname $collectionName \
- --throughput $throughput \
- --partitionkey $zipcode
\ No newline at end of file
diff --git a/cosmosdb/gremlin/autoscale.sh b/cosmosdb/gremlin/autoscale.sh
new file mode 100644
index 00000000..181561ac
--- /dev/null
+++ b/cosmosdb/gremlin/autoscale.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Gremlin API database and graph with autoscale
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="autoscale-gremlin-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-gremlin-cosmos"
+graph="msdocs-graph1-gremlin-cosmos"
+partitionKey="/partitionKey"
+maxThroughput=1000 #minimum = 1000
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Gremlin API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableGremlin --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False
+
+# Create a Gremlin database
+echo "Creating $database with $account"
+az cosmosdb gremlin database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Create a Gremlin graph with autoscale
+echo "Creating $graph"
+az cosmosdb gremlin graph create --account-name $account --resource-group $resourceGroup --database-name $database --name $graph --partition-key-path $partitionKey --max-throughput $maxThroughput
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/gremlin/create.sh b/cosmosdb/gremlin/create.sh
new file mode 100644
index 00000000..1f8d8e2a
--- /dev/null
+++ b/cosmosdb/gremlin/create.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Gremlin database and graph
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation="South Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="create-gremlin-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-gremlin-cosmos"
+graph="msdocs-graph1-gremlin-cosmos"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Gremlin API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableGremlin --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --locations regionName="$failoverLocation" failoverPriority=1 isZoneRedundant=False
+
+# Create a Gremlin database
+echo "Creating $database with $account"
+az cosmosdb gremlin database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Define the index policy for the graph, include spatial and composite indexes
+printf '
+{
+ "indexingMode": "consistent",
+ "includedPaths": [
+ {"path": "/*"}
+ ],
+ "excludedPaths": [
+ { "path": "/headquarters/employees/?"}
+ ],
+ "spatialIndexes": [
+ {"path": "/*", "types": ["Point"]}
+ ],
+ "compositeIndexes":[
+ [
+ { "path":"/name", "order":"ascending" },
+ { "path":"/age", "order":"descending" }
+ ]
+ ]
+}' > "idxpolicy-$randomIdentifier.json"
+
+# Create a Gremlin graph
+echo "Creating $graph"
+az cosmosdb gremlin graph create --account-name $account --resource-group $resourceGroup --database-name $database --name $graph -p "/zipcode" --throughput 400 --idx @idxpolicy-$randomIdentifier.json
+
+# Clean up temporary index policy file
+rm -f "idxpolicy-$randomIdentifier.json"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/gremlin/lock.sh b/cosmosdb/gremlin/lock.sh
new file mode 100644
index 00000000..6990a4c7
--- /dev/null
+++ b/cosmosdb/gremlin/lock.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+# Tested after running the "create.sh" script
+
+#
+# Resource lock operations for a Gremlin database and graph
+
+# Subscription owner permissions required for this script
+
+# Run this script after running
+# "https://docs.microsoft.com/azure/cosmos-db/scripts/cli/gremln/create#sample-script"
+
+# Variable block
+# Use values from prerequisite script or from your environment
+# resourceGroup="your resource group name"
+# account="your account name"
+# database="your database name"
+# container="your container name"
+# graph="your graph name"
+
+lockType="CanNotDelete" # CanNotDelete or ReadOnly
+databaseParent="databaseAccounts/$account"
+graphParent="databaseAccounts/$account/gremlinDatabases/$database"
+databaseLock="$database-Lock"
+graphLock="$graph-Lock"
+
+# Create a delete lock on database
+echo "Creating $lockType lock on $database"
+az lock create --name $databaseLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/gremlinDatabases --lock-type $lockType --parent $databaseParent --resource $database
+
+# Create a delete lock on graph
+echo "Creating $lockType lock on $graph"
+az lock create --name $graphLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/graphs --lock-type $lockType --parent $graphParent --resource $graph
+
+# List all locks on a Cosmos account
+echo "Listing locks on $account"
+az lock list --resource-group $resourceGroup --resource-name $account --namespace Microsoft.DocumentDB --resource-type databaseAccounts
+
+# Delete lock on database
+echo "Deleting $databaseLock on $database"
+lockid=$(az lock show --name $databaseLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/gremlinDatabases --resource $database --parent $databaseParent --output tsv --query id)
+az lock delete --ids $lockid
+
+# Delete lock on graph
+echo "Deleting $graphLock on $graph"
+lockid=$(az lock show --name $graphLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/graphs --resource-name $graph --parent $graphParent --output tsv --query id)
+az lock delete --ids $lockid
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/gremlin/serverless.sh b/cosmosdb/gremlin/serverless.sh
new file mode 100644
index 00000000..65f46bf0
--- /dev/null
+++ b/cosmosdb/gremlin/serverless.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Gremlin serverless account, database and graph
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation="Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="serverless-gremlin-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-gremlin-cosmos"
+graph="msdocs-graph1-gremlin-cosmos"
+partitionKey="/partitionKey"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Gremlin API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableGremlin EnableServerless --default-consistency-level Eventual --locations regionName="$failoverLocation" failoverPriority=0 isZoneRedundant=False
+
+# Create a Gremlin database
+echo "Creating $database with $account"
+az cosmosdb gremlin database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Create a Gremlin graph
+echo "Creating $graph"
+az cosmosdb gremlin graph create --account-name $account --resource-group $resourceGroup --database-name $database --name $graph --partition-key-path $partitionKey
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/gremlin/throughput.sh b/cosmosdb/gremlin/throughput.sh
new file mode 100644
index 00000000..9f474fca
--- /dev/null
+++ b/cosmosdb/gremlin/throughput.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Throughput operations for a Gremlin API database and graph
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="throughput-gremlin-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-gremlin-cosmos"
+graph="msdocs-graph1-gremlin-cosmos"
+partitionKey="/partitionKey"
+originalThroughput=400
+updateThroughput=500
+
+# Create a resource group
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Gremlin API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableGremlin
+
+# Create Gremlin database with throughput
+echo "Creating $database with $originalThroughput"
+az cosmosdb gremlin database create --account-name $account --resource-group $resourceGroup --name $database --throughput $originalThroughput
+
+# Create Gremlin graph with throughput
+echo "Creating $graph with $originalThroughput"
+az cosmosdb gremlin graph create --account-name $account --resource-group $resourceGroup --database-name $database --name $graph --partition-key-path $partitionKey --throughput $originalThroughput
+
+# Throughput operations for Gremlin API database
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned database throughput
+az cosmosdb gremlin database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable database throughput
+minimumThroughput=$(az cosmosdb gremlin database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.minimumThroughput -o tsv)
+
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update database throughput
+echo "Updating $database throughput to $updateThroughput"
+az cosmosdb gremlin database throughput update --account-name $account --resource-group $resourceGroup --name $database --throughput $updateThroughput
+
+# Migrate the database from standard (manual) throughput to autoscale throughput
+az cosmosdb gremlin database throughput migrate --account-name $account --resource-group $resourceGroup --name $database --throughput-type "autoscale"
+
+# Retrieve current autoscale provisioned max database throughput
+az cosmosdb gremlin database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.autoscaleSettings.maxThroughput -o tsv
+
+# Throughput operations for Gremlin API graph
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned graph throughput
+az cosmosdb gremlin graph throughput show --resource-group $resourceGroup --account-name $account --database $database --name $graph --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable graph throughput
+minimumThroughput=$(az cosmosdb gremlin graph throughput show --resource-group $resourceGroup --account-name $account --database $database --name $graph --query resource.minimumThroughput -o tsv)
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update graph throughput
+echo "Updating $graph throughput to $updateThroughput"
+az cosmosdb gremlin graph throughput update --resource-group $resourceGroup --account-name $account --database $database --name $graph --throughput $updateThroughput
+
+# Migrate the graph from standard (manual) throughput to autoscale throughput
+az cosmosdb gremlin graph throughput migrate --account-name $account --resource-group $resourceGroup --database $database --name $graph --throughput-type "autoscale"
+
+# Retrieve the current autoscale provisioned max graph throughput
+az cosmosdb gremlin graph throughput show --resource-group $resourceGroup --account-name $account --database $database --name $graph --query resource.autoscaleSettings.maxThroughput -o tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/high-availability-cosmosdb-configure-failover/high-availability-cosmosdb-configure-failover.sh b/cosmosdb/high-availability-cosmosdb-configure-failover/high-availability-cosmosdb-configure-failover.sh
deleted file mode 100644
index eba27e08..00000000
--- a/cosmosdb/high-availability-cosmosdb-configure-failover/high-availability-cosmosdb-configure-failover.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-databaseName='docdb-test-database'
-collectionName='docdb-test-collection'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Update failover configuration
-az cosmosdb update \
- --name $name \
- --resource-group $resourceGroupName \
- --locations "South Central US"=0 "North Central US"=1 "East US"=2 "West US"=3
\ No newline at end of file
diff --git a/cosmosdb/mongodb/autoscale.sh b/cosmosdb/mongodb/autoscale.sh
new file mode 100644
index 00000000..cfafc8ac
--- /dev/null
+++ b/cosmosdb/mongodb/autoscale.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a MongoDB API database with autoscale and 2 collections that share throughput
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="autoscale-mongodb-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-mongo-cosmos"
+serverVersion="4.0" #3.2, 3.6, 4.0
+maxThroughput=1000 #minimum = 1000
+collection1="collection1"
+collection2="collection2"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for MongoDB API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --kind MongoDB --server-version $serverVersion --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False
+
+# Create a MongoDB API database with shared autoscale throughput
+echo "Creating $database with $maxThroughput"
+az cosmosdb mongodb database create --account-name $account --resource-group $resourceGroup --name $database --max-throughput $maxThroughput
+
+# Create two MongoDB API collections to share throughput
+echo "Creating $collection1"
+az cosmosdb mongodb collection create --account-name $account --resource-group $resourceGroup --database-name $database --name $collection1 --shard "ShardKey1"
+
+echo "Creating $collection2"
+az cosmosdb mongodb collection create --account-name $account --resource-group $resourceGroup --database-name $database --name $collection2 --shard "ShardKey2"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/mongodb/create.sh b/cosmosdb/mongodb/create.sh
new file mode 100644
index 00000000..c4d88bd5
--- /dev/null
+++ b/cosmosdb/mongodb/create.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a MongoDB API database and collection
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation="South Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="create-mongodb-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-mongo-cosmos"
+serverVersion="4.0" #3.2, 3.6, 4.0
+collection="collection1"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for MongoDB API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --kind MongoDB --server-version $serverVersion --default-consistency-level Eventual --enable-automatic-failover true --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --locations regionName="$failoverLocation" failoverPriority=1 isZoneRedundant=False
+
+# Create a MongoDB API database
+echo "Creating $database"
+az cosmosdb mongodb database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Define the index policy for the collection, with _id, wildcard, compound, unique and TTL
+printf '
+[
+ {
+ "key": {"keys": ["_id"]}
+ },
+ {
+ "key": {"keys": ["$**"]}
+ },
+ {
+ "key": {"keys": ["user_id", "user_address"]},
+ "options": {"unique": "true"}
+ },
+ {
+ "key": {"keys": ["_ts"]},
+ "options": {"expireAfterSeconds": 2629746}
+ }
+]' > idxpolicy-$randomIdentifier.json
+
+# Create a MongoDB API collection
+echo "Creating $collection1"
+az cosmosdb mongodb collection create --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --shard "user_id" --throughput 400 --idx @idxpolicy-$randomIdentifier.json
+
+# Clean up temporary index policy file
+rm -f "idxpolicy-$randomIdentifier.json"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/mongodb/lock.sh b/cosmosdb/mongodb/lock.sh
new file mode 100644
index 00000000..43db8f63
--- /dev/null
+++ b/cosmosdb/mongodb/lock.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+# Tested after running the "create.sh" script
+
+#
+# Resource lock operations for a MongoDB API database and collection
+
+# Subscription owner permissions required for this script
+
+# Run this script after running
+# "https://docs.microsoft.com/azure/cosmos-db/scripts/cli/mongodb/create#sample-script"
+
+# Variable block
+# Use values from prerequisite script or from your environment
+# resourceGroup="your resource group name"
+# account="your account name"
+# database="your database name"
+# collection="your collection name"
+
+lockType='CanNotDelete' # CanNotDelete or ReadOnly
+databaseParent="databaseAccounts/$account"
+collectionParent="databaseAccounts/$account/mongodbDatabases/$database"
+databaseLock="$database-Lock"
+collectionLock="$collection-Lock"
+
+# Create a delete lock on database
+echo "Creating $lockType lock on $database"
+az lock create --name $databaseLock \
+--resource-group $resourceGroup \
+--resource-type Microsoft.DocumentDB/mongodbDatabases --lock-type $lockType --parent $databaseParent --resource $database
+
+# Create a delete lock on collection
+echo "Creating $lockType lock on $collection"
+az lock create --name $collectionLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/collections --lock-type $lockType --parent $collectionParent --resource $collection
+
+# List all locks on a Cosmos account
+echo "Listing locks on $account"
+az lock list --resource-group $resourceGroup --resource-name $account --namespace Microsoft.DocumentDB --resource-type databaseAccounts
+
+# Delete lock on database
+echo "Deleting $databaseLock on $database"
+lockid=$(az lock show --name $databaseLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/mongodbDatabases --resource $database --parent $databaseParent --output tsv --query id)
+az lock delete --ids $lockid
+
+# Delete lock on collection
+echo "Deleting $collectionLock on $collection"
+lockid=$(az lock show --name $collectionLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/collections --resource-name $collection --parent $collectionParent --output tsv --query id)
+az lock delete --ids $lockid
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/mongodb/serverless.sh b/cosmosdb/mongodb/serverless.sh
new file mode 100644
index 00000000..36e9977e
--- /dev/null
+++ b/cosmosdb/mongodb/serverless.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a MongoDB API serverless account database and collection
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="serverless-mongodb-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+serverVersion="4.0" #3.2, 3.6, 4.0
+database="msdocs-db-mongo-cosmos"
+collection="collection1"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for MongoDB API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --kind MongoDB --server-version $serverVersion --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --capabilities EnableServerless
+
+# Create a MongoDB API database
+echo "Creating $database"
+az cosmosdb mongodb database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Define the index policy for the collection, with _id, wildcard, compound, unique and TTL
+printf '
+[
+ {
+ "key": {"keys": ["_id"]}
+ },
+ {
+ "key": {"keys": ["$**"]}
+ }
+]' > idxpolicy-$randomIdentifier.json
+
+# Create a MongoDB API collection
+echo "Creating $collection1"
+az cosmosdb mongodb collection create --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --shard "shardKey1" --idx @idxpolicy-$randomIdentifier.json
+
+# Clean up temporary index policy file
+rm -f "idxpolicy-$randomIdentifier.json"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/mongodb/throughput.sh b/cosmosdb/mongodb/throughput.sh
new file mode 100644
index 00000000..2aa2f4ce
--- /dev/null
+++ b/cosmosdb/mongodb/throughput.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Throughput operations for a MongoDB API database and collection
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="throughput-mongodb-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-mongo-cosmos"
+collection="collection1"
+originalThroughput=400
+updateThroughput=500
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for MongoDB API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --kind MongoDB
+
+# Create a MongoDB API database
+echo "Creating $database with $originalThroughput"
+az cosmosdb mongodb database create --account-name $account --resource-group $resourceGroup --name $database --throughput $originalThroughput
+
+# Define a minimal index policy for the collection
+printf '[ {"key": {"keys": ["_id"]}} ]' > idxpolicy-$randomIdentifier.json
+
+# Create a MongoDB API collection
+az cosmosdb mongodb collection create --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --shard "user_id" --throughput $originalThroughput --idx @idxpolicy-$randomIdentifier.json
+
+# Clean up temporary index policy file
+rm -f "idxpolicy-$randomIdentifier.json"
+
+# Throughput operations for MongoDB API database
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned database throughput
+az cosmosdb mongodb database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable database throughput
+minimumThroughput=$(az cosmosdb mongodb database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.minimumThroughput -o tsv)
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update database throughput
+echo "Updating $database throughput to $updateThroughput"
+az cosmosdb mongodb database throughput update --account-name $account --resource-group $resourceGroup --name $database --throughput $updateThroughput
+
+# Migrate the database from standard (manual) throughput to autoscale throughput
+az cosmosdb mongodb database throughput migrate --account-name $account --resource-group $resourceGroup --name $database --throughput-type 'autoscale'
+
+# Retrieve current autoscale provisioned max database throughput
+az cosmosdb mongodb database throughput show --account-name $account --resource-group $resourceGroup --name $database --query resource.autoscaleSettings.maxThroughput -o tsv
+
+# Throughput operations for MongoDB API collection
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned collection throughput
+az cosmosdb mongodb collection throughput show --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable collection throughput
+minimumThroughput=$(az cosmosdb mongodb collection throughput show --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --query resource.minimumThroughput -o tsv)
+
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update collection throughput
+echo "Updating collection throughput to $updateThroughput"
+az cosmosdb mongodb collection throughput update --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --throughput $updateThroughput
+
+# Migrate the collection from standard (manual) throughput to autoscale throughput
+az cosmosdb mongodb collection throughput migrate --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --throughput 'autoscale'
+
+# Retrieve the current autoscale provisioned max collection throughput
+az cosmosdb mongodb collection throughput show --account-name $account --resource-group $resourceGroup --database-name $database --name $collection --query resource.autoscaleSettings.maxThroughput -o tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/scale-cosmosdb-autoscale-collection/scale-cosmosdb-autoscale-collection.sh b/cosmosdb/scale-cosmosdb-autoscale-collection/scale-cosmosdb-autoscale-collection.sh
deleted file mode 100644
index a63144fe..00000000
--- a/cosmosdb/scale-cosmosdb-autoscale-collection/scale-cosmosdb-autoscale-collection.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-# Autoscale a collection
-
-*To be completed by Kirill*
diff --git a/cosmosdb/scale-cosmosdb-get-account-key/secure-cosmosdb-get-account-key.sh b/cosmosdb/scale-cosmosdb-get-account-key/secure-cosmosdb-get-account-key.sh
deleted file mode 100644
index ff6d471f..00000000
--- a/cosmosdb/scale-cosmosdb-get-account-key/secure-cosmosdb-get-account-key.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --locations "South Central US"=0 "North Central US"=1 \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# List account keys
-az cosmosdb list-keys \
- --name $name \
- --resource-group $resourceGroupName
\ No newline at end of file
diff --git a/cosmosdb/scale-cosmosdb-replicate-multiple-regions/scale-cosmosdb-replicate-multiple-regions.sh b/cosmosdb/scale-cosmosdb-replicate-multiple-regions/scale-cosmosdb-replicate-multiple-regions.sh
deleted file mode 100644
index ba4c6fd8..00000000
--- a/cosmosdb/scale-cosmosdb-replicate-multiple-regions/scale-cosmosdb-replicate-multiple-regions.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Replicate in multiple regions
-az cosmosdb update \
- --name $name \
- --resource-group $resourceGroupName \
- --locations "South Central US"=0 "North Central US"=1 "East US"=2 "West US"=3
-
-# Modify regional failover priorities
-az cosmosdb update \
- --name $name \
- --resource-group $resourceGroupName \
- --locations "South Central US"=3 "North Central US"=2 "East US"=1 "West US"=0
-
-
diff --git a/cosmosdb/scale-cosmosdb-throughput/scale-cosmosdb-throughput.sh b/cosmosdb/scale-cosmosdb-throughput/scale-cosmosdb-throughput.sh
deleted file mode 100644
index 3c52a638..00000000
--- a/cosmosdb/scale-cosmosdb-throughput/scale-cosmosdb-throughput.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-databaseName='docdb-test-database'
-collectionName='docdb-test-collection'
-originalThroughput=400
-newThroughput=700
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --locations "South Central US"=0 "North Central US"=1 \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a database
-az cosmosdb database create \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Create a collection
-az cosmosdb collection create \
- --collection-name $collectionName \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName \
- --throughput $originalThrougput
-
-# Scale throughput
-az cosmosdb collection update \
- --collection-name $collectionName \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName \
- --throughput $newThroughput
diff --git a/cosmosdb/secure-cosmosdb-create-firewall/secure-cosmosdb-create-firewall.sh b/cosmosdb/secure-cosmosdb-create-firewall/secure-cosmosdb-create-firewall.sh
deleted file mode 100644
index 2ba87005..00000000
--- a/cosmosdb/secure-cosmosdb-create-firewall/secure-cosmosdb-create-firewall.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-databaseName='docdb-test-database'
-collectionName='docdb-test-collection'
-ipRangeFilter="13.91.6.132,13.91.6.1/24"
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --locations "South Central US"=0 "North Central US"=1 \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a database
-az cosmosdb database create \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Create a collection
-az cosmosdb collection create \
- --collection-name $collectionName \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Configure the firewall
-az cosmosdb update \
- --name $name \
- --resource-group $resourceGroupName \
- --ip-range-filter $ipRangeFilter
diff --git a/cosmosdb/secure-cosmosdb-get-mongodb-connection-string/secure-cosmosdb-get-mongodb-connection-string.sh b/cosmosdb/secure-cosmosdb-get-mongodb-connection-string/secure-cosmosdb-get-mongodb-connection-string.sh
deleted file mode 100644
index 3ec1d604..00000000
--- a/cosmosdb/secure-cosmosdb-get-mongodb-connection-string/secure-cosmosdb-get-mongodb-connection-string.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-databaseName='docdb-mongodb-database'
-collectionName='docdb-mongodb-collection'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a MongoDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind MongoDB \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# Create a database
-az cosmosdb database create \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Create a collection
-az cosmosdb collection create \
- --collection-name $collectionName \
- --name $name \
- --db-name $databaseName \
- --resource-group $resourceGroupName
-
-# Get the connection string for MongoDB apps
-az cosmosdb list-connection-strings \
- --name $name \
- --resource-group $resourceGroupName
diff --git a/cosmosdb/secure-cosmosdb-regenerate-keys/secure-cosmosdb-regenerate-keys.sh b/cosmosdb/secure-cosmosdb-regenerate-keys/secure-cosmosdb-regenerate-keys.sh
deleted file mode 100644
index 3f00984f..00000000
--- a/cosmosdb/secure-cosmosdb-regenerate-keys/secure-cosmosdb-regenerate-keys.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-
-# Set variables for the new account, database, and collection
-resourceGroupName='myResourceGroup'
-location='southcentralus'
-name='docdb-test'
-
-# Create a resource group
-az group create \
- --name $resourceGroupName \
- --location $location
-
-# Create a DocumentDB API Cosmos DB account
-az cosmosdb create \
- --name $name \
- --kind GlobalDocumentDB \
- --locations "South Central US"=0 "North Central US"=1 \
- --resource-group $resourceGroupName \
- --max-interval 10 \
- --max-staleness-prefix 200
-
-# List account keys
-az cosmosdb list-keys \
- --name $name \
- --resource-group $resourceGroupName
-
-# Regenerate an account key
-az documentdb regenerate-key \
- --name $name \
- --resource-group $resourceGroupName \
- --key-kind secondary
diff --git a/cosmosdb/sql/autoscale.sh b/cosmosdb/sql/autoscale.sh
new file mode 100644
index 00000000..7304d57e
--- /dev/null
+++ b/cosmosdb/sql/autoscale.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a SQL API database and container with autoscale
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="autoscale-sql-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-sql-cosmos"
+container="container1"
+partitionKey="/partitionKey"
+maxThroughput=1000 #minimum = 1000
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for SQL API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False
+
+# Create a SQL API database
+echo "Creating $database"
+az cosmosdb sql database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Create a SQL API container with autoscale
+echo "Creating $container with $maxThroughput"
+az cosmosdb sql container create --account-name $account --resource-group $resourceGroup --database-name $database --name $container --partition-key-path $partitionKey --max-throughput $maxThroughput
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/sql/create.sh b/cosmosdb/sql/create.sh
new file mode 100644
index 00000000..f2b0a785
--- /dev/null
+++ b/cosmosdb/sql/create.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a SQL API database and container
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation="South Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="create-sql-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-sql-cosmos"
+container="container1"
+partitionKey="/zipcode"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for SQL API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --locations regionName="$failoverLocation" failoverPriority=1 isZoneRedundant=False
+
+# Create a SQL API database
+echo "Creating $database"
+az cosmosdb sql database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Define the index policy for the container, include spatial and composite indexes
+printf '
+{
+ "indexingMode": "consistent",
+ "includedPaths": [
+ {"path": "/*"}
+ ],
+ "excludedPaths": [
+ { "path": "/headquarters/employees/?"}
+ ],
+ "spatialIndexes": [
+ {"path": "/*", "types": ["Point"]}
+ ],
+ "compositeIndexes":[
+ [
+ { "path":"/name", "order":"ascending" },
+ { "path":"/age", "order":"descending" }
+ ]
+ ]
+}' > "idxpolicy-$randomIdentifier.json"
+
+# Create a SQL API container
+echo "Creating $container with $maxThroughput"
+az cosmosdb sql container create --account-name $account --resource-group $resourceGroup --database-name $database --name $container --partition-key-path $partitionKey --throughput 400 --idx @idxpolicy-$randomIdentifier.json
+
+# Clean up temporary index policy file
+rm -f "idxpolicy-$randomIdentifier.json"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/sql/lock.sh b/cosmosdb/sql/lock.sh
new file mode 100644
index 00000000..bee12284
--- /dev/null
+++ b/cosmosdb/sql/lock.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+# Tested after running the "create.sh" script
+
+#
+# Resource lock operations for a SQL database and container
+
+# Subscription owner permissions required for this script
+
+# Run this script after running
+# "https://docs.microsoft.com/azure/cosmos-db/scripts/cli/sql/create#sample-script"
+
+# Variable block
+# Use values from prerequisite script or from your environment
+# resourceGroup="your resource group name"
+# account="your account name"
+# database="your database name"
+# container="your container name"
+
+lockType="CanNotDelete" # CanNotDelete or ReadOnly
+databaseParent="databaseAccounts/$account"
+containerParent="databaseAccounts/$account/sqlDatabases/$database"
+databaseLock="$database-Lock"
+containerLock="$container-Lock"
+
+# Create a delete lock on database
+echo "Creating $lockType lock on $database"
+az lock create --name $databaseLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/sqlDatabases --lock-type $lockType --parent $databaseParent --resource $database
+
+# Create a delete lock on container
+echo "Creating $lockType lock on $container"
+az lock create --name $containerLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/containers --lock-type $lockType --parent $containerParent --resource $container
+
+# List all locks on a Cosmos account
+echo "Listing locks on $account"
+az lock list --resource-group $resourceGroup --resource-name $account --namespace Microsoft.DocumentDB --resource-type databaseAccounts
+
+# Delete lock on database
+echo "Deleting $databaseLock on $database"
+lockid=$(az lock show --name $databaseLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/sqlDatabases --resource $database --parent $databaseParent --output tsv --query id)
+az lock delete --ids $lockid
+
+# Delete lock on container
+echo "Deleting $containerLock on $container"
+lockid=$(az lock show --name $containerLock --resource-group $resourceGroup --resource-type Microsoft.DocumentDB/containers --resource-name $container --parent $containerParent --output tsv --query id)
+az lock delete --ids $lockid
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/sql/rbac-bulk-apply.sh b/cosmosdb/sql/rbac-bulk-apply.sh
new file mode 100644
index 00000000..8ab84d87
--- /dev/null
+++ b/cosmosdb/sql/rbac-bulk-apply.sh
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+# Tested on February 26, 2025, with Azure CLI version 2.68.0
+
+#
+# This sample script is designed to help users migrate from key-based to Entra Id authentication for their
+# Cosmos DB accounts by assigning RBAC roles to both your Entra Id as well as a new user assigned managed identity
+# for you to apply as the "Identity" for any services within a resource group that contains a Cosmos DB account.
+
+# This script can be run as-is and it will process every Cosmos account within every resource group.
+# Or you can specify a single resource group and it will process every Cosmos account within it, or selected accounts.
+
+subscriptionId="my subscription id"
+
+# Login to Azure if not already authenticated, select subscription
+# This can be commented out if running in Azure Cloud Shell
+#az login
+az account set -s $subscriptionId
+
+# Capture the current user's Id
+principalId=$(az ad signed-in-user show --query id -o tsv)
+
+
+# Specify one or more resource groups and process all accounts within them
+# Or specify just one resource group and only specific accounts within that one resource group
+# Comment out to process all accounts in every resource group in the subscription
+#resourceGroups=('resource group 1' 'resource group 2')
+
+
+# Or you can process all resource groups and all accounts in the subscription
+if [ ${#resourceGroups[@]} -eq 0 ]; then
+ resourceGroups=$(az group list --query "[].name" -o tsv)
+fi
+
+
+# Loop through every resource group
+for resourceGroup in "${resourceGroups[@]}"; do
+ echo "Processing resource group: $resourceGroup"
+
+ # Deployed services need their own identity to access Cosmos.
+ # Managed identities tend to be workload specific so we will
+ # create a new user assigned managed identity for each resource group.
+ uaManagedIdentity="$resourceGroup-mi"
+ az identity create -g $resourceGroup -n $uaManagedIdentity --output none
+ miPrincipalId=$(az identity show -g $resourceGroup -n $uaManagedIdentity --query principalId -o tsv)
+ echo "Managed Identity created: $uaManagedIdentity"
+
+
+ # Apply Azure RBAC for the Control Plane for Cosmos DB. Users can create accounts and not always modify them so making that explicit here.
+ # Get the role definition Id for the Document DB Account Contributor role (Azure RBAC)
+ # This provides access to the Cosmos DB keys and connection strings too but if you're using this script, probably don't need those anymore
+ # Cosmos DB Account Operator is a more restrictive role that does not provide access to keys or connection strings
+ roleDefinitionId=$(az role definition list --name "DocumentDB Account Contributor" --query "[0].id" -o tsv)
+
+ # Apply the Account Contributor role to you, the current user
+ echo "Applying DocumentDB Account Contributor role to current user"
+ az role assignment create --role $roleDefinitionId --assignee-object-id $principalId --assignee-principal-type "User" --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroup --output none
+
+ # Apply the Account Contributor role to the user assigned managed identity if it is not null
+ if [ ! -z "$miPrincipalId" ]; then
+ echo "Applying DocumentDB Account Contributor role to the managed identity"
+ az role assignment create --role $roleDefinitionId --assignee-object-id $miPrincipalId --assignee-principal-type "ServicePrincipal" --scope /subscriptions/$subscriptionId/resourcegroups/$resourceGroup --output none
+ fi
+
+ # Limit to one or more Cosmos DB accounts within a specific resource group
+ # Or comment out to process all accounts in the resource group
+ # Only uncomment this if specifying a single resource group above
+ #accounts=('cosmos account 1' 'cosmos account 2')
+
+ # Or you can process all accounts in the resource group
+ if [ ${#accounts[@]} -eq 0 ]; then
+ processAllAccounts=true
+ # Get the list of Cosmos DB accounts in this resource group
+ readarray -t accounts < <(az cosmosdb list -g $resourceGroup --query "[].name" -o tsv)
+ fi
+
+ # Now apply Cosmos data plane RBAC to both the current user and the managed identity for each Cosmos DB account
+ # Loop through every Cosmos DB account in the resource group or array above
+ for account in "${accounts[@]}"; do
+
+ echo "Processing account: $account"
+
+ # Trim potential leading/trailing whitespace from account
+ account=$(echo "$account" | xargs)
+
+ echo "Updating account: $account with RBAC Policy"
+ echo "Please wait..."
+
+ # Apply the RBAC policy to the Cosmos DB account
+ az cosmosdb sql role assignment create \
+ -n "Cosmos DB Built-in Data Contributor" \
+ -g $resourceGroup \
+ -a $account \
+ -p $principalId \
+ -s /"/" \
+ --output none
+
+ # Apply the RBAC policy to the miPrincipalId if it is not null
+ if [ ! -z "$miPrincipalId" ]; then
+ az cosmosdb sql role assignment create \
+ -n "Cosmos DB Built-in Data Contributor" \
+ -g $resourceGroup \
+ -a $account \
+ -p $miPrincipalId \
+ -s /"/" \
+ --output none
+ fi
+
+ echo "Update complete for account: $account"
+
+ done
+
+ # Reset the accounts array if processing all accounts in one or more resource groups
+ if [ $processAllAccounts ]; then
+ accounts=()
+ fi
+
+ echo "Resource group: $resourceGroup complete"
+ echo "Locate this user assigned managed identity: $uaManagedIdentity, in resource group: $resourceGroup and make it the identity for any services accessing Cosmos"
+
+done
+
+echo "All Done! Enjoy your new RBAC enabled Cosmos accounts!"
+
+#
diff --git a/cosmosdb/sql/serverless.sh b/cosmosdb/sql/serverless.sh
new file mode 100644
index 00000000..b948100c
--- /dev/null
+++ b/cosmosdb/sql/serverless.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a SQL API serverless account with database and container
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="serverless-sql-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-sql-cosmos"
+container="container1"
+partitionKey="/partitionKey"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for SQL API
+az cosmosdb create --name $account --resource-group $resourceGroup --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --capabilities EnableServerless
+
+# Create a SQL API database
+echo "Creating $database"
+az cosmosdb sql database create --account-name $account --resource-group $resourceGroup --name $database
+
+# Create a SQL API container
+echo "Creating $container with $partitionKey"
+az cosmosdb sql container create --account-name $account --resource-group $resourceGroup --database-name $database --name $container --partition-key-path $partitionKey
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/sql/throughput.sh b/cosmosdb/sql/throughput.sh
new file mode 100644
index 00000000..d646a146
--- /dev/null
+++ b/cosmosdb/sql/throughput.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Throughput operations for a SQL API database and container
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="throughput-sql-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+database="msdocs-db-sql-cosmos"
+container="container1"
+partitionKey="/partitionKey"
+originalThroughput=400
+updateThroughput=500
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for SQL API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup
+
+# Create a SQL API database
+echo "Creating $database with $originalThroughput"
+az cosmosdb sql database create --account-name $account --resource-group $resourceGroup --name $database --throughput $originalThroughput
+
+# Create a SQL API container
+echo "Creating $container with $maxThroughput"
+az cosmosdb sql container create --account-name $account --resource-group $resourceGroup --database-name $database --name $container --partition-key-path $partitionKey --throughput $originalThroughput
+
+# Throughput operations for SQL API database
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned database throughput
+az cosmosdb sql database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable database throughput
+minimumThroughput=$(az cosmosdb sql database throughput show --resource-group $resourceGroup --account-name $account --name $database --query resource.minimumThroughput -o tsv)
+
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update database throughput
+echo "Updating $database throughput to $updateThroughput"
+az cosmosdb sql database throughput update --account-name $account --resource-group $resourceGroup --name $database --throughput $updateThroughput
+
+# Migrate the database from standard (manual) throughput to autoscale throughput
+az cosmosdb sql database throughput migrate --account-name $account --resource-group $resourceGroup --name $database --throughput-type "autoscale"
+
+# Retrieve current autoscale provisioned max database throughput
+az cosmosdb sql database throughput show --account-name $account --resource-group $resourceGroup --name $database --query resource.autoscaleSettings.maxThroughput -o tsv
+
+# Throughput operations for SQL API container
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned container throughput
+az cosmosdb sql container throughput show --account-name $account --resource-group $resourceGroup --database-name $database --name $container --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable container throughput
+minimumThroughput=$(az cosmosdb sql container throughput show --account-name $account --resource-group $resourceGroup --database-name $database --name $container --query resource.minimumThroughput -o tsv)
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update container throughput
+echo "Updating $container throughput to $updateThroughput"
+az cosmosdb sql container throughput update --account-name $account --resource-group $resourceGroup --database-name $database --name $container --throughput $updateThroughput
+
+# Migrate the container from standard (manual) throughput to autoscale throughput
+az cosmosdb sql container throughput migrate --account-name $account --resource-group $resourceGroup --database-name $database --name $container --throughput "autoscale"
+
+# Retrieve the current autoscale provisioned max container throughput
+az cosmosdb sql container throughput show --account-name $account --resource-group $resourceGroup --database-name $database --name $container --query resource.autoscaleSettings.maxThroughput -o tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/table/autoscale.sh b/cosmosdb/table/autoscale.sh
new file mode 100644
index 00000000..b4118a43
--- /dev/null
+++ b/cosmosdb/table/autoscale.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Table API table with autoscale
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="autoscale-table-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+table="msdocs-table-cosmos-$randomIdentifier"
+maxThroughput=1000 #minimum = 1000
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Table API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableTable --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False
+
+# Create a Table API Table with autoscale
+echo "Create $table with $maxThroughput"
+az cosmosdb table create --account-name $account --resource-group $resourceGroup --name $table --max-throughput $maxThroughput
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/table/create.sh b/cosmosdb/table/create.sh
new file mode 100644
index 00000000..c08f7704
--- /dev/null
+++ b/cosmosdb/table/create.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Table API table
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+failoverLocation="South Central US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="create-table-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+table="msdocs-table-cosmos-$randomIdentifier"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Table API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableTable --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False --locations regionName="$failoverLocation" failoverPriority=1 isZoneRedundant=False
+
+# Create a Table API Table
+echo "Creating $table"
+az cosmosdb table create --account-name $account --resource-group $resourceGroup --name $table --throughput 400
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/table/lock.sh b/cosmosdb/table/lock.sh
new file mode 100644
index 00000000..224ba3fa
--- /dev/null
+++ b/cosmosdb/table/lock.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+# Tested after running the "create.sh" script
+
+#
+# Resource lock operations for a Table API table
+
+# Subscription owner permissions required for this script
+
+# Run this script after running
+# "https://docs.microsoft.com/azure/cosmos-db/scripts/cli/table/create#sample-script"
+
+# Variable block
+# Use values from prerequisite script or from your environment
+# resourceGroup="your resource group name"
+# account="your account name"
+# table="your table name"
+
+lockType='CanNotDelete' # CanNotDelete or ReadOnly
+tableParent="databaseAccounts/$account"
+tableResourceType="Microsoft.DocumentDB/tables"
+tableLock='$table-Lock'
+
+# Create a delete lock on table
+echo "Creating $lockType lock on $table"
+az lock create --name $tableLock --resource-group $resourceGroup --resource-type $tableResourceType --lock-type $lockType --parent $tableParent --resource $table
+
+# List all locks on a Cosmos account
+echo "Listing locks on $account"
+az lock list --resource-group $resourceGroup --resource-name $account --namespace Microsoft.DocumentDB --resource-type databaseAccounts
+
+# Delete lock on table
+echo "Deleting $tableLock on $table"
+lockid=$(az lock show --name $tableLock --resource-group $resourceGroup --resource-type $tableResourceType --resource $table --parent $tableParent --output tsv --query id)
+az lock delete --ids $lockid
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/table/serverless.sh b/cosmosdb/table/serverless.sh
new file mode 100644
index 00000000..4bf75c8c
--- /dev/null
+++ b/cosmosdb/table/serverless.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Create a Table API serverless account and table
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="serverless-table-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+table="msdocs-table-cosmos-$randomIdentifier"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Table API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableTable EnableServerless --default-consistency-level Eventual --locations regionName="$location" failoverPriority=0 isZoneRedundant=False \
+
+# Create a Table API Table
+az cosmosdb table create --account-name $account --resource-group $resourceGroup --name $table
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/cosmosdb/table/throughput.sh b/cosmosdb/table/throughput.sh
new file mode 100644
index 00000000..2955e0ea
--- /dev/null
+++ b/cosmosdb/table/throughput.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/20/2022
+
+#
+# Throughput operations for a Table API table
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-cosmosdb-rg-$randomIdentifier"
+tag="throughput-table-cosmosdb"
+account="msdocs-account-cosmos-$randomIdentifier" #needs to be lower case
+table="msdocs-table-cosmos-$randomIdentifier"
+originalThroughput=400
+updateThroughput=500
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Cosmos account for Table API
+echo "Creating $account"
+az cosmosdb create --name $account --resource-group $resourceGroup --capabilities EnableTable
+
+# Create a Table API Table with autoscale
+echo "Create $table with $maxThroughput"
+az cosmosdb table create --account-name $account --resource-group $resourceGroup --name $table --throughput $originalThroughput
+
+# Throughput operations for Table API table
+# Read the current throughput
+# Read the minimum throughput
+# Make sure the updated throughput is not less than the minimum
+# Update the throughput
+# Migrate between standard (manual) and autoscale throughput
+# Read the autoscale max throughput
+
+# Retrieve the current provisioned table throughput
+az cosmosdb table throughput show --name $table --resource-group $resourceGroup --account-name $account --query resource.throughput -o tsv
+
+# Retrieve the minimum allowable table throughput
+minimumThroughput=$(az cosmosdb table throughput show --resource-group $resourceGroup --account-name $account --name $table --query resource.minimumThroughput -o tsv)
+echo $minimumThroughput
+
+# Make sure the updated throughput is not less than the minimum allowed throughput
+if [ $updateThroughput -lt $minimumThroughput ]; then
+ updateThroughput=$minimumThroughput
+fi
+
+# Update table throughput
+echo "Updating $table throughput to $updateThroughput"
+az cosmosdb table throughput update --account-name $account --resource-group $resourceGroup --name $table --throughput $updateThroughput
+
+# Migrate the table from standard (manual) throughput to autoscale throughput
+az cosmosdb table throughput migrate --account-name $account --resource-group $resourceGroup --name $table --throughput-type 'autoscale'
+
+# Retrieve current autoscale provisioned max table throughput
+az cosmosdb table throughput show --account-name $account --resource-group $resourceGroup --name $table --query resource.autoscaleSettings.maxThroughput -o tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/devtest-lab/create-verify-virtual-machine-in-lab/create-verify-virtual-machine-in-lab.sh b/devtest-lab/create-verify-virtual-machine-in-lab/create-verify-virtual-machine-in-lab.sh
new file mode 100644
index 00000000..6e54f8ce
--- /dev/null
+++ b/devtest-lab/create-verify-virtual-machine-in-lab/create-verify-virtual-machine-in-lab.sh
@@ -0,0 +1,31 @@
+resourceGroupName=''
+location=''
+labName=""
+vmName=""
+vmImageName=""
+vmSize=""
+
+# Create a resource group
+az group create \
+ --name $resourceGroupName \
+ --location $location
+
+# Create a VM from a marketplace image with ssh authentication
+az lab vm create
+ --lab-name $labName
+ --resource-group $resourceGroupName
+ --name $vmName
+ --image $vmImageName
+ --image-type gallery
+ --size $vmSize
+ --authentication-type ssh
+ --generate-ssh-keys
+ --ip-configuration public
+
+# Verify that the VM is available
+az lab vm show
+ --lab-name sampleLabName
+ --name sampleVMName
+ --resource-group sampleResourceGroup
+ --expand 'properties($expand=ComputeVm,NetworkInterface)'
+ --query '{status: computeVm.statuses[0].displayStatus, fqdn: fqdn, ipAddress: networkInterface.publicIpAddress}'
\ No newline at end of file
diff --git a/devtest-lab/start-connect-virtual-machine-in-lab/start-connect-virtual-machine-in-lab.sh b/devtest-lab/start-connect-virtual-machine-in-lab/start-connect-virtual-machine-in-lab.sh
new file mode 100644
index 00000000..fb12dfd7
--- /dev/null
+++ b/devtest-lab/start-connect-virtual-machine-in-lab/start-connect-virtual-machine-in-lab.sh
@@ -0,0 +1,9 @@
+resourceGroupName=''
+labName=""
+vmName=""
+
+# Start the VM
+az lab vm start
+ --lab-name $labName
+ --name $vmName
+ --resource-group $resourceGroupName
diff --git a/devtest-lab/stop-delete-virtual-machine-in-lab/stop-delete-virtual-machine-in-lab.sh b/devtest-lab/stop-delete-virtual-machine-in-lab/stop-delete-virtual-machine-in-lab.sh
new file mode 100644
index 00000000..758e510d
--- /dev/null
+++ b/devtest-lab/stop-delete-virtual-machine-in-lab/stop-delete-virtual-machine-in-lab.sh
@@ -0,0 +1,15 @@
+resourceGroupName=''
+labName=""
+vmName=""
+
+# Stop the VM
+az lab vm stop
+ --lab-name $labName
+ --name $vmName
+ --resource-group $resourceGroupName
+
+# Delete the VM
+az lab vm delete
+ --lab-name $labName
+ --name $vmName
+ --resource-group $resourceGroupName
\ No newline at end of file
diff --git a/dns/create-dns-zone-and-record/create-dns-zone-and-record.sh b/dns/create-dns-zone-and-record/create-dns-zone-and-record.sh
new file mode 100644
index 00000000..bc3eefb1
--- /dev/null
+++ b/dns/create-dns-zone-and-record/create-dns-zone-and-record.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Create a resource group.
+az group create \
+ -n myResourceGroup \
+ -l eastus
+
+# Create a DNS zone. Substitute zone name "contoso.com" with the values for your own.
+
+az network dns zone create \
+ -g MyResourceGroup \
+ -n contoso.com
+
+# Create a DNS record. Substitute zone name "contoso.com" and IP address "1.2.3.4* with the values for your own.
+
+az network dns record-set a add-record \
+ --g MyResourceGroup \
+ --z contoso.com \
+ --n www \
+ --a 1.2.3.4
+
+# Get a list the DNS records in your zone
+az network dns record-set list \
+ -g MyResourceGroup \
+ -z contoso.com
\ No newline at end of file
diff --git a/event-grid/create-topic-subscribe/event-grid.sh b/event-grid/create-topic-subscribe/event-grid.sh
new file mode 100644
index 00000000..d83ec4e1
--- /dev/null
+++ b/event-grid/create-topic-subscribe/event-grid.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/28/2022
+
+#
+# Create Event Grid custom topic
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+subscriptionId="$(az account show --query id -o tsv)"
+resourceGroup="msdocs-event-grid-rg-$randomIdentifier"
+tag="event-grid"
+topic="msdocs-event-grid-topic-$randomIdentifier"
+site="msdocs-event-grid-site-$randomIdentifier"
+eventSubscription="msdocs-event-subscription-$randomIdentifier"
+webappEndpoint="https://$site.azurewebsites.net/api/updates"
+storage="msdocsstorage$randomIdentifier"
+
+# Create a resource group
+echo "Creating in "$location"..."
+az group create --name $resourceGroup --location "$location" --tag $tag
+
+# Enable and then show the Event Grid resource provider
+az provider register --namespace Microsoft.EventGrid
+az provider show --namespace Microsoft.EventGrid --query "registrationState"
+
+# Create custom topic
+echo "Creating $topic"
+az eventgrid topic create \
+--resource-group $resourceGroup \
+--name $topic \
+--location "$location"
+
+# Create a message endpoint
+echo "Creating $site"
+az deployment group create \
+ --resource-group $resourceGroup \
+ --template-uri "https://raw.githubusercontent.com/Azure-Samples/azure-event-grid-viewer/master/azuredeploy.json" \
+ --parameters siteName=$site hostingPlanName=viewerhost
+
+# To view your web app, navigate to https://.azurewebsites.net
+
+# Subscribe to custom topic
+az eventgrid event-subscription create \
+ --source-resource-id "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.EventGrid/topics/$topic" \
+ --name demoViewerSub \
+ --endpoint $webappEndpoint
+
+# View your web app again to see the subscription validation event.
+# Select the eye icon to expand the event data
+
+# Send an event to your custom topic
+url=$(az eventgrid topic show --name $topic -g $resourceGroup --query "endpoint" --output tsv)
+key=$(az eventgrid topic key list --name $topic -g $resourceGroup --query "key1" --output tsv)
+echo $url
+echo $key
+event='[ {"id": "'"$RANDOM"'", "eventType": "recordInserted", "subject": "myapp/vehicles/motorcycles", "eventTime": "'`date +%Y-%m-%dT%H:%M:%S%z`'", "data":{ "make": "Ducati", "model": "Monster"},"dataVersion": "1.0"} ]'
+curl -X POST -H "aeg-sas-key: $key" -d "$event" $url
+
+# View your web app again to see the event that you just sent
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/load-balancer/create-vm-nlb/create-vm-nlb.sh b/load-balancer/create-vm-nlb/create-vm-nlb.sh
new file mode 100644
index 00000000..00cf493a
--- /dev/null
+++ b/load-balancer/create-vm-nlb/create-vm-nlb.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/3/2022
+
+#
+# Load balance traffic to VMs for high availability
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-load-balancer-rg-$randomIdentifier"
+tag="create-vm-nlb"
+vNet="msdocs-vnet-lb-$randomIdentifier"
+subnet="msdocs-subnet-lb-$randomIdentifier"
+loadBalancerPublicIp="msdocs-public-ip-lb-$randomIdentifier"
+loadBalancer="msdocs-load-balancer-$randomIdentifier"
+frontEndIp="msdocs-front-end-ip-lb-$randomIdentifier"
+backEndPool="msdocs-back-end-pool-lb-$randomIdentifier"
+probe80="msdocs-port80-health-probe-lb-$randomIdentifier"
+loadBalancerRuleWeb="msdocs-load-balancer-rule-port80-$randomIdentifier"
+loadBalancerRuleSSH="msdocs-load-balancer-rule-port22-$randomIdentifier"
+networkSecurityGroup="msdocs-network-security-group-lb-$randomIdentifier"
+networkSecurityGroupRuleSSH="msdocs-network-security-rule-port22-lb-$randomIdentifier"
+networkSecurityGroupRuleWeb="msdocs-network-security-rule-port80-lb-$randomIdentifier"
+nic="msdocs-nic-lb-$randomIdentifier"
+availabilitySet="msdocs-availablity-set-lb-$randomIdentifier"
+vm="msdocs-vm-lb-$randomIdentifier"
+image="Ubuntu2204"
+ipSku="Standard"
+login="azureuser"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network and a subnet.
+echo "Creating "
+az network vnet create --resource-group $resourceGroup --location "$location" --name $vNet --subnet-name $subnet
+
+# Create a public IP address for load balancer.
+echo "Creating $loadBalancerPublicIp"
+az network public-ip create --resource-group $resourceGroup --name $loadBalancerPublicIp
+
+# Create an Azure Load Balancer.
+echo "Creating $loadBalancer with $frontEndIP and $backEndPool"
+az network lb create --resource-group $resourceGroup --name $loadBalancer --public-ip-address $loadBalancerPublicIp --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool
+
+# Create an LB probe on port 80.
+echo "Creating $probe80 in $loadBalancer"
+az network lb probe create --resource-group $resourceGroup --lb-name $loadBalancer --name $probe80 --protocol tcp --port 80
+
+# Create an LB rule for port 80.
+echo "Creating $loadBalancerRuleWeb for $loadBalancer"
+az network lb rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $loadBalancerRuleWeb --protocol tcp --frontend-port 80 --backend-port 80 --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool --probe-name $probe80
+
+# Create three NAT rules for port 22.
+echo "Creating three NAT rules named $loadBalancerRuleSSH"
+for i in `seq 1 3`; do
+ az network lb inbound-nat-rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $loadBalancerRuleSSH$i --protocol tcp --frontend-port 422$i --backend-port 22 --frontend-ip-name $frontEndIp
+done
+
+# Create a network security group
+echo "Creating $networkSecurityGroup"
+az network nsg create --resource-group $resourceGroup --name $networkSecurityGroup
+
+# Create a network security group rule for port 22.
+echo "Creating $networkSecurityGroupRuleSSH in $networkSecurityGroup for port 22"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $networkSecurityGroup --name $networkSecurityGroupRuleSSH --protocol tcp --direction inbound --source-address-prefix '*' --source-port-range '*' --destination-address-prefix '*' --destination-port-range 22 --access allow --priority 1000
+
+# Create a network security group rule for port 80.
+echo "Creating $networkSecurityGroupRuleWeb in $networkSecurityGroup for port 22"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $networkSecurityGroup --name $networkSecurityGroupRuleWeb --protocol tcp --direction inbound --priority 1001 --source-address-prefix '*' --source-port-range '*' --destination-address-prefix '*' --destination-port-range 80 --access allow --priority 2000
+
+# Create three virtual network cards and associate with public IP address and NSG.
+echo "Creating three NICs named $nic for $vNet and $subnet"
+for i in `seq 1 3`; do
+ az network nic create --resource-group $resourceGroup --name $nic$i --vnet-name $vNet --subnet $subnet --network-security-group $networkSecurityGroup --lb-name $loadBalancer --lb-address-pools $backEndPool --lb-inbound-nat-rules $loadBalancerRuleSSH$i
+done
+
+# Create an availability set.
+echo "Creating $availabilitySet"
+az vm availability-set create --resource-group $resourceGroup --name $availabilitySet --platform-fault-domain-count 3 --platform-update-domain-count 3
+
+# Create three virtual machines, this creates SSH keys if not present.
+echo "Creating three VMs named $vm with $nic using $image"
+for i in `seq 1 3`; do
+ az vm create --resource-group $resourceGroup --name $vm$i --availability-set $availabilitySet --nics $nic$i --image $image --public-ip-sku $ipSku --admin-username $login --generate-ssh-keys --no-wait
+done
+
+# List the virtual machines
+az vm list --resource-group $resourceGroup
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/load-balancer/load-balance-across-availability-zones/load-balance-across-availability-zones.sh b/load-balancer/load-balance-across-availability-zones/load-balance-across-availability-zones.sh
new file mode 100644
index 00000000..9eacd402
--- /dev/null
+++ b/load-balancer/load-balance-across-availability-zones/load-balance-across-availability-zones.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/4/2022
+
+#
+# Load balance VMs across availability zones
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-load-balancer-rg-$randomIdentifier"
+tag="load-balance-vms-across-availability-zones"
+vNet="msdocs-vnet-lb-$randomIdentifier"
+subnet="msdocs-subnet-lb-$randomIdentifier"
+loadBalancerPublicIp="msdocs-public-ip-lb-$randomIdentifier"
+ipSku="Standard"
+zone="1 2 3"
+loadBalancer="msdocs-load-balancer-$randomIdentifier"
+frontEndIp="msdocs-front-end-ip-lb-$randomIdentifier"
+backEndPool="msdocs-back-end-pool-lb-$randomIdentifier"
+probe80="msdocs-port80-health-probe-lb-$randomIdentifier"
+loadBalancerRuleWeb="msdocs-load-balancer-rule-port80-$randomIdentifier"
+loadBalancerRuleSSH="msdocs-load-balancer-rule-port22-$randomIdentifier"
+networkSecurityGroup="msdocs-network-security-group-lb-$randomIdentifier"
+networkSecurityGroupRuleSSH="msdocs-network-security-rule-port22-lb-$randomIdentifier"
+networkSecurityGroupRuleWeb="msdocs-network-security-rule-port80-lb-$randomIdentifier"
+nic="msdocs-nic-lb-$randomIdentifier"
+vm="msdocs-vm-lb-$randomIdentifier"
+image="Ubuntu2204"
+login="azureuser"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network and a subnet.
+echo "Creating $vNet and $subnet"
+az network vnet create --resource-group $resourceGroup --name $vNet --location "$location" --subnet-name $subnet
+
+# Create a zonal Standard public IP address for load balancer.
+echo "Creating $loadBalancerPublicIp"
+az network public-ip create --resource-group $resourceGroup --name $loadBalancerPublicIp --sku $ipSku --zone $zone
+
+# Create an Azure Load Balancer.
+echo "Creating $loadBalancer with $frontEndIP and $backEndPool"
+az network lb create --resource-group $resourceGroup --name $loadBalancer --public-ip-address $loadBalancerPublicIp --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool --sku $ipSku
+
+# Create an LB probe on port 80.
+echo "Creating $probe80 in $loadBalancer"
+az network lb probe create --resource-group $resourceGroup --lb-name $loadBalancer --name $probe80 --protocol tcp --port 80
+
+# Create an LB rule for port 80.
+echo "Creating $loadBalancerRuleWeb for $loadBalancer"
+az network lb rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $loadBalancerRuleWeb --protocol tcp --frontend-port 80 --backend-port 80 --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool --probe-name $probe80
+
+# Create three NAT rules for port 22.
+echo "Creating three NAT rules named $loadBalancerRuleSSH"
+for i in `seq 1 3`; do
+az network lb inbound-nat-rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $loadBalancerRuleSSH$i --protocol tcp --frontend-port 422$i --backend-port 22 --frontend-ip-name $frontEndIp
+done
+
+# Create a network security group
+echo "Creating $networkSecurityGroup"
+az network nsg create --resource-group $resourceGroup --name $networkSecurityGroup
+
+# Create a network security group rule for port 22.
+echo "Creating $networkSecurityGroupRuleSSH in $networkSecurityGroup for port 22"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $networkSecurityGroup --name $networkSecurityGroupRuleSSH --protocol tcp --direction inbound --source-address-prefix '*' --source-port-range '*' --destination-address-prefix '*' --destination-port-range 22 --access allow --priority 1000
+
+# Create a network security group rule for port 80.
+echo "Creating $networkSecurityGroupRuleWeb in $networkSecurityGroup for port 22"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $networkSecurityGroup --name $networkSecurityGroupRuleWeb --protocol tcp --direction inbound --priority 1001 --source-address-prefix '*' --source-port-range '*' --destination-address-prefix '*' --destination-port-range 80 --access allow --priority 2000
+
+# Create three virtual network cards and associate with public IP address and NSG.
+echo "Creating three NICs named $nic for $vNet and $subnet"
+for i in `seq 1 3`; do
+az network nic create --resource-group $resourceGroup --name $nic$i --vnet-name $vNet --subnet $subnet --network-security-group $networkSecurityGroup --lb-name $loadBalancer --lb-address-pools $backEndPool --lb-inbound-nat-rules $loadBalancerRuleSSH$i
+done
+
+# Create three virtual machines, this creates SSH keys if not present.
+echo "Creating three VMs named $vm with $nic using $image"
+for i in `seq 1 3`; do
+az vm create --resource-group $resourceGroup --name $vm$i --zone $i --nics $nic$i --image $image --admin-username $login --generate-ssh-keys --no-wait
+done
+
+# List the virtual machines
+az vm list --resource-group $resourceGroup
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/load-balancer/load-balance-multiple-web-sites-vm/load-balance-multiple-web-sites-vm.sh b/load-balancer/load-balance-multiple-web-sites-vm/load-balance-multiple-web-sites-vm.sh
index 74b68096..c84fe31f 100644
--- a/load-balancer/load-balance-multiple-web-sites-vm/load-balance-multiple-web-sites-vm.sh
+++ b/load-balancer/load-balance-multiple-web-sites-vm/load-balance-multiple-web-sites-vm.sh
@@ -1,181 +1,140 @@
#!/bin/bash
-
-RgName="MyResourceGroup"
-Location="eastus"
-
-# Create a resource group.
-az group create \
- --name $RgName \
- --location $Location
+# Passed validation in Cloud Shell on 3/3/2022
+
+#
+# Load balance multiple websites
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-load-balancer-rg-$randomIdentifier"
+tag="load-balance-multiple-web-sites-vm"
+availabilitySet="msdocs-availablity-set-lb-$randomIdentifier"
+vNet="msdocs-vnet-lb-$randomIdentifier"
+subnet="msdocs-subnet-lb-$randomIdentifier"
+loadBalancerPublicIp="msdocs-public-ip-lb-$randomIdentifier"
+loadBalancerFrontEndConfig1="msdocs-contoso-lb-$randomIdentifier"
+loadBalancerFrontEndConfig2="msdocs-fabrikam-lb-$randomIdentifier"
+loadBalancer="msdocs-load-balancer-$randomIdentifier"
+frontEndIp="msdocs-front-end-ip-lb-$randomIdentifier"
+frontEndIpConfig1="msdocs-front-end-ip-config-contoso-lb-$randomIdentifier"
+frontEndIpConfig2="msdocs-front-end-ip-config-fabrikam-lb-$randomIdentifier"
+backEndPool="msdocs-back-end-pool-lb-$randomIdentifier"
+backEndAddressPool1="msdocs-back-end-address-pool-contoso-lb-$randomIdentifier"
+backEndAddressPool2="msdocs-back-end-address-pool-fabrikam-lb-$randomIdentifier"
+probe80="msdocs-port80-health-probe-lb-$randomIdentifier"
+lbRuleConfig1="msdocs-contoso-load-balancer-rule-$randomIdentifier"
+lbRuleConfig2="msdocs-fabrikam-load-balancer-rule-$randomIdentifier"
+publicIpVm1="msdocs-public-ip-vm1-lb-$randomIdentifier"
+nicVm1="msdocs-nic-vm1-$randomIdentifier"
+ipConfig1="msdocs-ipconfig-config1-lb-$randomIdentifier"
+ipConfig2="msdocs-ipconfig-config2-lb-$randomIdentifier"
+vm1="msdocs-vm1-lb-$randomIdentifier"
+publicIpVm2="msdocs-public-ip-vm2-lb-$randomIdentifier"
+ipSku="Standard"
+nicVm2="msdocs-nic-vm2-lb-$randomIdentifier"
+ipConfig1="msdocs-ipconfig-config1-lb-$randomIdentifier"
+ipConfig2="msdocs-ipconfig-config2-lb-$randomIdentifier"
+vm2="msdocs-vm2-lb-$randomIdentifier"
+image="Ubuntu2204"
+login="azureuser"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create an availability set for the two VMs that host both websites.
-az vm availability-set create \
- --resource-group $RgName \
- --location $Location \
- --name MyAvailabilitySet \
- --platform-fault-domain-count 2 \
- --platform-update-domain-count 2
+echo "Creating $availabilitySet"
+az vm availability-set create --resource-group $resourceGroup --location "$location" --name $availabilitySet --platform-fault-domain-count 2 --platform-update-domain-count 2
# Create a virtual network and a subnet.
-az network vnet create \
- --resource-group $RgName \
- --name MyVnet \
- --address-prefix 10.0.0.0/16 \
- --location $Location \
- --subnet-name MySubnet \
- --subnet-prefix 10.0.0.0/24
+echo "Creating $vNet and $subnet"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefix 10.0.0.0/16 --location "$location" --subnet-name $subnet --subnet-prefix 10.0.0.0/24
# Create three public IP addresses; one for the load balancer and two for the front-end IP configurations.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-LoadBalancer \
- --allocation-method Dynamic
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-Contoso \
- --allocation-method Dynamic
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-Fabrikam \
- --allocation-method Dynamic
-
-# Create a load balancer.
-az network lb create \
- --resource-group $RgName \
- --location $Location \
- --name MyLoadBalancer \
- --frontend-ip-name FrontEnd \
- --backend-pool-name BackEnd \
- --public-ip-address MyPublicIp-LoadBalancer
+echo "Creating $loadBalancerPublicIp"
+az network public-ip create --resource-group $resourceGroup --name $loadBalancerPublicIp --allocation-method Dynamic
+
+echo "Creating $loadBalancerFrontEndConfig1"
+az network public-ip create --resource-group $resourceGroup --name $loadBalancerFrontEndConfig1 --allocation-method Dynamic
+
+echo "Creating $loadBalancerFrontEndConfig2"
+az network public-ip create --resource-group $resourceGroup --name $loadBalancerFrontEndConfig2 --allocation-method Dynamic
+
+# Create an Azure Load Balancer.
+echo "Creating $loadBalancer with $frontEndIP and $backEndPool"
+az network lb create --resource-group $resourceGroup --location "$location" --name $loadBalancer --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool --public-ip-address $loadBalancerPublicIp
# Create two front-end IP configurations for both web sites.
-az network lb frontend-ip create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --public-ip-address MyPublicIp-Contoso \
- --name FeContoso
-az network lb frontend-ip create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --public-ip-address MyPublicIp-Fabrikam \
- --name FeFabrikam
+echo "Creating $frontEndIpConfig1 for $loadBalancerFrontEndConfig1"
+az network lb frontend-ip create --resource-group $resourceGroup --lb-name $loadBalancer --public-ip-address $loadBalancerFrontEndConfig1 --name $frontEndIpConfig1
+
+echo "Creating $frontEndIpConfig2 for $loadBalancerFrontEndConfig2"
+az network lb frontend-ip create --resource-group $resourceGroup --lb-name $loadBalancer --public-ip-address $loadBalancerFrontEndConfig2 --name $frontEndIpConfig2
# Create the back-end address pools.
-az network lb address-pool create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --name BeContoso
-az network lb address-pool create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --name BeFabrikam
+echo "Creating $backEndAddressPool1"
+az network lb address-pool create --resource-group $resourceGroup --lb-name $loadBalancer --name $backEndAddressPool1
+
+echo "Creating $backEndAddressPool2"
+az network lb address-pool create --resource-group $resourceGroup --lb-name $loadBalancer --name $backEndAddressPool2
# Create a probe on port 80.
-az network lb probe create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --name MyProbe \
- --protocol Http \
- --port 80 --path /
-
-# Create the load balancing rules.
-az network lb rule create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --name LBRuleContoso \
- --protocol Tcp \
- --probe-name MyProbe \
- --frontend-port 5000 \
- --backend-port 5000 \
- --frontend-ip-name FeContoso \
- --backend-pool-name BeContoso
-az network lb rule create \
- --resource-group $RgName \
- --lb-name MyLoadBalancer \
- --name LBRuleFabrikam \
- --protocol Tcp \
- --probe-name MyProbe \
- --frontend-port 5000 \
- --backend-port 5000 \
- --frontend-ip-name FeFabrikam \
- --backend-pool-name BeFabrikam
+echo "Creating $probe80 in $loadBalancer"
+az network lb probe create --resource-group $resourceGroup --lb-name $loadBalancer --name $probe80 --protocol Http --port 80 --path /
+
+# Create the load balancing rules forport 80.
+echo "Creating $lbRuleConfig1 for $loadBalancer"
+az network lb rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $lbRuleConfig1 --protocol Tcp --probe-name $probe80 --frontend-port 5000 --backend-port 5000 --frontend-ip-name $frontEndIpConfig1 --backend-pool-name $backEndAddressPool1
+
+echo "Creating $lbRuleConfig2 for $loadBalancer"
+az network lb rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $lbRuleConfig2 --protocol Tcp --probe-name $probe80 --frontend-port 5000 --backend-port 5000 --frontend-ip-name $frontEndIpConfig2 --backend-pool-name $backEndAddressPool2
# ############## VM1 ###############
# Create an Public IP for the first VM.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-Vm1 \
- --allocation-method Dynamic
+echo "Creating $publicIpVm1"
+az network public-ip create --resource-group $resourceGroup --name $publicIpVm1 --allocation-method Dynamic
# Create a network interface for VM1.
-az network nic create \
- --resource-group $RgName \
- --vnet-name MyVnet \
- --subnet MySubnet \
- --name MyNic-Vm1 \
- --public-ip-address MyPublicIp-Vm1
+echo "Creating $nicVm1 in $vNet and $subnet"
+az network nic create --resource-group $resourceGroup --vnet-name $vNet --subnet $subnet --name $nicVm1 --public-ip-address $publicIpVm1
# Create IP configurations for Contoso and Fabrikam.
-az network nic ip-config create \
- --resource-group $RgName \
- --name ipconfig2 \
- --nic-name MyNic-Vm1 \
- --lb-name MyLoadBalancer \
- --lb-address-pools BeContoso
-az network nic ip-config create \
- --resource-group $RgName \
- --name ipconfig3 \
- --nic-name MyNic-Vm1 \
- --lb-name MyLoadBalancer \
- --lb-address-pools BeFabrikam
+echo "Creating $ipConfig1 for $nicVm1"
+az network nic ip-config create --resource-group $resourceGroup --name $ipConfig1 --nic-name $nicVm1 --lb-name $loadBalancer --lb-address-pools $backEndAddressPool1
+
+echo "Creating $ipConfig2 for $nicVm1"
+az network nic ip-config create --resource-group $resourceGroup --name $ipConfig2 --nic-name $nicVm1 --lb-name $loadBalancer --lb-address-pools $backEndAddressPool2
# Create Vm1.
-az vm create \
- --resource-group $RgName \
- --name MyVm1 \
- --nics MyNic-Vm1 \
- --image UbuntuLTS \
- --availability-set MyAvailabilitySet \
- --admin-username azureadmin \
- --generate-ssh-keys
+echo "Creating $vm1"
+az vm create --resource-group $resourceGroup --name $vm1 --nics $nicVm1 --image $image --availability-set $availabilitySet --public-ip-sku $ipSku --admin-username $login --generate-ssh-keys
############### VM2 ###############
# Create an Public IP for the second VM.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-Vm2 \
- --allocation-method Dynamic
+echo "Creating $publicIpVm2"
+az network public-ip create --resource-group $resourceGroup --name $publicIpVm2 --allocation-method Dynamic
# Create a network interface for VM2.
-az network nic create \
- --resource-group $RgName \
- --vnet-name MyVnet \
- --subnet MySubnet \
- --name MyNic-Vm2 \
- --public-ip-address MyPublicIp-Vm2
+echo "Creating $nicVm2 in $vNet and $subnet"
+az network nic create --resource-group $resourceGroup --vnet-name $vNet --subnet $subnet --name $nicVm2 --public-ip-address $publicIpVm2
# Create IP-Configs for Contoso and Fabrikam.
-az network nic ip-config create \
- --resource-group $RgName \
- --name ipconfig2 \
- --nic-name MyNic-Vm2 \
- --lb-name MyLoadBalancer \
- --lb-address-pools BeContoso
-az network nic ip-config create \
- --resource-group $RgName \
- --name ipconfig3 \
- --nic-name MyNic-Vm2 \
- --lb-name MyLoadBalancer \
- --lb-address-pools BeFabrikam
+echo "Creating $ipConfig1 for $nicVm2"
+az network nic ip-config create --resource-group $resourceGroup --name $ipConfig1 --nic-name $nicVm2 --lb-name $loadBalancer --lb-address-pools $backEndAddressPool1
+
+echo "Creating $ipConfig2 for $nicVm2"
+az network nic ip-config create --resource-group $resourceGroup --name $ipConfig2 --nic-name $nicVm2 --lb-name $loadBalancer --lb-address-pools $backEndAddressPool2
# Create Vm2.
-az vm create \
- --resource-group $RgName \
- --name MyVm2 \
- --nics MyNic-Vm2 \
- --image UbuntuLTS \
- --availability-set MyAvailabilitySet \
- --admin-username azureadmin \
- --generate-ssh-keys
+echo "Creating $vm2"
+az vm create --resource-group $resourceGroup --name $vm2 --nics $nicVm2 --image Ubuntu2204 --availability-set $availabilitySet --public-ip-sku $ipSku --admin-username $login --generate-ssh-keys
+
+# List the virtual machines
+az vm list --resource-group $resourceGroup
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/load-balancer/load-balance-vms-within-specific-availability-zone/load-balance-vms-within-specific-availability-zone.sh b/load-balancer/load-balance-vms-within-specific-availability-zone/load-balance-vms-within-specific-availability-zone.sh
new file mode 100644
index 00000000..61e409e6
--- /dev/null
+++ b/load-balancer/load-balance-vms-within-specific-availability-zone/load-balance-vms-within-specific-availability-zone.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/4/2022
+
+#
+# Load balance traffic to VMs within a specific availability zone
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-load-balancer-rg-$randomIdentifier"
+tag="load-balance-vms-within-a-specific-availability-zone"
+vNet="msdocs-vnet-lb-$randomIdentifier"
+subnet="msdocs-subnet-lb-$randomIdentifier"
+loadBalancerPublicIp="msdocs-public-ip-lb-$randomIdentifier"
+ipSku="Standard"
+zone="1"
+loadBalancer="msdocs-load-balancer-$randomIdentifier"
+frontEndIp="msdocs-front-end-ip-lb-$randomIdentifier"
+backEndPool="msdocs-back-end-pool-lb-$randomIdentifier"
+probe80="msdocs-port80-health-probe-lb-$randomIdentifier"
+loadBalancerRuleWeb="msdocs-load-balancer-rule-port80-$randomIdentifier"
+loadBalancerRuleSSH="msdocs-load-balancer-rule-port22-$randomIdentifier"
+networkSecurityGroup="msdocs-network-security-group-lb-$randomIdentifier"
+networkSecurityGroupRuleSSH="msdocs-network-security-rule-port22-lb-$randomIdentifier"
+networkSecurityGroupRuleWeb="msdocs-network-security-rule-port80-lb-$randomIdentifier"
+nic="msdocs-nic-lb-$randomIdentifier"
+vm="msdocs-vm-lb-$randomIdentifier"
+image="Ubuntu2204"
+login="azureuser"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network and a subnet.
+echo "Creating $vNet and $subnet"
+az network vnet create --resource-group $resourceGroup --name $vNet --location "$location" --subnet-name $subnet
+
+# Create a zonal Standard public IP address for load balancer.
+echo "Creating $loadBalancerPublicIp"
+az network public-ip create --resource-group $resourceGroup --name $loadBalancerPublicIp --sku $ipSku --zone $zone
+
+# Create an Azure Load Balancer.
+echo "Creating $loadBalancer with $frontEndIP and $backEndPool"
+az network lb create --resource-group $resourceGroup --name $loadBalancer --public-ip-address $loadBalancerPublicIp --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool --sku $ipSku
+
+# Create an LB probe on port 80.
+echo "Creating $probe80 in $loadBalancer"
+az network lb probe create --resource-group $resourceGroup --lb-name $loadBalancer --name $probe80 --protocol tcp --port 80
+
+# Create an LB rule for port 80.
+echo "Creating $loadBalancerRuleWeb for $loadBalancer"
+az network lb rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $loadBalancerRuleWeb --protocol tcp --frontend-port 80 --backend-port 80 --frontend-ip-name $frontEndIp --backend-pool-name $backEndPool --probe-name $probe80
+
+# Create three NAT rules for port 22.
+echo "Creating three NAT rules named $loadBalancerRuleSSH"
+for i in `seq 1 3`; do
+az network lb inbound-nat-rule create --resource-group $resourceGroup --lb-name $loadBalancer --name $loadBalancerRuleSSH$i --protocol tcp --frontend-port 422$i --backend-port 22 --frontend-ip-name $frontEndIp
+done
+
+# Create a network security group
+echo "Creating $networkSecurityGroup"
+az network nsg create --resource-group $resourceGroup --name $networkSecurityGroup
+
+# Create a network security group rule for port 22.
+echo "Creating $networkSecurityGroupRuleSSH in $networkSecurityGroup for port 22"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $networkSecurityGroup --name $networkSecurityGroupRuleSSH --protocol tcp --direction inbound --source-address-prefix '*' --source-port-range '*' --destination-address-prefix '*' --destination-port-range 22 --access allow --priority 1000
+
+# Create a network security group rule for port 80.
+echo "Creating $networkSecurityGroupRuleWeb in $networkSecurityGroup for port 22"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $networkSecurityGroup --name $networkSecurityGroupRuleWeb --protocol tcp --direction inbound --priority 1001 --source-address-prefix '*' --source-port-range '*' --destination-address-prefix '*' --destination-port-range 80 --access allow --priority 2000
+
+# Create three virtual network cards and associate with public IP address and NSG.
+echo "Creating three NICs named $nic for $vNet and $subnet"
+for i in `seq 1 3`; do
+az network nic create --resource-group $resourceGroup --name $nic$i --vnet-name $vNet --subnet $subnet --network-security-group $networkSecurityGroup --lb-name $loadBalancer --lb-address-pools $backEndPool --lb-inbound-nat-rules $loadBalancerRuleSSH$i
+done
+
+# Create three virtual machines, this creates SSH keys if not present.
+echo "Creating three VMs named $vm with $nic using $image"
+for i in `seq 1 3`; do
+az vm create --resource-group $resourceGroup --name $vm$i --zone $zone --nics $nic$i --image $image --admin-username $login --generate-ssh-keys --no-wait
+done
+
+# List the virtual machines
+az vm list --resource-group $resourceGroup
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/managed-applications/create-application/create-application.sh b/managed-applications/create-application/create-application.sh
deleted file mode 100644
index 3b8f246f..00000000
--- a/managed-applications/create-application/create-application.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# Create resource group
-az group create --name applicationGroup --location westcentralus
-
-# Get ID of managed application definition
-appid=$(az managedapp definition show --name ManagedStorage --resource-group appDefinitionGroup --query id --output tsv)
-
-# Get subscription ID
-subid=$(az account show --query id --output tsv)
-
-# Construct the ID of the managed resource group
-managedGroupId=/subscriptions/$subid/resourceGroups/infrastructureGroup
-
-# Create the managed application
-az managedapp create \
- --name storageApp \
- --location "westcentralus" \
- --kind "Servicecatalog" \
- --resource-group applicationGroup \
- --managedapp-definition-id $appid \
- --managed-rg-id $managedGroupId \
- --parameters "{\"storageAccountNamePrefix\": {\"value\": \"demostorage\"}, \"storageAccountType\": {\"value\": \"Standard_LRS\"}}"
diff --git a/managed-applications/create-application/create-managed-application.sh b/managed-applications/create-application/create-managed-application.sh
new file mode 100644
index 00000000..0277655f
--- /dev/null
+++ b/managed-applications/create-application/create-managed-application.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/7/2022
+
+#
+# Define and create a managed application
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+appDefinitionResourceGroup="msdocs-managed-applications-app-definition-rg-$randomIdentifier"
+appResourceGroup="msdocs-managed-applications-app-definition-rg-$randomIdentifier"
+tag="create-managed-application"
+managedApp="StorageApp"
+
+# Create definition for a managed application
+
+# Create a application definition resource group
+echo "Creating $appDefinitionResourceGroup in "$location"..."
+az group create --name $appDefinitionResourceGroup --location "$location" --tags $tag
+
+# Get Azure Active Directory group to manage the application
+groupid=$(az ad group show --group reader --query id --output tsv)
+
+# Get role
+roleid=$(az role definition list --name Owner --query [].name --output tsv)
+
+# Create the definition for a managed application
+az managedapp definition create --name "$managedApp" --location "$location" --resource-group $appDefinitionResourceGroup --lock-level ReadOnly --display-name "Managed Storage Account" --description "Managed Azure Storage Account" --authorizations "$groupid:$roleid" --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/Managed%20Application%20Sample%20Packages/201-managed-storage-account/managedstorage.zip"
+
+# Create managed application
+
+# Create application resource group
+echo "Creating $appResourceGroup in "$location"..."
+az group create --name $appResourceGroup --location "$location" --tags $tag
+
+# Get ID of managed application definition
+appid=$(az managedapp definition show --name $managedApp --resource-group $appDefinitionResourceGroup --query id --output tsv)
+
+# Get subscription ID
+subid=$(az account show --query id --output tsv)
+
+# Construct the ID of the managed resource group
+managedGroupId=/subscriptions/$subid/resourceGroups/infrastructureGroup
+
+# Create the managed application
+az managedapp create --name storageApp --location "$location" --kind "Servicecatalog" --resource-group $appResourceGroup --managedapp-definition-id $appid --managed-rg-id $managedGroupId --parameters "{\"storageAccountNamePrefix\": {\"value\": \"demostorage\"}, \"storageAccountType\": {\"value\": \"Standard_LRS\"}}"
+#
+
+# echo "Deleting all resources"
+# az group delete --name $appResourceGroup -y
+# az group delete --name $appDefinitionResourceGroup -y
diff --git a/managed-applications/create-definition/create-definition.sh b/managed-applications/create-definition/create-definition.sh
deleted file mode 100644
index ac699e3f..00000000
--- a/managed-applications/create-definition/create-definition.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-# Create resource group
-az group create --name appDefinitionGroup --location westcentralus
-
-# Get Azure Active Directory group to manage the application
-groupid=$(az ad group show --group appManagers --query objectId --output tsv)
-
-# Get role
-roleid=$(az role definition list --name Owner --query [].name --output tsv)
-
-# Create the definition for a managed application
-az managedapp definition create \
- --name "ManagedStorage" \
- --location "westcentralus" \
- --resource-group appDefinitionGroup \
- --lock-level ReadOnly \
- --display-name "Managed Storage Account" \
- --description "Managed Azure Storage Account" \
- --authorizations "$groupid:$roleid" \
- --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-storage-account/managedstorage.zip"
\ No newline at end of file
diff --git a/managed-applications/get-application/get-application.sh b/managed-applications/get-application/get-application.sh
deleted file mode 100644
index 3a2411a9..00000000
--- a/managed-applications/get-application/get-application.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-# Get managed applications from known resource group
-az managedapp list --query "[?contains(resourceGroup,'DemoApp')]"
-
-# Get ID of managed resource group
-az managedapp list --query "[?contains(resourceGroup,'DemoApp')].{ managedResourceGroup:managedResourceGroupId }"
-
-# Get virtual machines in the managed resource group
-az resource list -g DemoApp6zkevchqk7sfq --query "[?contains(type,'Microsoft.Compute/virtualMachines')]"
-
-# Get information about virtual machines in managed resource group
-az vm list -g DemoApp6zkevchqk7sfq --query "[].{VMName:name,OSType:storageProfile.osDisk.osType,VMSize:hardwareProfile.vmSize}"
-
-## Resize virtual machines in managed resource group
-az vm resize --size Standard_D2_v2 --ids $(az vm list -g DemoApp6zkevchqk7sfq --query "[].id" -o tsv)
\ No newline at end of file
diff --git a/mariadb/backup-restore-pitr/backup-restore.sh b/mariadb/backup-restore-pitr/backup-restore.sh
new file mode 100644
index 00000000..b6fb9976
--- /dev/null
+++ b/mariadb/backup-restore-pitr/backup-restore.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/11/2022
+
+#
+# Restore a server from backup to a new server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mariadb-rg-$randomIdentifier"
+tag="backup-restore-mariadb"
+server="msdocs-mariadb-server-$randomIdentifier"
+sku="GP_Gen5_2"
+restoreServer="restore-server$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MariaDB server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mariadb server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Sleeping commands to wait long enough for automatic backup to be created
+echo "Sleeping..."
+sleep 10m
+
+# Restore a server from backup to a new server
+# To specify a specific point-in-time (in UTC) to restore from, use the ISO8601 format:
+# restorePoint=“2021-07-09T13:10:00Z”
+restorePoint=$(date +%s)
+restorePoint=$(expr $restorePoint - 60)
+restorePoint=$(date -d @$restorePoint +"%Y-%m-%dT%T")
+echo $restorePoint
+
+echo "Restoring $restoreServer"
+az mariadb server restore --name $restoreServer --resource-group $resourceGroup --restore-point-in-time $restorePoint --source-server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mariadb/change-server-configurations/change-server-configurations.sh b/mariadb/change-server-configurations/change-server-configurations.sh
new file mode 100644
index 00000000..c5f4501f
--- /dev/null
+++ b/mariadb/change-server-configurations/change-server-configurations.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/11/2022
+
+#
+# Change server configurations
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mariadb-rg-$randomIdentifier"
+tag="change-server-cofigurations-mariadb"
+server="msdocs-mariadb-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MariaDB server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mariadb server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Display all available configurations with valid values of an Azure Database for MariaDB server
+az mariadb server configuration list --resource-group $resourceGroup --server-name $server
+
+# Set value of *innodb_lock_wait_timeout*
+echo "Setting value of the innodb_lock_wait_timeout setting on $server"
+az mariadb server configuration set --resource-group $resourceGroup --server-name $server --name innodb_lock_wait_timeout --value 120
+
+# Check the value of *innodb_lock_wait_timeout*
+echo "Checking the value of the innodb_lock_wait_timeout setting on $server"
+az mariadb server configuration show --resource-group $resourceGroup --server-name $server --name innodb_lock_wait_timeout
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mariadb/create-mariadb-server-and-firewall-rule/create-mariadb-server-and-firewall-rule.sh b/mariadb/create-mariadb-server-and-firewall-rule/create-mariadb-server-and-firewall-rule.sh
new file mode 100644
index 00000000..dc72c152
--- /dev/null
+++ b/mariadb/create-mariadb-server-and-firewall-rule/create-mariadb-server-and-firewall-rule.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/11/2022
+
+#
+# Create MariaDB server and firewall rule
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mariadb-rg-$randomIdentifier"
+tag="create-mariadb-server-and-firewall-rule"
+server="msdocs-mariadb-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+# Specify appropriate IP address values for your environment
+# to limit / allow access to the MariaDB server
+startIp=0.0.0.0
+endIp=0.0.0.0
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MariaDB server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mariadb server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Configure a firewall rule for the server
+echo "Configuring a firewall rule for $server for the IP address range of $startIp to $endIp"
+az mariadb server firewall-rule create --resource-group $resourceGroup --server $server --name AllowIps --start-ip-address $startIp --end-ip-address $endIp
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mariadb/create-mariadb-server-vnet/create-mariadb-server.sh b/mariadb/create-mariadb-server-vnet/create-mariadb-server.sh
new file mode 100644
index 00000000..349efeee
--- /dev/null
+++ b/mariadb/create-mariadb-server-vnet/create-mariadb-server.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/11/2022
+
+#
+# Create MariaDB server in vNet
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mariadb-rg-$randomIdentifier"
+tag="create-mariadb-server"
+server="msdocs-mariadb-server-$randomIdentifier"
+sku="GP_Gen5_2"
+vNet="vNet-$randomIdentifier"
+vNetAddressPrefix="10.0.0.0/16"
+subnet="subnet-$randomIdentifier"
+subnetAddressPrefix="10.0.1.0/24"
+rule="rule-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MariaDB server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mariadb server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Get available service endpoints for Azure region output is JSON
+echo "List of available service endpoints for $location"
+az network vnet list-endpoint-services --location "$location"
+
+# Add Azure SQL service endpoint to a subnet while creating the virtual network
+echo "Adding service endpoint to $subnet in $vNet"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefixes $vNetAddressPrefix --location "$location"
+
+# Creates the service endpoint
+echo "Creating a service endpoint to $subnet in $vNet"
+az network vnet subnet create --resource-group $resourceGroup --name $subnet --vnet-name $vNet --address-prefix $subnetAddressPrefix --service-endpoints Microsoft.SQL
+
+# View service endpoints configured on a subnet
+echo "Viewing the service endpoint to $subnet in $vNet"
+az network vnet subnet show --resource-group $resourceGroup --name $subnet --vnet-name $vNet
+
+# Create a VNet rule on the server to secure it to the subnet
+# Note: resource group (-g) parameter is where the database exists.
+# VNet resource group if different should be specified using subnet id (URI) instead of subnet, VNet pair.
+echo "Creating a VNet rule on $server to secure it to $subnet in $vNet"
+az mariadb server vnet-rule create --name $rule --resource-group $resourceGroup --server $server --vnet-name $vNet --subnet $subnet
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mariadb/scale-mariadb-server/scale-mariadb-server.sh b/mariadb/scale-mariadb-server/scale-mariadb-server.sh
new file mode 100644
index 00000000..f027f7f3
--- /dev/null
+++ b/mariadb/scale-mariadb-server/scale-mariadb-server.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/11/2022
+
+#
+# Scale MariaDB server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+subscriptionId="$(az account show --query id -o tsv)"
+location="East US"
+resourceGroup="msdocs-mariadb-rg-$randomIdentifier"
+tag="scale-mariadb-server"
+server="msdocs-mariadb-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+scaleUpSku="GP_Gen5_4"
+scaleDownSku="GP_Gen5_2"
+storageSize="102400"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MariaDB server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mariadb server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Monitor usage metrics - CPU
+echo "Returning the CPU usage metrics for $server"
+az monitor metrics list --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMariaDB/servers/$server" --metric cpu_percent --interval PT1M
+
+# Monitor usage metrics - Storage
+echo "Returning the storage usage metrics for $server"
+az monitor metrics list --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMariaDB/servers/$server" --metric storage_used --interval PT1M
+
+# Scale up the server by provisionining more vCores within the same tier
+echo "Scaling up $server by changing the SKU to $scaleUpSku"
+az mariadb server update --resource-group $resourceGroup --name $server --sku-name $scaleUpSku
+
+# Scale down the server by provisioning fewer vCores within the same tier
+echo "Scaling down $server by changing the SKU to $scaleDownSku"
+az mariadb server update --resource-group $resourceGroup --name $server --sku-name $scaleDownSku
+
+# Scale up the server to provision a storage size of 10GB
+# Storage size cannot be reduced
+echo "Scaling up the storage size for $server to $storageSize"
+az mariadb server update --resource-group $resourceGroup --name $server --storage-size $storageSize
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mariadb/server-logs/server-logs.sh b/mariadb/server-logs/server-logs.sh
new file mode 100644
index 00000000..ea7a44c0
--- /dev/null
+++ b/mariadb/server-logs/server-logs.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/11/2022
+
+#
+# Enable server logs for MariaDB
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mariadb-rg-$randomIdentifier"
+tag="server-logs-mariadb"
+server="msdocs-mariadb-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+configurationParameter="slow_query_log"
+logValue="On"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MariaDB server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mariadb server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# List the configuration options for review
+echo "Returning the configuration options on $server"
+az mariadb server configuration list --resource-group $resourceGroup --server $server
+
+# Show the value of the slow_query_log server configuration parameter
+echo "Returning the value of the slow_query_log server configuration parameter on $server"
+az mariadb server configuration show --name $configurationParameter --resource-group $resourceGroup --server $server
+
+# Enable the slow_query_log
+echo "Enabling the slow_query_log on $server"
+az mariadb server configuration set --name $configurationParameter --resource-group $resourceGroup --server $server --value $logValue
+
+# List the available log files
+echo "Returning the list of available log files on $server"
+az mariadb server-logs list --resource-group $resourceGroup --server $server
+
+# To download log file from Azure, direct the output of the previous comment to a text file
+# "> log_files_list.txt"
+# Review the text file to find the server log file name for the desired timeframe
+# Substitute the in the script below with your server log file name
+# Creates the log file in the current command line path
+# az mariadb server-logs download --name $resourceGroup --server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/media-services/create-asset/Create-Asset.sh b/media-services/create-asset/Create-Asset.sh
new file mode 100644
index 00000000..1aa8907e
--- /dev/null
+++ b/media-services/create-asset/Create-Asset.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+amsAccountName=amsmediaaccountname
+assetName="myAsset-uniqueID"
+expiry=$(date -u +"%Y-%m-%dT%TZ" -d "+23 hours")
+
+# Create a Media Services Asset to upload content to.
+# In the v3 API, Asset names are unique ARM resource identifiers and must be unique to the account.
+# It's recommended to use short unique IDs or GUIDs to keep the names unique to the account.
+az ams asset create \
+ -n $assetName \
+ -a $amsAccountName \
+ -g $resourceGroup \
+
+# Get the SAS URLs to upload content to the container for the Asset
+# Default is 23 hour expiration, but you can adjust with the --expiry flag.
+# Max supported is 24 hours.
+az ams asset get-sas-urls \
+ -n $assetName \
+ -a $amsAccountName \
+ -g $resourceGroup \
+ --expiry $expiry \
+ --permissions ReadWrite \
+
+# Use the az storage modules to upload a local file to the container using the SAS URL from previous step.
+# If you are logged in already to the subscription with access to the storage account, you do not need to use the --sas-token at all. Just eliminate it below.
+# The container name is in the SAS URL path, and should be set with the -c option.
+# Use the -f option to point to a local file on your machine.
+# Use the -n option to name the blob in storage.
+# Use the --account-name option to point to the storage account name to use
+# Use the --sas-token option to place the SAS token after the query string from previous step.
+# NOTE that the SAS Token is only good for up to 24 hours max.
+
+# az storage blob upload \
+# -c asset-84045780-a71c-4511-801b-711b1a2e76b2 \
+# -f C:\Videos\ignite-short.mp4 \
+# -n ignite-short.mp4 \
+# --account-name mconverticlitest0003 \
+# --sas-token "?sv=2015-07-08&sr=c&sig=BvMXDCOjR%2FOP2%2FYi6lVknC4Gcq7fIun5tst8jgED7zY%3D&se=2018-04-25T00:00:00Z&sp=rwl" \
+
+echo "press [ENTER] to continue."
+read continue
\ No newline at end of file
diff --git a/media-services/create-event-grid/Create-EventGrid.sh b/media-services/create-event-grid/Create-EventGrid.sh
new file mode 100644
index 00000000..18a07242
--- /dev/null
+++ b/media-services/create-event-grid/Create-EventGrid.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+amsAccountName=amsmediaaccountname
+webhookEndpoint="https://testeventgrid.azurewebsites.net/api/GenericWebhookCSharp1?code=wZZbhwxtS///qsCHJAEv/SJMagaQDlAOCLKeBqnmC1axKipM0EayXw==&clientId=default"
+
+# Create an account level Event Grid subscription for Job State Changes.
+# ResourceId variable should be set to the full ARM resource URL for the media account.
+# Endpoint must point to a valid webhook that is enabled to respond to the EventGrid validation event.
+az eventgrid event-subscription create \
+ --name myEvent \
+ --resource-id //subscriptions/00000000-23da-4fce-b59c-f6fb9513eeeb/resourceGroups/build2018/providers/Microsoft.Media/mediaservices/build18 \
+ --included-event-types "Microsoft.Media.JobStateChange" \
+ --endpoint $webhookEndpoint \
+
+echo "press [ENTER] to continue."
+read continue
\ No newline at end of file
diff --git a/media-services/create-jobs/Create-Jobs.sh b/media-services/create-jobs/Create-Jobs.sh
new file mode 100644
index 00000000..bfa77d83
--- /dev/null
+++ b/media-services/create-jobs/Create-Jobs.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+amsAccountName=amsmediaaccountname
+outputAssetName=myOutputAsset
+transformName=audioAnalyzerTransform
+
+# NOTE: First create the Transforms in the Create-Transform.sh for these jobs to work!
+
+# Create a Media Services Asset to output the job results to.
+az ams asset create \
+ -n $outputAssetName \
+ -a $amsAccountName \
+ -g $resourceGroup \
+
+# Submit a Job to a simple encoding Transform using HTTPs URL
+az ams job start \
+ --name myFirstJob_007 \
+ --transform-name $transformName \
+ --base-uri 'https://nimbuscdn-nimbuspm.streaming.mediaservices.windows.net/00000000-b215-4409-80af-529c3e853622/' \
+ --files 'Ignite-short.mp4' \
+ --output-asset $outputAssetName \
+ -a $amsAccountName \
+ -g $resourceGroup \
+
+echo "press [ENTER] to continue."
+read continue
diff --git a/media-services/create-transform/Create-Transform.sh b/media-services/create-transform/Create-Transform.sh
new file mode 100644
index 00000000..2c32a480
--- /dev/null
+++ b/media-services/create-transform/Create-Transform.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+amsAccountName=amsmediaaccountname
+
+# Create a simple Transform for Adaptive Bitrate Encoding
+az ams transform create \
+ --name myFirstTransform \
+ --preset AdaptiveStreaming \
+ --description 'a simple Transform for Adaptive Bitrate Encoding' \
+ -g $resourceGroup \
+ -a $amsAccountName \
+
+ # Create a Transform for Video Analyer Preset
+az ams transform create \
+ --name videoAnalyzerTransform \
+ --preset VideoAnalyzer \
+ -g $resourceGroup \
+ -a $amsAccountName \
+
+ # Create a Transform for Audio Analzyer Preset
+az ams transform create \
+ --name audioAnalyzerTransform \
+ --preset AudioAnalyzer \
+ -g $resourceGroup \
+ -a $amsAccountName \
+
+# List all the Transforms in an account
+az ams transform list -a $amsAccountName -g $resourceGroup
+
+echo "press [ENTER] to continue."
+read continue
diff --git a/media-services/media-services-create-account/Create-Account.sh b/media-services/media-services-create-account/Create-Account.sh
new file mode 100644
index 00000000..06b8daf2
--- /dev/null
+++ b/media-services/media-services-create-account/Create-Account.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+storageName=amsstorename
+amsAccountName=amsmediaaccountname
+amsSPName=mediaserviceprincipal
+amsSPPassword=mediasppassword
+
+# Create a resource resourceGroupName
+az group create \
+ --name $resourceGroup \
+ --location "westcentralus"
+
+# Create an azure storage account, General Purpose v2, Standard RAGRS
+az storage account create \
+ --name $storageName \
+ --kind StorageV2 \
+ --sku Standard_RAGRS \
+ --location "westcentralus" \
+ --resource-group $resourceGroup
+
+# Create an azure media service account
+az ams account create \
+ --name $amsAccountName \
+ --resource-group $resourceGroup \
+ --storage-account $storageName \
+ --location "westcentralus"
+
+# Create a service principal with password and configure its access to an Azure Media Services account.
+az ams account sp create \
+ --account-name $amsAccountName \
+ --name $amsSPName \
+ --password $amsSPPassword \
+ --resource-group $resourceGroup \
+ --role Owner \
+ --xml \
+ --years 2 \
+
+echo "press [ENTER] to continue."
+read continue
diff --git a/media-services/media-services-create-account/media-services-create-account.sh b/media-services/media-services-create-account/media-services-create-account.sh
new file mode 100644
index 00000000..d19fe235
--- /dev/null
+++ b/media-services/media-services-create-account/media-services-create-account.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+resourceGroup=amsResourceGroup
+storageName=amsstorename
+amsLocation=westus2
+amsAccountName=amsmediaaccountname
+amsSPName=mediaserviceprincipal
+amsSPPassword=mediasppassword
+
+# Create a resource resourceGroupName
+az group create \
+ --name $resourceGroup \
+ --location $amsLocation
+
+# Create an azure storage account
+az storage account create \
+ --name $storageName \
+ --kind StorageV2 \
+ --sku Standard_RAGRS \
+ --location amsLocation \
+ --resource-group $resourceGroup
+
+# Create an azure media service account
+az ams account create \
+ --name $amsAccountName \
+ --resource-group $resourceGroup \
+ --storage-account $storageName \
+ --location $amsLocation
+
+# Create a service principal with password and configure its access to an Azure Media Services account.
+az ams account sp create \
+ --account-name $amsAccountName \
+ --name $amsSPName \
+ --resource-group $resourceGroup \
+ --password $amsSPPassword \
+ --role Owner
diff --git a/media-services/publish-asset/Publish-Asset.sh b/media-services/publish-asset/Publish-Asset.sh
new file mode 100644
index 00000000..57e82f7a
--- /dev/null
+++ b/media-services/publish-asset/Publish-Asset.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# WARNING: This shell script requires Python 3 to be installed to parse JSON.
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+amsAccountName=amsmediaaccountname
+assetName="myAsset-uniqueID"
+locatorName="myStreamingLocator"
+streamingPolicyName="Predefined_DownloadAndClearStreaming"
+#contentPolicyName=""
+
+# Delete the locator if it already exists
+az ams streaming locator delete \
+ -a $amsAccountName \
+ -g $resourceGroup \
+ -n $locatorName \
+
+# Create a new Streaming Locator. Modify the assetName variable to point to the Asset you want to publish
+# This uses the predefined Clear Streaming Only policy, which allows for unencypted deliver over HLS, Smooth and DASH protocols.
+az ams streaming locator create \
+ -a $amsAccountName \
+ -g $resourceGroup \
+ --asset-name $assetName \
+ -n $locatorName \
+ --streaming-policy-name $streamingPolicyName \
+ #--end-time 2100-10-10T00:00:00Z \
+ #--start-time 2018-04-28T00:00:00Z \
+ #--content-policy-name $contentPolicyName \
+
+# List the Streaming Endpoints on the account. If this is a new account it only has a 'default' endpoint, which may be stopped.
+# To stream, you must first Start a Streaming Endpoint on your account.
+# This next commmand lists the Streaming Endpoints, and gets the value of the "hostname" property for the 'default' endpoint to be used when building
+# the complete Streaming or download URL from the locator get-paths method following this.
+# NOTE: This command requires Python 3.5 to be installed.
+hostName=$(az ams streaming endpoint list \
+ -a $amsAccountName \
+ -g $resourceGroup | \
+ python -c "import sys, json; print(json.load(sys.stdin)[0]['hostName'])")
+
+echo -e "\n"
+echo -e "Default hostname: https://"$hostName
+
+# List the Streming URLs relative paths for the new locator. You must append your Streaming Endpoint "hostname" path to these to resolve the full URL.
+# Note that the asset must have an .ismc and be encoded for Adaptive streaming in order to get Streaming URLs back. You can get download paths for any content type.
+paths=$(az ams streaming locator get-paths \
+ -a $amsAccountName \
+ -g $resourceGroup \
+ -n $locatorName )
+
+downloadPaths=$(echo $paths | \
+ python -c "import sys, json; print(json.load(sys.stdin)['downloadPaths'])" )
+
+streamingPaths=$(echo $paths |\
+ python -c "import sys, json; print(json.load(sys.stdin)['streamingPaths'])" )
+
+echo -e "\n"
+echo "DownloadPaths:"
+echo $downloadPaths
+echo -e "\n"
+echo "StreamingPaths:"
+echo $streamingPaths
+
+echo "press [ENTER] to continue."
+read continue
\ No newline at end of file
diff --git a/media-services/reset-account-credentials/Reset-Account-Credentials.sh b/media-services/reset-account-credentials/Reset-Account-Credentials.sh
new file mode 100644
index 00000000..ec43c96a
--- /dev/null
+++ b/media-services/reset-account-credentials/Reset-Account-Credentials.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+resourceGroup=amsResourceGroup
+amsAccountName=amsmediaaccountname
+amsSPName=build2018demo
+
+# Reset your account credentials and get the app.config settings back
+az ams account sp reset-credentials \
+ --account-name $amsAccountName \
+ --name $amsSPName \
+ --resource-group $resourceGroup \
+ --role Owner \
+ --xml \
+ --years 2 \
+
+echo "press [ENTER] to continue."
+read continue
\ No newline at end of file
diff --git a/media-services/upload-file-asset/UploadFile-Asset.sh b/media-services/upload-file-asset/UploadFile-Asset.sh
new file mode 100644
index 00000000..42f84713
--- /dev/null
+++ b/media-services/upload-file-asset/UploadFile-Asset.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Update the following variables for your own settings:
+storageAccountName=build2018storage
+assetContainer="asset-4c834446-7e55-4760-9a25-f2d4fb1f4657"
+localFile="..\Media\ignite-short.mp4"
+blobName="ignite-short.mp4"
+assetName="myAsset-uniqueID"
+sasToken="?sv=2015-07-08&sr=c&sig=u1uy9OIeXnZUEN62hE0bDgg%2FPXYgRDNGnQxE%2BSi51dM%3D&se=2018-04-29T18:42:02Z&sp=rwl"
+
+# Use the az storage modules to upload a local file to the container using the SAS URL from previous step.
+# If you are logged in already to the subscription with access to the storage account, you do not need to use the --sas-token at all. Just eliminate it below.
+# The container name is in the SAS URL path, and should be set with the -c option.
+# Use the -f option to point to a local file on your machine.
+# Use the -n option to name the blob in storage.
+# Use the --account-name option to point to the storage account name to use
+# Use the --sas-token option to place the SAS token after the query string from previous step.
+# NOTE that the SAS Token is only good for up to 24 hours max.
+#
+az storage blob upload \
+ -c $assetContainer \
+ -f $localFile \
+ -n $blobName \
+ --account-name $storageAccountName \
+ --sas-token $sasToken \
+
+echo "press [ENTER] to continue."
+read continue
\ No newline at end of file
diff --git a/mysql/backup-restore-pitr/backup-restore.sh b/mysql/backup-restore-pitr/backup-restore.sh
index 620415a3..af79aa5f 100644
--- a/mysql/backup-restore-pitr/backup-restore.sh
+++ b/mysql/backup-restore-pitr/backup-restore.sh
@@ -1,25 +1,46 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 2/11/2022
+
+#
+# Restore an Azure Database for MySQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="backup-restore-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+restoreServer="restore-server$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
# Create a resource group
-az group create \
---name myresource \
---location westus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a MySQL server in the resource group
# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
-# Substitute the with your own value.
-az mysql server create \
---name mysqlserver4demo \
---resource-group myresource \
---location westus \
---admin-user myadmin \
---admin-password \
---performance-tier Basic \
---compute-units 50
+echo "Creating $server in $location..."
+az mysql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Sleeping commands to wait long enough for automatic backup to be created
+echo "Sleeping..."
+sleep 10m
# Restore a server from backup to a new server
-az mysql server restore \
---name mysqlserver4demo-new \
---resource-group myresource \
---restore-point-in-time "2017-10-13T13:10:00Z" \
---source-server mysqlserver4demo
\ No newline at end of file
+# To specify a specific point-in-time (in UTC) to restore from, use the ISO8601 format:
+# restorePoint=“2021-07-09T13:10:00Z”
+restorePoint=$(date +%s)
+restorePoint=$(expr $restorePoint - 60)
+restorePoint=$(date -d @$restorePoint +"%Y-%m-%dT%T")
+echo $restorePoint
+
+echo "Restoring $restoreServer"
+az mysql server restore --name $restoreServer --resource-group $resourceGroup --restore-point-in-time $restorePoint --source-server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/backup-restore-pitr/delete-mysql.sh b/mysql/backup-restore-pitr/delete-mysql.sh
deleted file mode 100644
index e694e63d..00000000
--- a/mysql/backup-restore-pitr/delete-mysql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresource
diff --git a/mysql/change-server-configurations/change-server-configurations.sh b/mysql/change-server-configurations/change-server-configurations.sh
index f515725c..16028164 100644
--- a/mysql/change-server-configurations/change-server-configurations.sh
+++ b/mysql/change-server-configurations/change-server-configurations.sh
@@ -1,36 +1,41 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# List and update configurations of an Azure Database for MySQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="change-server-cofigurations-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
# Create a resource group
-az group create \
---name myresource \
---location westus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a MySQL server in the resource group
# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
-# Substitute the with your own value.
-az mysql server create \
---name mysqlserver4demo \
---resource-group myresource \
---location westus \
---admin-user myadmin \
---admin-password \
---performance-tier Basic \
---compute-units 50
+echo "Creating $server in $location..."
+az mysql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
# Display all available configurations with valid values of an Azure Database for MySQL server
-az mysql server configuration list \
---resource-group myresource \
---server-name mysqlserver4demo
+az mysql server configuration list --resource-group $resourceGroup --server-name $server
# Set value of *innodb_lock_wait_timeout*
-az mysql server configuration set \
---resource-group myresource \
---server-name mysqlserver4demo \
---name innodb_lock_wait_timeout \
---value 120
+echo "Setting value of the innodb_lock_wait_timeout setting on $server"
+az mysql server configuration set --resource-group $resourceGroup --server-name $server --name innodb_lock_wait_timeout --value 120
# Check the value of *innodb_lock_wait_timeout*
-az mysql server configuration show \
---resource-group myresource \
---server-name mysqlserver4demo \
---name innodb_lock_wait_timeout
\ No newline at end of file
+echo "Checking the value of the innodb_lock_wait_timeout setting on $server"
+az mysql server configuration show --resource-group $resourceGroup --server-name $server --name innodb_lock_wait_timeout
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/change-server-configurations/delete-mysql.sh b/mysql/change-server-configurations/delete-mysql.sh
deleted file mode 100644
index e694e63d..00000000
--- a/mysql/change-server-configurations/delete-mysql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresource
diff --git a/mysql/create-mysql-server-and-firewall-rule/create-mysql-server-and-firewall-rule.sh b/mysql/create-mysql-server-and-firewall-rule/create-mysql-server-and-firewall-rule.sh
index 25302d5f..46425664 100644
--- a/mysql/create-mysql-server-and-firewall-rule/create-mysql-server-and-firewall-rule.sh
+++ b/mysql/create-mysql-server-and-firewall-rule/create-mysql-server-and-firewall-rule.sh
@@ -1,27 +1,38 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Create a MySQL server and configure a firewall rule
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="create-mysql-server-and-firewall-rule"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+# Specify appropriate IP address values for your environment
+# to limit / allow access to the MySQL server
+startIp=0.0.0.0
+endIp=0.0.0.0
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
# Create a resource group
-az group create \
---name myresource \
---location westus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a MySQL server in the resource group
# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
-# Substitute the with your own value.
-az mysql server create \
---name mysqlserver4demo \
---resource-group myresource \
---location westus \
---admin-user myadmin \
---admin-password \
---performance-tier Basic \
---compute-units 50
+echo "Creating $server in $location..."
+az mysql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Configure a firewall rule for the server
+echo "Configuring a firewall rule for $server for the IP address range of $startIp to $endIp"
+az mysql server firewall-rule create --resource-group $resourceGroup --server $server --name AllowIps --start-ip-address $startIp --end-ip-address $endIp
+#
-# Configure a firewall rule for the server
-# The ip address range that you want to allow to access your server
-az mysql server firewall-rule create \
---resource-group myresource \
---server mysqlserver4demo \
---name AllowIps \
---start-ip-address 0.0.0.0 \
---end-ip-address 255.255.255.255
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/create-mysql-server-and-firewall-rule/delete-mysql.sh b/mysql/create-mysql-server-and-firewall-rule/delete-mysql.sh
deleted file mode 100644
index e694e63d..00000000
--- a/mysql/create-mysql-server-and-firewall-rule/delete-mysql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresource
diff --git a/mysql/create-mysql-server-vnet/create-mysql-server.sh b/mysql/create-mysql-server-vnet/create-mysql-server.sh
new file mode 100644
index 00000000..78a368bc
--- /dev/null
+++ b/mysql/create-mysql-server-vnet/create-mysql-server.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Create and manage Azure Database for MySQL VNet service endpoints
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="create-mysql-server"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+vNet="vNet-$randomIdentifier"
+vNetAddressPrefix="10.0.0.0/16"
+subnet="subnet-$randomIdentifier"
+subnetAddressPrefix="10.0.1.0/24"
+rule="rule-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mysql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Get available service endpoints for Azure region output in JSON
+echo "List of available service endpoints for $location"
+az network vnet list-endpoint-services --location "$location"
+
+# Create the virtual network
+echo "Creating $vNet"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefixes $vNetAddressPrefix --location "$location"
+
+# Creates the subnet
+echo "Creating $subnet in $vNet"
+az network vnet subnet create --resource-group $resourceGroup --name $subnet --vnet-name $vNet --address-prefix $subnetAddressPrefix --service-endpoints Microsoft.SQL
+
+# View service endpoints configured on a subnet
+echo "Viewing the service endpoint to $subnet in $vNet"
+az network vnet subnet show --resource-group $resourceGroup --name $subnet --vnet-name $vNet
+
+# Create a VNet rule on the server to secure it to the subnet
+# Note: resource group (-g) parameter is where the database exists.
+# VNet resource group if different should be specified using subnet id (URI) instead of subnet, VNet pair.
+echo "Creating a VNet rule on $server to secure it to $subnet in $vNet"
+az mysql server vnet-rule create --name $rule --resource-group $resourceGroup --server $server --vnet-name $vNet --subnet $subnet
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/backup-restore/restore-server.sh b/mysql/flexible-server/backup-restore/restore-server.sh
new file mode 100644
index 00000000..660febea
--- /dev/null
+++ b/mysql/flexible-server/backup-restore/restore-server.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/11/2022
+
+#
+# Perform point-in-time-restore of a source server to a new server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="restore-server-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+restoreServer="restore-server$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Sleeping commands to wait long enough for automatic backup to be created
+echo "Sleeping..."
+sleep 15m
+
+# Restore a server from backup to a new server
+# To specify a specific point-in-time (in UTC) to restore from, use the ISO8601 format:
+# restorePoint=“2021-07-09T13:10:00Z”
+restorePoint=$(date +%s)
+restorePoint=$(expr $restorePoint - 60)
+restorePoint=$(date -d @$restorePoint +"%Y-%m-%dT%T")
+echo $restorePoint
+
+echo "Restoring to $restoreServer"
+az mysql flexible-server restore --name $restoreServer --resource-group $resourceGroup --restore-time $restorePoint --source-server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/configure-logs/configure-audit-logs.sh b/mysql/flexible-server/configure-logs/configure-audit-logs.sh
new file mode 100644
index 00000000..3f2f3b00
--- /dev/null
+++ b/mysql/flexible-server/configure-logs/configure-audit-logs.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Configure audit logs on Azure Database for MySQL - Flexible Server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="configure-audit-logs-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Enable audit logs
+echo "Enabling audit logs"
+az mysql flexible-server parameter set --resource-group $resourceGroup --server-name $server --name audit_log_enabled --value ON
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/configure-logs/configure-slow-query-logs.sh b/mysql/flexible-server/configure-logs/configure-slow-query-logs.sh
new file mode 100644
index 00000000..fc570c50
--- /dev/null
+++ b/mysql/flexible-server/configure-logs/configure-slow-query-logs.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Configure slow query logs on Azure Database for MySQL - Flexible Server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="slow-query-logs-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Enable slow query logs
+echo "Enabling slow query logs"
+az mysql flexible-server parameter set --name slow_query_log --resource-group $resourceGroup --server-name $server --value ON
+
+# Set long_query_time time to 15 seconds
+# This setting will log all queries executing for more than 15 sec. Please adjust this threshold based on your definition for slow queries
+echo "Setting long query time to 15 seconds"
+az mysql flexible-server parameter set --name long_query_time --resource-group $resourceGroup --server $server --value 15
+
+# Allow slow administrative statements (ex. ALTER_TABLE, ANALYZE_TABLE) to be logged.
+echo "Allow logging of slow administrative statements"
+az mysql flexible-server parameter set --resource-group $resourceGroup --server-name $server --name log_slow_admin_statements --value ON
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/create-server-private-access/create-connect-server-in-vnet.sh b/mysql/flexible-server/create-server-private-access/create-connect-server-in-vnet.sh
new file mode 100644
index 00000000..5e1808da
--- /dev/null
+++ b/mysql/flexible-server/create-server-private-access/create-connect-server-in-vnet.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Create an Azure Database for MySQL - Flexible Server in a VNet
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="create-connect-server-in-vnet-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="Standard_D2ds_v4"
+tier="GeneralPurpose"
+storageSize="64"
+storageAutoGrow="Enabled"
+vNet="vNet-$randomIdentifier"
+vNetAddressPrefix="155.5.0.0/24"
+mySqlSubnet="msdocs-subnet-mysql-$randomIdentifier"
+mySqlSubnetAddressPrefix="155.5.0.0/28"
+rule="msdocs-rule-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+image="Ubuntu2204"
+vm="msdocs-vm-$randomIdentifier"
+vmSubnet="msdocs-subnet-vm-$randomIdentifier"
+vmSubnetAddressPrefix="155.5.0.48/28"
+dns="msdocsDNS.private.mysql.database.azure.com"
+ipSku="basic"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create MySQL server in a VNET
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Get available service endpoints for Azure region output in JSON
+echo "List of available service endpoints for $location"
+az network vnet list-endpoint-services --location "$location"
+
+# Create the virtual network
+echo "Creating $vNet"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefixes $vNetAddressPrefix --location "$location"
+
+# Creates the mySqlSubnet
+echo "Creating $mySqlSubnet in $vNet"
+az network vnet subnet create --resource-group $resourceGroup --name $mySqlSubnet --vnet-name $vNet --address-prefix $mySqlSubnetAddressPrefix --service-endpoints Microsoft.SQL
+
+# View service endpoints configured on a subnet
+echo "Viewing the service endpoint to $mySqlSubnet in $vNet"
+az network vnet subnet show --resource-group $resourceGroup --name $mySqlSubnet --vnet-name $vNet
+
+# Create private DNS zone
+echo "Creating $dns"
+az network private-dns zone create -g $resourceGroup -n $dns
+
+# OPTIONAL : View all SKUs for Flexible Server
+# az mysql flexible-server list-skus --location "$location"
+
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server within $mySqlSubnet"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --sku-name $sku --tier $tier --storage-size $storageSize --storage-auto-grow $storageAutoGrow --admin-user $login --admin-password $password --vnet $vNet --subnet $mySqlSubnet --private-dns-zone $dns
+
+# Connect to the MySQL server from a VM in the same VNET
+
+# Create a subnet for the virtual machine within the virtual network
+echo "Creating $vmSubnet within $vNet"
+az network vnet subnet create --resource-group $resourceGroup --vnet-name $vNet --name $vmSubnet --address-prefixes $vmSubnetAddressPrefix
+
+# Create a VM within the VNET to connect to MySQL Flex Server
+echo "Creating $vm within $vmSubnet"
+az vm create --resource-group $resourceGroup --name $vm --location "$location" --image $image --admin-username $login --generate-ssh-keys --vnet-name $vNet --subnet $vmSubnet --public-ip-sku $ipSku
+
+# Open port 80 for web traffic
+echo "Opening port 80 for web traffic"
+az vm open-port --port 80 --resource-group $resourceGroup --name $vm
+
+# Follow steps in the parent article to test connectivity to the MySQL server from the VM
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/create-server-public-access/create-connect-burstable-server-public-access.sh b/mysql/flexible-server/create-server-public-access/create-connect-burstable-server-public-access.sh
new file mode 100644
index 00000000..98f0e194
--- /dev/null
+++ b/mysql/flexible-server/create-server-public-access/create-connect-burstable-server-public-access.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/11/2022
+
+#
+# Create an Azure Database for MySQL - Flexible Server Burstable B1ms instance
+# and configure Public Access connectivity method
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="create-connect-burstable-server-public-access-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Connect to server in interactive mode
+az mysql flexible-server connect --name $server --admin-user $login --admin-password $password --interactive
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/high-availability/same-zone-ha.sh b/mysql/flexible-server/high-availability/same-zone-ha.sh
new file mode 100644
index 00000000..9906ad3c
--- /dev/null
+++ b/mysql/flexible-server/high-availability/same-zone-ha.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Configure same-zone high availability
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="same-zone-ha-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="Standard_D2ds_v4"
+tier="GeneralPurpose"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Enable Same-zone HA while creating a MySQL Flexible server in the resource group
+# HA is not available for burstable tier
+# HA cannot be enabled post create
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup \
+--location "$location" --sku-name $sku --tier $tier --admin-user $login --admin-password $password \
+--public-access $ipAddress --high-availability SameZone
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Disable Same-zone HA
+echo "Disabling same-zone HA"
+az mysql flexible-server update --resource-group $resourceGroup --name $server --high-availability Disabled
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/high-availability/zone-redundant-ha.sh b/mysql/flexible-server/high-availability/zone-redundant-ha.sh
new file mode 100644
index 00000000..5594c6cd
--- /dev/null
+++ b/mysql/flexible-server/high-availability/zone-redundant-ha.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Configure zone-redundant high availability
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="zone-redundant-ha-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="Standard_D2ds_v4"
+tier="GeneralPurpose"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+primaryZone="1"
+standbyZone="2"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Enable Zone-redundant HA while creating a MySQL Flexible server in the resource group
+# HA is not available for burstable tier
+# Zone and standby-zone parameters are optional
+# HA cannot be enabled post create
+
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --sku-name $sku --tier $tier --admin-user $login --admin-password $password --public-access $ipAddress --high-availability ZoneRedundant --zone $primaryZone --standby-zone $standbyZone
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Disable Zone-redundant HA
+echo "Disabling zone redundant HA"
+az mysql flexible-server update --resource-group $resourceGroup --name $server --high-availability Disabled
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/manage-server/change-server-parameters.sh b/mysql/flexible-server/manage-server/change-server-parameters.sh
new file mode 100644
index 00000000..4c457322
--- /dev/null
+++ b/mysql/flexible-server/manage-server/change-server-parameters.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Change server parameters for Azure Database for MySQL - Flexible Server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="configure-audit-logs-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# List all MySQL - Flexible Server parameters with their values and parameter descriptions
+echo "List parameters and values"
+az mysql flexible-server parameter list --resource-group $resourceGroup --server-name $server
+
+# Set value of max_connections parameter
+echo "Set maximum connections"
+az mysql flexible-server parameter set --resource-group $resourceGroup --server-name $server --name max_connections --value 250
+
+# Check value of max_connections paramater
+echo "Check maximum connections"
+az mysql flexible-server parameter show --resource-group $resourceGroup --server-name $server --name max_connections
+
+# Set value of max_connections parameter back to default
+echo "Set maximum connnections to default"
+az mysql flexible-server parameter set --resource-group $resourceGroup --server-name $server --name max_connections
+
+# Set global level time zone
+echo "Set time zone"
+az mysql flexible-server parameter set --resource-group $resourceGroup --server-name $server --name time_zone --value "+02:00"
+
+# Check global level time zone
+echo "Check time zone"
+az mysql flexible-server parameter show --resource-group $resourceGroup --server-name $server --name time_zone
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/manage-server/restart-start-stop.sh b/mysql/flexible-server/manage-server/restart-start-stop.sh
new file mode 100644
index 00000000..631348fc
--- /dev/null
+++ b/mysql/flexible-server/manage-server/restart-start-stop.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Create a server, perform restart / start / stop operations
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="restart-start-stop-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible Server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Stop the running server
+echo "Stopping $server"
+az mysql flexible-server stop --resource-group $resourceGroup --name $server
+
+# Start the stopped server
+echo "Starting $server"
+az mysql flexible-server start --resource-group $resourceGroup --name $server
+
+# Restart the server
+echo "Restarting $server"
+az mysql flexible-server restart --resource-group $resourceGroup --name $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/monitor-and-scale/monitor-and-scale.sh b/mysql/flexible-server/monitor-and-scale/monitor-and-scale.sh
new file mode 100644
index 00000000..1e6e4ac2
--- /dev/null
+++ b/mysql/flexible-server/monitor-and-scale/monitor-and-scale.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Monitor your MySQLFlexible Server and scale compute, storage, and IOPS
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+subscriptionId="$(az account show --query id -o tsv)"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="monitor-and-scale-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Monitor CPU percent, storage usage and IO percent
+
+# Monitor CPU Usage metric
+echo "Monitor CPU usage"
+az monitor metrics list \
+ --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMySQL/flexibleservers/$server" \
+ --metric cpu_percent \
+ --interval PT1M
+
+# Monitor Storage usage metric
+echo "Monitor storage usage"
+az monitor metrics list \
+ --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMySQL/flexibleservers/$server" \
+ --metric storage_used \
+ --interval PT1M
+
+# Monitor IO Percent
+echo "Monitor I/O percent"
+az monitor metrics list \
+ --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMySQL/flexibleservers/$server" \
+ --metric io_consumption_percent \
+ --interval PT1M
+
+# Scale up the server by provisionining to higher tier from Burstable to General purpose 4vcore
+echo "Scale up to Standard_D4ds_v4"
+az mysql flexible-server update \
+ --resource-group $resourceGroup \
+ --name $server \
+ --sku-name Standard_D4ds_v4 \
+ --tier GeneralPurpose
+
+# Scale down to by provisioning to General purpose 2vcore within the same tier
+echo "Scale down to Standard_D2ds_v4"
+az mysql flexible-server update \
+ --resource-group $resourceGroup \
+ --name $server \
+ --sku-name Standard_D2ds_v4
+
+# Scale up the server to provision a storage size of 64GB. Note storage size cannot be reduced.
+echo "Scale up storage to 64 GB"
+az mysql flexible-server update \
+ --resource-group $resourceGroup \
+ --name $server \
+ --storage-size 64
+
+# Scale IOPS
+echo "Scale IOPS to 550"
+az mysql flexible-server update \
+ --resource-group $resourceGroup \
+ --name $server \
+ --iops 550
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/flexible-server/read-replicas/create-manage-read-replicas.sh b/mysql/flexible-server/read-replicas/create-manage-read-replicas.sh
new file mode 100644
index 00000000..dcac43a8
--- /dev/null
+++ b/mysql/flexible-server/read-replicas/create-manage-read-replicas.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Create and manage MySQL - Flexible Server read replicas
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+subscriptionId="$(az account show --query id -o tsv)"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="monitor-and-scale-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+ipAddress="None"
+sku="Standard_D2ds_v4"
+tier="GeneralPurpose"
+storageSize="64"
+replica="msdocs-replica-mysql-$randomIdentifier" # Substitute with preferred name for the replica server.
+
+# Specifying an IP address of 0.0.0.0 allows public access from any resources
+# deployed within Azure to access your server. Setting it to "None" sets the server
+# in public access mode but does not create a firewall rule.
+# For your public IP address, https://whatismyipaddress.com
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a MySQL Flexible server in the resource group
+echo "Creating $server"
+az mysql flexible-server create --name $server --resource-group $resourceGroup --location "$location" --sku-name $sku --tier $tier --storage-size $storageSize --admin-user $login --admin-password $password --public-access $ipAddress
+
+# Optional: Add firewall rule to connect from all Azure services
+# To limit to a specific IP address or address range, change start-ip-address and end-ip-address
+echo "Adding firewall for IP address range"
+az mysql flexible-server firewall-rule create --name $server --resource-group $resourceGroup --rule-name AllowAzureIPs --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+# Create Replica Server
+echo "Creating $replica"
+az mysql flexible-server replica create --replica-name $replica --source-server $server --resource-group $resourceGroup
+
+# List all read replicas for the source server
+echo "List replicas on $server"
+az mysql flexible-server replica list --source-server $server --resource-group $resourceGroup
+
+# Stop replication to a read replica and make it a read/write server.
+echo "Stop replication to $replica"
+az mysql flexible-server replica stop-replication --resource-group $resourceGroup --name $replica --yes
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/scale-mysql-server/delete-mysql.sh b/mysql/scale-mysql-server/delete-mysql.sh
deleted file mode 100644
index e694e63d..00000000
--- a/mysql/scale-mysql-server/delete-mysql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresource
diff --git a/mysql/scale-mysql-server/scale-mysql-server.sh b/mysql/scale-mysql-server/scale-mysql-server.sh
index b74eba41..15574f22 100644
--- a/mysql/scale-mysql-server/scale-mysql-server.sh
+++ b/mysql/scale-mysql-server/scale-mysql-server.sh
@@ -1,36 +1,55 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Monitor and scale an Azure Database for MySQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+subscriptionId="$(az account show --query id -o tsv)"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="scale-mysql-server"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+scaleUpSku="GP_Gen5_4"
+scaleDownSku="GP_Gen5_2"
+storageSize="102400"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
# Create a resource group
-az group create \
---name myresource \
---location westus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a MySQL server in the resource group
# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
-# Substitute the with your own value.
-az mysql server create \
---name mysqlserver4demo \
---resource-group myresource \
---location westus \
---admin-user myadmin \
---admin-password \
---performance-tier Basic \
---compute-units 50
-
-# Monitor usage metrics - Compute
-az monitor metrics list \
---resource-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresource/providers/Microsoft.DBforMySQL/servers/mysqlserver4demo" \
---metric-names compute_consumption_percent \
---time-grain PT1M
+echo "Creating $server in $location..."
+az mysql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Monitor usage metrics - CPU
+echo "Returning the CPU usage metrics for $server"
+az monitor metrics list --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMySQL/servers/$server" --metric cpu_percent --interval PT1M
# Monitor usage metrics - Storage
-az monitor metrics list \
---resource-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresource/providers/Microsoft.DBforMySQL/servers/mysqlserver4demo" \
---metric-names storage_used \
---time-grain PT1M
-
-# Scale up the server to provision more Compute Units within the same Tier
-az mysql server update \
---resource-group myresource \
---name mysqlserver4demo \
---compute-units 100
+echo "Returning the storage usage metrics for $server"
+az monitor metrics list --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforMySQL/servers/$server" --metric storage_used --interval PT1M
+
+# Scale up the server by provisionining more vCores within the same tier
+echo "Scaling up $server by changing the SKU to $scaleUpSku"
+az mysql server update --resource-group $resourceGroup --name $server --sku-name $scaleUpSku
+
+# Scale down the server by provisioning fewer vCores within the same tier
+echo "Scaling down $server by changing the SKU to $scaleDownSku"
+az mysql server update --resource-group $resourceGroup --name $server --sku-name $scaleDownSku
+
+# Scale up the server to provision a storage size of 10GB
+# Storage size cannot be reduced
+echo "Scaling up the storage size for $server to $storageSize"
+az mysql server update --resource-group $resourceGroup --name $server --storage-size $storageSize
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/mysql/server-logs/delete-mysql.sh b/mysql/server-logs/delete-mysql.sh
deleted file mode 100644
index e694e63d..00000000
--- a/mysql/server-logs/delete-mysql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresource
diff --git a/mysql/server-logs/server-logs.sh b/mysql/server-logs/server-logs.sh
index d8f6f604..5aa9b7d9 100644
--- a/mysql/server-logs/server-logs.sh
+++ b/mysql/server-logs/server-logs.sh
@@ -1,57 +1,55 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 2/9/2022
+
+#
+# Enable and download server slow query logs of an Azure Database for MySQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-mysql-rg-$randomIdentifier"
+tag="server-logs-mysql"
+server="msdocs-mysql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+configurationParameter="slow_query_log"
+logValue="On"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
# Create a resource group
-az group create \
---name myresource \
---location westus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a MySQL server in the resource group
-# Name of a server maps to DNS name and is thus required to be globally unique in Azure
-# Substitute the with your own value
-az mysql server create \
---name mysqlserver4demo \
---resource-group myresource \
---location westus \
---admin-user myadmin \
---admin-password \
---performance-tier Basic \
---compute-units 50
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az mysql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
# List the configuration options for review
-az mysql server configuration list \
---resource-group myresource \
---server mysqlserver4demo
-
-# Turn on slow query log
-az mysql server configuration set \
---name slow_query_log \
---resource-group myresource \
---server mysqlserver4demo \
---value ON
-
-# Set long query time to 10 sec
-az mysql server configuration set \
---name long_query_time \
---resource-group myresource \
---server mysqlserver4demo \
---value 10
-
-# Turn off the logging of slow admin statement
-az mysql server configuration set \
---name log_slow_admin_statements \
---resource-group myresource \
---server mysqlserver4demo \
---value OFF
-
-# List the available log files and direct to a text file
-az mysql server-logs list \
---resource-group myresource \
---server mysqlserver4demo > log_files_list.txt
-
-# Download logs to your environment
-# Use "cat log_files_list.txt" to find the server log file name
-# Substitute the with your server log file name
-az mysql server-logs download \
---name \
---resource-group myresource \
---server mysqlserver4demo
+echo "Returning the configuration options on $server"
+az mysql server configuration list --resource-group $resourceGroup --server $server
+
+# Show the value of the slow_query_log server configuration parameter
+echo "Returning the value of the slow_query_log server configuration parameter on $server"
+az mysql server configuration show --name $configurationParameter --resource-group $resourceGroup --server $server
+
+# Enable the slow_query_log
+echo "Enabling the slow_query_log on $server"
+az mysql server configuration set --name $configurationParameter --resource-group $resourceGroup --server $server --value $logValue
+
+# List the available log files
+echo "Returning the list of available log files on $server"
+az mysql server-logs list --resource-group $resourceGroup --server $server
+
+# To download log file from Azure, direct the output of the previous comment to a text file
+# "> log_files_list.txt"
+# Review the text file to find the server log file name for the desired timeframe
+# Substitute the in the script below with your server log file name
+# Creates the log file in the current command line path
+# az mysql server-logs download --name $resourceGroup --server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/postgresql/backup-restore/backup-restore.sh b/postgresql/backup-restore/backup-restore.sh
new file mode 100644
index 00000000..4c818c12
--- /dev/null
+++ b/postgresql/backup-restore/backup-restore.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/11/2022
+
+#
+# Restore an Azure Database for PostgreSQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-postgresql-rg-$randomIdentifier"
+tag="backup-restore-postgresql"
+server="msdocs-postgresql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+restoreServer="restore-server$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a PostgreSQL server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az postgres server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Sleeping commands to wait long enough for automatic backup to be created
+echo "Sleeping..."
+sleep 10m
+
+# Restore a server from backup to a new server
+# To specify a specific point-in-time (in UTC) to restore from, use the ISO8601 format:
+# restorePoint=“2021-07-09T13:10:00Z”
+restorePoint=$(date +%s)
+restorePoint=$(expr $restorePoint - 60)
+restorePoint=$(date -d @$restorePoint +"%Y-%m-%dT%T")
+echo $restorePoint
+
+echo "Restoring $restoreServer"
+az postgres server restore --name $restoreServer --resource-group $resourceGroup --restore-point-in-time $restorePoint --source-server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/postgresql/change-server-configurations/change-server-configurations.sh b/postgresql/change-server-configurations/change-server-configurations.sh
new file mode 100644
index 00000000..b9864653
--- /dev/null
+++ b/postgresql/change-server-configurations/change-server-configurations.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/13/2022
+
+#
+# List and update configurations of an Azure Database for PostgreSQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-postgresql-rg-$randomIdentifier"
+tag="change-server-cofigurations-postgresql"
+server="msdocs-postgresql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a PostgreSQL server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az postgres server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Display all available configurations with valid values of an Azure Database for PostgreSQL server
+az postgres server configuration list --resource-group $resourceGroup --server-name $server
+
+# Set value of **log_retention_days**
+echo "Setting value of the log_retention_days setting on $server"
+az postgres server configuration set --resource-group $resourceGroup --server-name $server --name log_retention_days --value 7
+
+# Check the value of **log_retention_days**
+echo "Checking the value of the log_retention_days setting on $server"
+az postgres server configuration show --resource-group $resourceGroup --server-name $server --name log_retention_days
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/postgresql/create-postgresql-server-and-firewall-rule/create-postgresql-server-and-firewall-rule.sh b/postgresql/create-postgresql-server-and-firewall-rule/create-postgresql-server-and-firewall-rule.sh
index 55a75ed2..ede8aeed 100644
--- a/postgresql/create-postgresql-server-and-firewall-rule/create-postgresql-server-and-firewall-rule.sh
+++ b/postgresql/create-postgresql-server-and-firewall-rule/create-postgresql-server-and-firewall-rule.sh
@@ -1,27 +1,48 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 1/13/2022
-# Create a resource group
-az group create \
---name myresourcegroup \
---location westus
+#
+# Create an Azure Database for PostgreSQL server and configure a firewall rule
+#
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-postgresql-rg-$randomIdentifier"
+tag="create-postgresql-server-and-firewall-rule"
+server="msdocs-postgresql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+# Specify appropriate IP address values for your environment
+# to limit / allow access to the PostgreSQL server
+startIp=0.0.0.0
+endIp=0.0.0.0
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+#
+#
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+#
+#
# Create a PostgreSQL server in the resource group
# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
-# Substitute the with your own value.
-az postgres server create \
---name mypgserver-20170401 \
---resource-group myresourcegroup \
---location westus \
---admin-user mylogin \
---admin-password \
---performance-tier Basic \
---compute-units 50
+echo "Creating $server in $location..."
+az postgres server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+#
+#
+# Configure a firewall rule for the server
+echo "Configuring a firewall rule for $server for the IP address range of $startIp to $endIp"
+az postgres server firewall-rule create --resource-group $resourceGroup --server $server --name AllowIps --start-ip-address $startIp --end-ip-address $endIp
+#
+#
+# List firewall rules for the server
+echo "List of server-based firewall rules for $server"
+az postgres server firewall-rule list --resource-group $resourceGroup --server-name $server
+# You may use the switch `--output table` for a more readable table format as the output.
+#
+#
-# Configure a firewall rule for the server
-# The ip address range that you want to allow to access your server
-az postgres server firewall-rule create \
---resource-group myresourcegroup \
---server mypgserver-20170401 \
---name AllowIps \
---start-ip-address 0.0.0.0 \
---end-ip-address 255.255.255.255
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/postgresql/create-postgresql-server-and-firewall-rule/delete-postgresql.sh b/postgresql/create-postgresql-server-and-firewall-rule/delete-postgresql.sh
deleted file mode 100644
index 08b34509..00000000
--- a/postgresql/create-postgresql-server-and-firewall-rule/delete-postgresql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresourcegroup
diff --git a/postgresql/create-postgresql-server-vnet/create-postgresql-server.sh b/postgresql/create-postgresql-server-vnet/create-postgresql-server.sh
new file mode 100644
index 00000000..26d5f4f0
--- /dev/null
+++ b/postgresql/create-postgresql-server-vnet/create-postgresql-server.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/13/2022
+
+#
+# Create a PostgreSQL server and configure a vNet rule
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-postgresql-rg-$randomIdentifier"
+tag="create-postgresql-server"
+server="msdocs-postgresql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+vNet="vNet-$randomIdentifier"
+vNetAddressPrefix="10.0.0.0/16"
+subnet="subnet-$randomIdentifier"
+subnetAddressPrefix="10.0.1.0/24"
+rule="rule-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a PostgreSQL server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az postgres server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Get available service endpoints for Azure region output is JSON
+echo "List of available service endpoints for $location"
+az network vnet list-endpoint-services --location "$location"
+
+# Add Azure SQL service endpoint to a subnet while creating the virtual network
+echo "Adding service endpoint to $subnet in $vNet"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefixes $vNetAddressPrefix --location "$location"
+
+# Creates the service endpoint
+echo "Creating a service endpoint to $subnet in $vNet"
+az network vnet subnet create --resource-group $resourceGroup --name $subnet --vnet-name $vNet --address-prefix $subnetAddressPrefix --service-endpoints Microsoft.SQL
+
+# View service endpoints configured on a subnet
+echo "Viewing the service endpoint to $subnet in $vNet"
+az network vnet subnet show --resource-group $resourceGroup --name $subnet --vnet-name $vNet
+
+# Create a VNet rule on the server to secure it to the subnet
+# Note: resource group (-g) parameter is where the database exists.
+# VNet resource group if different should be specified using subnet id (URI) instead of subnet, VNet pair.
+echo "Creating a VNet rule on $server to secure it to $subnet in $vNet"
+az postgres server vnet-rule create --name $rule --resource-group $resourceGroup --server $server --vnet-name $vNet --subnet $subnet
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/postgresql/scale-postgresql-server/delete-postgresql.sh b/postgresql/scale-postgresql-server/delete-postgresql.sh
deleted file mode 100644
index 08b34509..00000000
--- a/postgresql/scale-postgresql-server/delete-postgresql.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-az group delete --name myresourcegroup
diff --git a/postgresql/scale-postgresql-server/scale-postgresql-server.sh b/postgresql/scale-postgresql-server/scale-postgresql-server.sh
index c16ed185..de7e5216 100644
--- a/postgresql/scale-postgresql-server/scale-postgresql-server.sh
+++ b/postgresql/scale-postgresql-server/scale-postgresql-server.sh
@@ -1,36 +1,55 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 1/13/2022
+
+#
+# Monitor and scale a single PostgreSQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+subscriptionId="$(az account show --query id -o tsv)"
+location="East US"
+resourceGroup="msdocs-postgresql-rg-$randomIdentifier"
+tag="scale-postgresql-server"
+server="msdocs-postgresql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+scaleUpSku="GP_Gen5_4"
+scaleDownSku="GP_Gen5_2"
+storageSize="102400"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
# Create a resource group
-az group create \
---name myresourcegroup \
---location westus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a PostgreSQL server in the resource group
# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
-# Substitute the with your own value.
-az postgres server create \
---name mypgserver-20170401 \
---resource-group myresourcegroup \
---location westus \
---admin-user mylogin \
---admin-password \
---performance-tier Basic \
---compute-units 50
-
-# Monitor usage metrics - Compute
-az monitor metrics list \
---resource-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.DBforPostgreSQL/servers/mypgserver-20170401" \
---metric-names compute_consumption_percent \
---time-grain PT1M
+echo "Creating $server in $location..."
+az postgres server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# Monitor usage metrics - CPU
+echo "Returning the CPU usage metrics for $server"
+az monitor metrics list --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforPostgresql/servers/$server" --metric cpu_percent --interval PT1M
# Monitor usage metrics - Storage
-az monitor metrics list \
---resource-id "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.DBforPostgreSQL/servers/mypgserver-20170401" \
---metric-names storage_used \
---time-grain PT1M
-
-# Scale up the server to provision more Compute Units within the same Tier
-az postgres server update \
---resource-group myresourcegroup \
---name mypgserver-20170401 \
---compute-units 100
+echo "Returning the storage usage metrics for $server"
+az monitor metrics list --resource "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.DBforPostgresql/servers/$server" --metric storage_used --interval PT1M
+
+# Scale up the server by provisionining more vCores within the same tier
+echo "Scaling up $server by changing the SKU to $scaleUpSku"
+az postgres server update --resource-group $resourceGroup --name $server --sku-name $scaleUpSku
+
+# Scale down the server by provisioning fewer vCores within the same tier
+echo "Scaling down $server by changing the SKU to $scaleDownSku"
+az postgres server update --resource-group $resourceGroup --name $server --sku-name $scaleDownSku
+
+# Scale up the server to provision a storage size of 10GB
+# Storage size cannot be reduced
+echo "Scaling up the storage size for $server to $storageSize"
+az postgres server update --resource-group $resourceGroup --name $server --storage-size $storageSize
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/postgresql/server-logs/server-logs.sh b/postgresql/server-logs/server-logs.sh
new file mode 100644
index 00000000..3fb910e1
--- /dev/null
+++ b/postgresql/server-logs/server-logs.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/13/2022
+
+#
+# Enable and download server slow query logs of an Azure Database for PostgreSQL server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-postgresql-rg-$randomIdentifier"
+tag="server-logs-postgresql"
+server="msdocs-postgresql-server-$randomIdentifier"
+sku="GP_Gen5_2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+configurationParameter="slow_query_log"
+logValue="On"
+durationStatementLog="durationStatementLog-$randomIdentifier"
+logDuration="10000"
+logFileList="logFileList"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a PostgreSQL server in the resource group
+# Name of a server maps to DNS name and is thus required to be globally unique in Azure.
+echo "Creating $server in $location..."
+az postgres server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password --sku-name $sku
+
+# List the configuration options for review
+echo "Returning the configuration options on $server"
+az postgres server configuration list --resource-group $resourceGroup --server $server
+
+# Turn on statement level log
+echo "Enable the statement level log"
+az postgres server configuration set --name log_statement --resource-group $resourceGroup --server $server --value all
+
+# Set log_min_duration_statement time to 10 sec
+echo "Setting log_min_duration_statement to 10 sec"
+az postgres server configuration set --name log_min_duration_statement --resource-group $resourceGroup --server $server --value 10000
+
+# List the available log files
+echo "Returning the list of available log files on $server"
+az postgres server-logs list --resource-group $resourceGroup --server $server
+
+# To download log file from Azure, direct the output of the previous comment to a text file
+# "> log_files_list.txt"
+# Review the text file to find the server log file name for the desired timeframe
+# Substitute the in the script below with your server log file name
+# Creates the log file in the current command line path
+# az postgres server-logs download --name $resourceGroup --server $server
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/redis-cache/cache-keys-ports/cache-keys-ports.sh b/redis-cache/cache-keys-ports/cache-keys-ports.sh
deleted file mode 100644
index a2077baf..00000000
--- a/redis-cache/cache-keys-ports/cache-keys-ports.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#/bin/bash
-
-# Retrieve the hostname, ports, and keys for contosoCache located in contosoGroup
-
-# Retrieve the hostname and ports for an Azure Redis Cache instance
-redis=($(az redis show --name contosoCache --resource-group contosoGroup --query [hostName,enableNonSslPort,port,sslPort] --output tsv))
-
-# Retrieve the keys for an Azure Redis Cache instance
-keys=($(az redis list-keys --name contosoCache --resource-group contosoGroup --query [primaryKey,secondaryKey] --output tsv))
-
-# Display the retrieved hostname, keys, and ports
-echo "Hostname:" ${redis[0]}
-echo "Non SSL Port:" ${redis[2]}
-echo "Non SSL Port Enabled:" ${redis[1]}
-echo "SSL Port:" ${redis[3]}
-echo "Primary Key:" ${keys[0]}
-echo "Secondary Key:" ${keys[1]}
\ No newline at end of file
diff --git a/redis-cache/create-cache/create-cache.sh b/redis-cache/create-cache/create-cache.sh
deleted file mode 100644
index ec9f8b94..00000000
--- a/redis-cache/create-cache/create-cache.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#/bin/bash
-
-# Creates a Resource Group named contosoGroup, and creates a Redis Cache in that group named contosoCache
-
-# Create a Resource Group
-az group create --name contosoGroup --location eastus
-
-# Create a Basic C0 (256 MB) Redis Cache
-az redis create --name contosoCache --resource-group contosoGroup --location eastus --sku Basic --vm-size C0
-
diff --git a/redis-cache/create-cache/create-manage-cache.sh b/redis-cache/create-cache/create-manage-cache.sh
new file mode 100644
index 00000000..46788084
--- /dev/null
+++ b/redis-cache/create-cache/create-manage-cache.sh
@@ -0,0 +1,49 @@
+#/bin/bash
+# Passed validation in Cloud Shell on 01/31/2023
+
+#
+# Create and manage a C0 Redis Cache
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-redis-cache-rg-$randomIdentifier"
+tag="create-manage-cache"
+cache="msdocs-redis-cache-$randomIdentifier"
+sku="basic"
+size="C0"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Basic C0 (256 MB) Redis Cache
+echo "Creating $cache"
+az redis create --name $cache --resource-group $resourceGroup --location "$location" --sku $sku --vm-size $size
+
+# Get details of an Azure Cache for Redis
+echo "Showing details of $cache"
+az redis show --name $cache --resource-group $resourceGroup
+
+# Retrieve the hostname and ports for an Azure Redis Cache instance
+redis=($(az redis show --name $cache --resource-group $resourceGroup --query [hostName,enableNonSslPort,port,sslPort] --output tsv))
+
+# Retrieve the keys for an Azure Redis Cache instance
+keys=($(az redis list-keys --name $cache --resource-group $resourceGroup --query [primaryKey,secondaryKey] --output tsv))
+
+# Display the retrieved hostname, keys, and ports
+echo "Hostname:" ${redis[0]}
+echo "Non SSL Port:" ${redis[2]}
+echo "Non SSL Port Enabled:" ${redis[1]}
+echo "SSL Port:" ${redis[3]}
+echo "Primary Key:" ${keys[0]}
+echo "Secondary Key:" ${keys[1]}
+
+# Delete a redis cache
+echo "Deleting $cache"
+az redis delete --name $cache --resource-group $resourceGroup -y
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
+
diff --git a/redis-cache/create-premium-cache-cluster/create-manage-premium-cache-cluster.sh b/redis-cache/create-premium-cache-cluster/create-manage-premium-cache-cluster.sh
new file mode 100644
index 00000000..86352813
--- /dev/null
+++ b/redis-cache/create-premium-cache-cluster/create-manage-premium-cache-cluster.sh
@@ -0,0 +1,50 @@
+#/bin/# Passed validation in Cloud Shell on 3/11/2022
+
+#
+# Create and manage a premium P1 Redis Cache with clustering
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-redis-cache-rg-$randomIdentifier"
+tag="create-manage-premium-cache-cluster"
+cache="msdocs-redis-cache-$randomIdentifier"
+sku="premium"
+size="P1"
+shardCount="2"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a Premium P1 (6 GB) Redis Cache with clustering enabled and 2 shards (for a total of 12 GB)
+echo "Creating $cache"
+az redis create --name $cache --resource-group $resourceGroup --location "$location" --sku $sku --vm-size $size --shard-count $shardCount
+
+# Get details of an Azure Cache for Redis
+echo "Showing details of $cache"
+az redis show --name $cache --resource-group $resourceGroup
+
+# Retrieve the hostname and ports for an Azure Redis Cache instance
+redis=($(az redis show --name $resourceGroup --resource-group $resourceGroup --query [hostName,enableNonSslPort,port,sslPort] --output tsv))
+
+# Retrieve the keys for an Azure Redis Cache instance
+keys=($(az redis list-keys --name contosoCache --resource-group contosoGroup --query [primaryKey,secondaryKey] --output tsv))
+
+# Display the retrieved hostname, keys, and ports
+echo "Hostname:" ${redis[0]}
+echo "Non SSL Port:" ${redis[2]}
+echo "Non SSL Port Enabled:" ${redis[1]}
+echo "SSL Port:" ${redis[3]}
+echo "Primary Key:" ${keys[0]}
+echo "Secondary Key:" ${keys[1]}
+
+# Delete a redis cache
+echo "Deleting $cache"
+az redis delete --name $resourceGroup --resource-group $resourceGroup -y
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
+
+
diff --git a/redis-cache/create-premium-cache-cluster/create-premium-cache-cluster.sh b/redis-cache/create-premium-cache-cluster/create-premium-cache-cluster.sh
deleted file mode 100644
index 0c6edf18..00000000
--- a/redis-cache/create-premium-cache-cluster/create-premium-cache-cluster.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#/bin/bash
-
-# Creates a Resource Group named contosoGroup, and creates a Premium Redis Cache with clustering in that group named contosoCache
-
-# Create a Resource Group
-az group create --name contosoGroup --location eastus
-
-# Create a Premium P1 (6 GB) Redis Cache with clustering enabled and 2 shards (for a total of 12 GB)
-az redis create --name contosoCache --resource-group contosoGroup --location eastus --vm-size P1 --sku Premium --shard-count 2
-
diff --git a/redis-cache/delete-cache/delete-cache.sh b/redis-cache/delete-cache/delete-cache.sh
deleted file mode 100644
index dfb11b82..00000000
--- a/redis-cache/delete-cache/delete-cache.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#/bin/bash
-
-# Delete a Redis Cache named contosoCache from the Resource Group contosoGroup
-az redis delete --name contosoCache --resource-group contosoGroup
diff --git a/redis-cache/show-cache/show-cache.sh b/redis-cache/show-cache/show-cache.sh
deleted file mode 100644
index a883f8ce..00000000
--- a/redis-cache/show-cache/show-cache.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#/bin/bash
-
-# Retrieve the details for an Azure Redis Cache instance named contosoCache in the Resource Group contosoGroup
-# This script shows details such as hostname, ports, and provisioning status
-az redis show --name contosoCache --resource-group contosoGroup
\ No newline at end of file
diff --git a/service-fabric/create-cluster-deploy-application/create-cluster-deploy-application - Copy.sh.txt b/service-fabric/create-cluster-deploy-application/create-cluster-deploy-application - Copy.sh.txt
new file mode 100644
index 00000000..96e79195
--- /dev/null
+++ b/service-fabric/create-cluster-deploy-application/create-cluster-deploy-application - Copy.sh.txt
@@ -0,0 +1,112 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/21/2022
+
+#
+# Create a secure Service Fabric Linux cluster
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-service-fabric-rg-$randomIdentifier"
+tag="create-cluster-deploy-application"
+cluster="msdocs-cluster-$randomIdentifier"
+password="Pa$$w0rD-$randomIdentifier"
+subject="msdocs-cluster.eastus.cloudapp.azure.com"
+vault="msdocskeyvault$randomIdentifier"
+vmUser="azureuser"
+vmPassword="vmPa$$w0rD-$randomIdentifier"
+size="5"
+os="UbuntuServer1604"
+application="msdocs-application-$randomIdentifier"
+appType="msdocs-application-type-$randomIdentifier"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create key vault
+echo "Creating $vault"
+az keyvault create --name $vault --resource-group $resourceGroup --enabled-for-deployment true
+
+# Create secure five node Linux cluster. Create a certficate in the key vault.
+# The certificate's subject name must match the domain that you use to access the Service Fabric cluster.
+# The certificate is downloaded locally.
+echo "Creating $cluster"
+az sf cluster create \
+ --resource-group $resourceGroup \
+ --location "$location" \
+ --certificate-password $password \
+ --cluster-size $size \
+ --vm-password $vmPassword \
+ --vm-user-name $vmUser \
+ --certificate-output-folder . \
+ --certificate-subject-name $subject \
+ --vault-name $vault \
+ --vault-rg $resourceGroup \
+ --cluster-name $cluster \
+ --os $os
+
+# Create application type
+echo "Creating $appType"
+az sf application-type create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-type-name $appType
+
+# Create application version
+az sf application-type version create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-type-name $appType \
+ --version 1.0 \
+ --package-url "https://sftestapp.blob.core.windows.net/sftestapp/testApp_1.0.sfpkg"
+
+# List application type
+ az sf application-type list \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster
+
+# Create application in the cluster
+echo "Creating $application in $cluster"
+az sf application create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-name $application \
+ --application-type-name $appType \
+ --application-type-version v1 \
+ --package-url "https://sftestapp.blob.core.windows.net/sftestapp/testApp_1.0.sfpkg" \
+ --application-parameters key0=value0
+
+az sf application create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-name $application \
+ --application-type-name $appType \
+ --application-type-version v1 \
+ --application-parameters key0=value0
+
+# List application in the cluster
+echo "List $application in $cluster"
+az sf application list \
+--resource-group $resourceGroup \
+--cluster-name $cluster
+
+# Upgrade application
+echo "Upgrading $application in $cluster"
+az sf application update \
+--resource-group $resourceGroup \
+--cluster-name $cluster
+ --application-name $application \
+--minimum-nodes 1 \
+--maximum-nodes 3
+
+# Delete application
+echo "Deleting $application"
+az sf application delete \
+--resource-group $resourceGroup \
+--cluster-name $cluster \
+--application-name $application
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/service-fabric/create-cluster-deploy-application/create-cluster-deploy-application.sh b/service-fabric/create-cluster-deploy-application/create-cluster-deploy-application.sh
new file mode 100644
index 00000000..96e79195
--- /dev/null
+++ b/service-fabric/create-cluster-deploy-application/create-cluster-deploy-application.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 3/21/2022
+
+#
+# Create a secure Service Fabric Linux cluster
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-service-fabric-rg-$randomIdentifier"
+tag="create-cluster-deploy-application"
+cluster="msdocs-cluster-$randomIdentifier"
+password="Pa$$w0rD-$randomIdentifier"
+subject="msdocs-cluster.eastus.cloudapp.azure.com"
+vault="msdocskeyvault$randomIdentifier"
+vmUser="azureuser"
+vmPassword="vmPa$$w0rD-$randomIdentifier"
+size="5"
+os="UbuntuServer1604"
+application="msdocs-application-$randomIdentifier"
+appType="msdocs-application-type-$randomIdentifier"
+
+# Create a resource group
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create key vault
+echo "Creating $vault"
+az keyvault create --name $vault --resource-group $resourceGroup --enabled-for-deployment true
+
+# Create secure five node Linux cluster. Create a certficate in the key vault.
+# The certificate's subject name must match the domain that you use to access the Service Fabric cluster.
+# The certificate is downloaded locally.
+echo "Creating $cluster"
+az sf cluster create \
+ --resource-group $resourceGroup \
+ --location "$location" \
+ --certificate-password $password \
+ --cluster-size $size \
+ --vm-password $vmPassword \
+ --vm-user-name $vmUser \
+ --certificate-output-folder . \
+ --certificate-subject-name $subject \
+ --vault-name $vault \
+ --vault-rg $resourceGroup \
+ --cluster-name $cluster \
+ --os $os
+
+# Create application type
+echo "Creating $appType"
+az sf application-type create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-type-name $appType
+
+# Create application version
+az sf application-type version create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-type-name $appType \
+ --version 1.0 \
+ --package-url "https://sftestapp.blob.core.windows.net/sftestapp/testApp_1.0.sfpkg"
+
+# List application type
+ az sf application-type list \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster
+
+# Create application in the cluster
+echo "Creating $application in $cluster"
+az sf application create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-name $application \
+ --application-type-name $appType \
+ --application-type-version v1 \
+ --package-url "https://sftestapp.blob.core.windows.net/sftestapp/testApp_1.0.sfpkg" \
+ --application-parameters key0=value0
+
+az sf application create \
+ --resource-group $resourceGroup \
+ --cluster-name $cluster \
+ --application-name $application \
+ --application-type-name $appType \
+ --application-type-version v1 \
+ --application-parameters key0=value0
+
+# List application in the cluster
+echo "List $application in $cluster"
+az sf application list \
+--resource-group $resourceGroup \
+--cluster-name $cluster
+
+# Upgrade application
+echo "Upgrading $application in $cluster"
+az sf application update \
+--resource-group $resourceGroup \
+--cluster-name $cluster
+ --application-name $application \
+--minimum-nodes 1 \
+--maximum-nodes 3
+
+# Delete application
+echo "Deleting $application"
+az sf application delete \
+--resource-group $resourceGroup \
+--cluster-name $cluster \
+--application-name $application
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/backup-database/backup-database.sh b/sql-database/backup-database/backup-database.sh
new file mode 100644
index 00000000..8d9dbc63
--- /dev/null
+++ b/sql-database/backup-database/backup-database.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Backup an Azure SQL single database to an Azure storage container
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="backup-database"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+storage="msdocsazuresql$randomIdentifier"
+container="msdocs-azuresql-container-$randomIdentifier"
+bacpac="backup.bacpac"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $storage..."
+az storage account create --name $storage --resource-group $resourceGroup --location "$location" --sku Standard_LRS
+
+echo "Creating $container on $storage..."
+key=$(az storage account keys list --account-name $storage --resource-group $resourceGroup -o json --query [0].value | tr -d '"')
+az storage container create --name $container --account-key $key --account-name $storage
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+az sql server firewall-rule create --resource-group $resourceGroup --server $server --name AllowAzureServices --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+echo "Creating $database..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --edition GeneralPurpose --sample-name AdventureWorksLT
+
+echo "Backing up $database..."
+az sql db export --admin-password $password --admin-user $login --storage-key $key --storage-key-type StorageAccessKey --storage-uri "https://$storage.blob.core.windows.net/$container/$bacpac" --name $database --resource-group $resourceGroup --server $server
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/copy-database-to-new-server/copy-database-to-new-server.sh b/sql-database/copy-database-to-new-server/copy-database-to-new-server.sh
new file mode 100644
index 00000000..a440cc53
--- /dev/null
+++ b/sql-database/copy-database-to-new-server/copy-database-to-new-server.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Copy a database in Azure SQL Database to a new server
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="copy-database-to-new-server"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+targetResourceGroup="msdocs-azuresql-targetrg-$randomIdentifier"
+targetLocation="Central US"
+targetServer="msdocs-azuresql-targetServer-$randomIdentifier"
+targetDatabase="msdocs-azuresql-targetDatabase-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in location $location and $targetResourceGroup in $targetLocation..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+az group create --name $targetResourceGroup --location "$targetLocation"
+
+echo "Creating $server in $location and $targetServer in $targetLocation..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+az sql server create --name $targetServer --resource-group $targetResourceGroup --location "$targetLocation" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --service-objective S0
+
+echo "Copying $database on $server to $targetDatabase on $targetServer..."
+az sql db copy --dest-name $targetDatabase --dest-resource-group $targetResourceGroup --dest-server $targetServer --name $database --resource-group $resourceGroup --server $server
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $targetResourceGroup -y
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/create-and-configure-database/create-and-configure-database.sh b/sql-database/create-and-configure-database/create-and-configure-database.sh
index d7dddf89..7ff715af 100644
--- a/sql-database/create-and-configure-database/create-and-configure-database.sh
+++ b/sql-database/create-and-configure-database/create-and-configure-database.sh
@@ -1,40 +1,42 @@
#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
-# Set an admin login and password for your database
-export adminlogin=ServerAdmin
-export password=ChangeYourAdminPassword1
-# The logical server name has to be unique in the system
-export servername=server-$RANDOM
-# The ip address range that you want to allow to access your DB
-export startip=0.0.0.0
-export endip=0.0.0.0
+#
+# Create a single database and configure a firewall rule
+#
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="create-and-configure-database"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+# Specify appropriate IP address values for your environment
+# to limit access to the SQL Database server
+startIp=0.0.0.0
+endIp=0.0.0.0
-# Create a resource group
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create a logical server in the resource group
-az sql server create \
- --name $servername \
- --resource-group myResourceGroup \
- --location westeurope \
- --admin-user $adminlogin \
- --admin-password $password
-
-# Configure a firewall rule for the server
-az sql server firewall-rule create \
- --resource-group myResourceGroup \
- --server $servername \
- -n AllowYourIp \
- --start-ip-address $startip \
- --end-ip-address $endip
-
-# Create a database in the server
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name mySampleDatabase \
- --sample-name AdventureWorksLT \
- --service-objective S0
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+#
+#
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+#
+#
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+#
+#
+echo "Configuring firewall..."
+az sql server firewall-rule create --resource-group $resourceGroup --server $server -n AllowYourIp --start-ip-address $startIp --end-ip-address $endIp
+#
+#
+echo "Creating $database on $server..."
+az sql db create --resource-group $resourceGroup --server $server --name $database --sample-name AdventureWorksLT --edition GeneralPurpose --family Gen5 --capacity 2 --zone-redundant true # zone redundancy is only supported on premium and business critical service tiers
+#
+#
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/database-auditing-and-threat-detection/database-auditing-and-threat-detection.sh b/sql-database/database-auditing-and-threat-detection/database-auditing-and-threat-detection.sh
new file mode 100644
index 00000000..169b8bf1
--- /dev/null
+++ b/sql-database/database-auditing-and-threat-detection/database-auditing-and-threat-detection.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Configure SQL Database auditing and Advanced Threat Protection
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="database-auditing-and-threat-detection"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+storage="msdocsazuresql$randomIdentifier"
+notification="changeto@your.email;changeto@your.email"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --service-objective S0
+
+echo "Creating $storage..."
+az storage account create --name $storage --resource-group $resourceGroup --location "$location" --sku Standard_LRS
+
+echo "Setting access policy on $storage..."
+az sql db audit-policy update --name $database --resource-group $resourceGroup --server $server --state Enabled --bsts Enabled --storage-account $storage
+
+# use `az sql db advanced-threat-protection-setting update` to set the threat detection policy on $storage
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/failover-groups/add-elastic-pool-to-failover-group-az-cli.sh b/sql-database/failover-groups/add-elastic-pool-to-failover-group-az-cli.sh
new file mode 100644
index 00000000..ae1b66d2
--- /dev/null
+++ b/sql-database/failover-groups/add-elastic-pool-to-failover-group-az-cli.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Add an Azure SQL Database elastic pool to a failover group
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="add-elastic-pool-to-failover-group-az-cli"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+#
+pool="msdocs-azuresql-pool-$randomIdentifier"
+#
+#
+failoverGroup="msdocs-azuresql-failover-group-$randomIdentifier"
+failoverLocation="Central US"
+secondaryServer="msdocs-azuresql-secondary-server-$randomIdentifier"
+#
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --sample-name AdventureWorksLT
+
+#
+echo "Creating $pool on $server..."
+az sql elastic-pool create --name $pool --resource-group $resourceGroup --server $server
+#
+#
+echo "Adding $database to $pool..."
+az sql db update --elastic-pool $pool --name $database --resource-group $resourceGroup --server $server
+#
+#
+echo "Creating $secondaryServer in $failoverLocation..."
+az sql server create --name $secondaryServer --resource-group $resourceGroup --location "$failoverLocation" --admin-user $login --admin-password $password
+#
+#
+echo "Creating $pool on $secondaryServer..."
+az sql elastic-pool create --name $pool --resource-group $resourceGroup --server $secondaryServer
+#
+#
+echo "Creating $failoverGroup between $server and $secondaryServer..."
+az sql failover-group create --name $failoverGroup --partner-server $secondaryServer --resource-group $resourceGroup --server $server --failover-policy Automatic --grace-period 2
+databaseId=$(az sql elastic-pool list-dbs --name $pool --resource-group $resourceGroup --server $server --query [0].name -o json | tr -d '"')
+#
+#
+echo "Adding $database to $failoverGroup..."
+az sql failover-group update --name $failoverGroup --add-db $databaseId --resource-group $resourceGroup --server $server
+#
+#
+echo "Confirming the role of each server in the failover group..." # note ReplicationRole property
+az sql failover-group show --name $failoverGroup --resource-group $resourceGroup --server $server
+#
+#
+echo "Failing over to $secondaryServer..."
+az sql failover-group set-primary --name $failoverGroup --resource-group $resourceGroup --server $secondaryServer
+
+echo "Confirming role of $secondaryServer is now primary..." # note ReplicationRole property
+az sql failover-group show --name $failoverGroup --resource-group $resourceGroup --server $server
+#
+#
+echo "Failing back to $server...."
+az sql failover-group set-primary --name $failoverGroup --resource-group $resourceGroup --server $server
+#
+
+#
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/failover-groups/add-managed-instance-to-failover-group-az-cli.sh b/sql-database/failover-groups/add-managed-instance-to-failover-group-az-cli.sh
new file mode 100644
index 00000000..1557f862
--- /dev/null
+++ b/sql-database/failover-groups/add-managed-instance-to-failover-group-az-cli.sh
@@ -0,0 +1,122 @@
+#!/bin/bash
+# Failed validation in Bash 12/01/2021 - not yet supported in Managed Instance using Azure CLI.
+# In order to establish failover group between two SQL MIs, both of them have to be part of the same DNS zone.
+# To achieve this, you need to provide instance partner to the secondary instance during creation.
+# However, this property is not yet available in CLI
+# So, not surfaced in md file or in TOC
+# Due to deployment times, you should plan for a full day to complete the entire script. You can monitor deployment progress in the activity log within the Azure portal. For more information on deployment times, see https://docs.microsoft.com/azure/sql-database/sql-database-managed-instance#managed-instance-management-operations.
+
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="add-managed-instance-to-failover-group-az-cli"
+vnet="msdocs-azuresql-vnet-$randomIdentifier"
+subnet="msdocs-azuresql-subnet-$randomIdentifier"
+nsg="msdocs-azuresql-nsg-$randomIdentifier"
+route="msdocs-azuresql-route-$randomIdentifier"
+instance="msdocs-azuresql-instance-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+vpnSharedKey="abc123"
+gateway="msdocs-azuresql-gateway-$randomIdentifier"
+gatewayIp="$gateway-ip"
+gatewayConnection="$gateway-connection"
+failoverResourceGroup="msdocs-azuresql-failover-rg-$randomIdentifier"
+failoverLocation="Central US"
+failoverGroup="msdocs-azuresql-failover-group-$randomIdentifier"
+failoverVnet="msdocs-azuresql-failover-vnet-$randomIdentifier"
+failoverSubnet="msdocs-azuresql-failover-subnet-$randomIdentifier"
+failoverNsg="msdocs-azuresql-failover-nsg-$randomIdentifier"
+failoverRoute="msdocs-azuresql-failover-route-$randomIdentifier"
+failoverInstance="msdocs-azuresql-failover-instance-$randomIdentifier"
+failoverGateway="msdocs-azuresql-failover-gateway-$randomIdentifier"
+failoverGatewayIP="$failoverGateway-ip"
+failoverGatewayConnection="$failoverGateway-connection"
+
+echo "Using resource groups $resourceGroup and $failoverResourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location and $failoverResourceGroup in $failoverLocation..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+az group create --name $failoverResourceGroup --location "$failoverLocation"
+
+echo "Creating $vnet with $subnet..."
+az network vnet create --name $vnet --resource-group $resourceGroup --location "$location" --address-prefixes 10.0.0.0/16
+az network vnet subnet create --name $subnet --resource-group $resourceGroup --vnet-name $vnet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Sql/managedInstances
+
+echo "Creating $nsg..."
+az network nsg create --name $nsg --resource-group $resourceGroup --location "$location"
+
+az network nsg rule create --name "allow_management_inbound" --nsg-name $nsg --priority 100 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges 9000 9003 1438 1440 1452 --direction Inbound --protocol Tcp --source-address-prefixes "*" --source-port-ranges "*"
+az network nsg rule create --name "allow_misubnet_inbound" --nsg-name $nsg --priority 200 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges "*" --direction Inbound --protocol "*" --source-address-prefixes 10.0.0.0/24 --source-port-ranges "*"
+az network nsg rule create --name "allow_health_probe_inbound" --nsg-name $nsg --priority 300 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges "*" --direction Inbound --protocol "*" --source-address-prefixes AzureLoadBalancer --source-port-ranges "*"
+az network nsg rule create --name "allow_management_outbound" --nsg-name $nsg --priority 1100 --resource-group $resourceGroup --access Allow --destination-address-prefixes AzureCloud --destination-port-ranges 443 12000 --direction Outbound --protocol Tcp --source-address-prefixes 10.0.0.0/24 --source-port-ranges "*"
+az network nsg rule create --name "allow_misubnet_outbound" --nsg-name $nsg --priority 200 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges "*" --direction Outbound --protocol "*" --source-address-prefixes 10.0.0.0/24 --source-port-ranges "*"
+
+echo "Creating $route..."
+az network route-table create --name $route --resource-group $resourceGroup --location "$location"
+
+az network route-table route create --address-prefix 0.0.0.0/0 --name "primaryToMIManagementService" --next-hop-type Internet --resource-group $resourceGroup --route-table-name $route
+az network route-table route create --address-prefix 10.0.0.0/24 --name "ToLocalClusterNode" --next-hop-type VnetLocal --resource-group $resourceGroup --route-table-name $route
+
+echo "Configuring $subnet with $nsg and $route..."
+az network vnet subnet update --name $subnet --network-security-group $nsg --route-table $route --vnet-name $vnet --resource-group $resourceGroup
+
+# This step will take awhile to complete. You can monitor deployment progress in the activity log within the Azure portal.
+echo "Creating $instance with $vnet and $subnet..."
+az sql mi create --admin-password $password --admin-user $login --name $instance --resource-group $resourceGroup --subnet $subnet --vnet-name $vnet --location "$location" --assign-identity
+
+echo "Creating $failoverVnet with $failoverSubnet..."
+az network vnet create --name $failoverVnet --resource-group $failoverResourceGroup --location "$failoverLocation" --address-prefixes 10.128.0.0/16
+az network vnet subnet create --name $failoverSubnet --resource-group $failoverResourceGroup --vnet-name $failoverVnet --address-prefixes 10.128.0.0/24 --delegations Microsoft.Sql/managedInstances
+
+echo "Creating $failoverNsg..."
+az network nsg create --name $failoverNsg --resource-group $failoverResourceGroup --location "$failoverLocation"
+
+az network nsg rule create --name "allow_management_inbound" --nsg-name $failoverNsg --priority 100 --resource-group $failoverResourceGroup --access Allow --destination-address-prefixes 10.128.0.0/24 --destination-port-ranges 9000 9003 1438 1440 1452 --direction Inbound --protocol Tcp --source-address-prefixes "*" --source-port-ranges "*"
+az network nsg rule create --name "allow_misubnet_inbound" --nsg-name $failoverNsg --priority 200 --resource-group $failoverResourceGroup --access Allow --destination-address-prefixes 10.128.0.0/24 --destination-port-ranges "*" --direction Inbound --protocol "*" --source-address-prefixes 10.128.0.0/24 --source-port-ranges "*"
+az network nsg rule create --name "allow_health_probe_inbound" --nsg-name $failoverNsg --priority 300 --resource-group $failoverResourceGroup --access Allow --destination-address-prefixes 10.128.0.0/24 --destination-port-ranges "*" --direction Inbound --protocol "*" --source-address-prefixes AzureLoadBalancer --source-port-ranges "*"
+az network nsg rule create --name "allow_management_outbound" --nsg-name $failoverNsg --priority 1100 --resource-group $failoverResourceGroup --access Allow --destination-address-prefixes AzureCloud --destination-port-ranges 443 12000 --direction Outbound --protocol Tcp --source-address-prefixes 10.128.0.0/24 --source-port-ranges "*"
+az network nsg rule create --name "allow_misubnet_outbound" --nsg-name $failoverNsg --priority 200 --resource-group $failoverResourceGroup --access Allow --destination-address-prefixes 10.128.0.0/24 --destination-port-ranges "*" --direction Outbound --protocol "*" --source-address-prefixes 10.128.0.0/24 --source-port-ranges "*"
+
+echo "Creating $failoverRoute..."
+az network route-table create --name $failoverRoute --resource-group $failoverResourceGroup --location "$failoverLocation"
+
+az network route-table route create --address-prefix 0.0.0.0/0 --name "primaryToMIManagementService" --next-hop-type Internet --resource-group $failoverResourceGroup --route-table-name $failoverRoute
+az network route-table route create --address-prefix 10.128.0.0/24 --name "ToLocalClusterNode" --next-hop-type VnetLocal --resource-group $failoverResourceGroup --route-table-name $failoverRoute
+
+echo "Configuring $failoverSubnet with $failoverNsg and $failoverRoute..."
+az network vnet subnet update --name $failoverSubnet --network-security-group $failoverNsg --route-table $failoverRoute --vnet-name $failoverVnet --resource-group $failoverResourceGroup
+
+# This step will take awhile to complete. You can monitor deployment progress in the activity log within the Azure portal.
+echo "Creating $failoverInstance with $failoverVnet and $failoverSubnet..."
+az sql mi create --admin-password $password --admin-user $login --name $failoverInstance --resource-group $failoverResourceGroup --subnet $failoverSubnet --vnet-name $failoverVnet --location "$failoverLocation" --assign-identity
+
+echo "Creating gateway..."
+az network vnet subnet create --name "GatewaySubnet" --resource-group $resourceGroup --vnet-name $vnet --address-prefixes 10.0.255.0/27
+az network public-ip create --name $gatewayIp --resource-group $resourceGroup --allocation-method Dynamic --location "$location"
+az network vnet-gateway create --name $gateway --public-ip-addresses $gatewayIp --resource-group $resourceGroup --vnet $vnet --asn 61000 --gateway-type Vpn --location "$location" --sku VpnGw1 --vpn-type RouteBased #-EnableBgp $true
+
+echo "Creating failover gateway..."
+az network vnet subnet create --name "GatewaySubnet" --resource-group $failoverResourceGroup --vnet-name $failoverVnet --address-prefixes 10.128.255.0/27
+az network public-ip create --name $failoverGatewayIP --resource-group $failoverResourceGroup --allocation-method Dynamic --location "$failoverLocation"
+az network vnet-gateway create --name $failoverGateway --public-ip-addresses $failoverGatewayIP --resource-group $failoverResourceGroup --vnet $failoverVnet --asn 62000 --gateway-type Vpn --location "$failoverLocation" --sku VpnGw1 --vpn-type RouteBased
+
+echo "Connecting gateway and failover gateway..."
+az network vpn-connection create --name $gatewayConnection --resource-group $resourceGroup --vnet-gateway1 $gateway --enable-bgp --location "$location" --vnet-gateway2 $failoverGateway --shared-key $vpnSharedKey
+az network vpn-connection create --name $failoverGatewayConnection --resource-group $failoverResourceGroup --vnet-gateway1 $failoverGateway --enable-bgp --location "$failoverLocation" --shared-key $vpnSharedKey --vnet-gateway2 $gateway
+
+echo "Creating the failover group..."
+az sql instance-failover-group create --mi $instance --name $failoverGroup--partner-mi $failoverInstance --resource-group $resourceGroup --partner-resource-group $failoverResourceGroup --failover-policy Automatic --grace-period 1
+az sql instance-failover-group show --location "$location" --name $failoverGroup--resource-group $resourceGroup # verify the primary role
+
+echo "Failing managed instance over to secondary location..."
+az sql instance-failover-group set-primary --location "$failoverLocation" --name $failoverGroup--resource-group $resource
+az sql instance-failover-group show --location "$failoverLocation" --name $failoverGroup--resource-group $resourceGroup # verify the primary role
+
+echo "Failing managed instance back to primary location..."
+az sql instance-failover-group set-primary --location "$location" --name $failoverGroup--resource-group $resource
+az sql instance-failover-group show --location "$location" --name $failoverGroup--resource-group $resourceGroup # verify the primary role
+
+# echo "Deleting all resources"
+# az group delete --name $failoverResourceGroup -y
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/failover-groups/add-single-db-to-failover-group-az-cli.sh b/sql-database/failover-groups/add-single-db-to-failover-group-az-cli.sh
new file mode 100644
index 00000000..1555ddfa
--- /dev/null
+++ b/sql-database/failover-groups/add-single-db-to-failover-group-az-cli.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Add an Azure SQL Database to an auto-failover group
+
+# VariableBlock
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="add-single-db-to-failover-group-az-cli"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+#
+failoverGroup="msdocs-azuresql-failover-group-$randomIdentifier"
+failoverLocation="Central US"
+secondaryServer="msdocs-azuresql-secondary-server-$randomIdentifier"
+#
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --sample-name AdventureWorksLT
+#
+echo "Creating $secondaryServer in $failoverLocation..."
+az sql server create --name $secondaryServer --resource-group $resourceGroup --location "$failoverLocation" --admin-user $login --admin-password $password
+#
+#
+echo "Creating $failoverGroup between $server and $secondaryServer..."
+az sql failover-group create --name $failoverGroup --partner-server $secondaryServer --resource-group $resourceGroup --server $server --failover-policy Automatic --grace-period 2 --add-db $database
+#
+#
+echo "Confirming the role of each server in the failover group..." # note ReplicationRole property
+az sql failover-group show --name $failoverGroup --resource-group $resourceGroup --server $server
+#
+#
+echo "Failing over to $secondaryServer..."
+az sql failover-group set-primary --name $failoverGroup --resource-group $resourceGroup --server $secondaryServer
+
+echo "Confirming role of $secondaryServer is now primary..." # note ReplicationRole property
+az sql failover-group show --name $failoverGroup --resource-group $resourceGroup --server $server
+#
+#
+echo "Failing back to $server...."
+az sql failover-group set-primary --name $failoverGroup --resource-group $resourceGroup --server $server
+#
+#
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
+
+# The script is used in the following file, adding or removing lines may require you update the range value in this file
+# articles\azure-sql\database\failover-group-add-single-database-tutorial.md
diff --git a/sql-database/import-from-bacpac/import-from-bacpac.sh b/sql-database/import-from-bacpac/import-from-bacpac.sh
new file mode 100644
index 00000000..f55cce27
--- /dev/null
+++ b/sql-database/import-from-bacpac/import-from-bacpac.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Import a BACPAC file into a database in SQL Database
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="import-from-bacpac"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+storage="msdocsazuresql$randomIdentifier"
+container="msdocs-azuresql-container-$randomIdentifier"
+bacpac="sample.bacpac"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $storage..."
+az storage account create --name $storage --resource-group $resourceGroup --location "$location" --sku Standard_LRS
+
+echo "Creating $container on $storage..."
+key=$(az storage account keys list --account-name $storage --resource-group $resourceGroup -o json --query [0].value | tr -d '"')
+
+az storage container create --name $container --account-key $key --account-name $storage #--public-access container
+
+echo "Downloading sample database..."
+az rest --uri https://github.com/Microsoft/sql-server-samples/releases/download/wide-world-importers-v1.0/WideWorldImporters-Standard.bacpac --output-file $bacpac -m get --skip-authorization-header
+
+echo "Uploading sample database to $container..."
+az storage blob upload --container-name $container --file $bacpac --name $bacpac --account-key $key --account-name $storage
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+az sql server firewall-rule create --resource-group $resourceGroup --server $server --name AllowAzureServices --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
+
+echo "Creating $database..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --edition "GeneralPurpose"
+
+echo "Importing sample database from $container to $database..."
+az sql db import --admin-password $password --admin-user $login --storage-key $key --storage-key-type StorageAccessKey --storage-uri https://$storage.blob.core.windows.net/$container/$bacpac --name $database --resource-group $resourceGroup --server $server
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/import-from-bacpac/sample.bacpac b/sql-database/import-from-bacpac/sample.bacpac
new file mode 100644
index 00000000..40c246c8
Binary files /dev/null and b/sql-database/import-from-bacpac/sample.bacpac differ
diff --git a/sql-database/managed-instance/create-managed-instance.sh b/sql-database/managed-instance/create-managed-instance.sh
new file mode 100644
index 00000000..e292eddc
--- /dev/null
+++ b/sql-database/managed-instance/create-managed-instance.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 2/11/2022
+
+#
+# Create an Azure SQL Managed Instance
+
+#
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="create-managed-instance"
+vNet="msdocs-azuresql-vnet-$randomIdentifier"
+subnet="msdocs-azuresql-subnet-$randomIdentifier"
+nsg="msdocs-azuresql-nsg-$randomIdentifier"
+route="msdocs-azuresql-route-$randomIdentifier"
+instance="msdocs-azuresql-instance-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+dbname="SampleDB"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+#
+
+#
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+#
+
+#
+
+echo "Creating $vNet with $subnet..."
+az network vnet create --name $vNet --resource-group $resourceGroup --location "$location" --address-prefixes 10.0.0.0/16
+az network vnet subnet create --name $subnet --resource-group $resourceGroup --vnet-name $vNet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Sql/managedInstances
+
+echo "Creating $nsg..."
+az network nsg create --name $nsg --resource-group $resourceGroup --location "$location"
+
+az network nsg rule create --name "allow_management_inbound" --nsg-name $nsg --priority 100 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges 9000 9003 1438 1440 1452 --direction Inbound --protocol Tcp --source-address-prefixes "*" --source-port-ranges "*"
+az network nsg rule create --name "allow_misubnet_inbound" --nsg-name $nsg --priority 200 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges "*" --direction Inbound --protocol "*" --source-address-prefixes 10.0.0.0/24 --source-port-ranges "*"
+az network nsg rule create --name "allow_health_probe_inbound" --nsg-name $nsg --priority 300 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges "*" --direction Inbound --protocol "*" --source-address-prefixes AzureLoadBalancer --source-port-ranges "*"
+az network nsg rule create --name "allow_management_outbound" --nsg-name $nsg --priority 1100 --resource-group $resourceGroup --access Allow --destination-address-prefixes AzureCloud --destination-port-ranges 443 12000 --direction Outbound --protocol Tcp --source-address-prefixes 10.0.0.0/24 --source-port-ranges "*"
+az network nsg rule create --name "allow_misubnet_outbound" --nsg-name $nsg --priority 200 --resource-group $resourceGroup --access Allow --destination-address-prefixes 10.0.0.0/24 --destination-port-ranges "*" --direction Outbound --protocol "*" --source-address-prefixes 10.0.0.0/24 --source-port-ranges "*"
+
+echo "Creating $route..."
+az network route-table create --name $route --resource-group $resourceGroup --location "$location"
+
+az network route-table route create --address-prefix 0.0.0.0/0 --name "primaryToMIManagementService" --next-hop-type Internet --resource-group $resourceGroup --route-table-name $route
+az network route-table route create --address-prefix 10.0.0.0/24 --name "ToLocalClusterNode" --next-hop-type VnetLocal --resource-group $resourceGroup --route-table-name $route
+
+echo "Configuring $subnet with $nsg and $route..."
+az network vnet subnet update --name $subnet --network-security-group $nsg --route-table $route --vnet-name $vNet --resource-group $resourceGroup
+
+#
+
+#
+# This step will take awhile to complete. You can monitor deployment progress in the activity log within the Azure portal.
+echo "Creating $instance with $vNet and $subnet..."
+az sql mi create --admin-password $password --admin-user $login --name $instance --resource-group $resourceGroup --subnet $subnet --vnet-name $vNet --location "$location"
+
+#
+
+#
+
+az sql midb create -g $resourceGroup --mi $instance -n $dbname --collation Latin1_General_100_CS_AS_SC
+
+#
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/monitor-and-scale-database/monitor-and-scale-database.sh b/sql-database/monitor-and-scale-database/monitor-and-scale-database.sh
index fc0d4613..21a5ffaa 100644
--- a/sql-database/monitor-and-scale-database/monitor-and-scale-database.sh
+++ b/sql-database/monitor-and-scale-database/monitor-and-scale-database.sh
@@ -1,40 +1,37 @@
-#!/bin/bash
-
-# Set an admin login and password for your database
-export adminlogin=ServerAdmin
-export password=ChangeYourAdminPassword1
-# the logical server name has to be unique in the system
-export servername=server-$RANDOM
-
-# Create a resource group
-az group create \
- --name myResourceGroup \
- -location westeurope
-
-# Create a server
-az sql server create \
- --name $servername \
- --resource-group myResourceGroup \
- --location westeurope \
- --admin-user $adminlogin \
- --admin-password $password
-
-# Create a database
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name mySampleDatabase \
- --service-objective S0
-
-# Monitor database size
-az sql db list-usages \
- --name mySampleDatabase \
- --resource-group myResourceGroup \
- --name $servername
-
-# Scale up database to S1 performance level (create command executes update if DB already exists)
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name mySampleDatabase \
- --service-objective S1
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Monitor and scale a single database in Azure SQL Database
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="monitor-and-scale-database"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server on $resource..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --resource-group $resourceGroup --server $server --name $database --edition GeneralPurpose --family Gen5 --capacity 2
+
+echo "Monitoring size of $database..."
+az sql db list-usages --name $database --resource-group $resourceGroup --server $server
+
+echo "Scaling up $database..." # create command executes update if database already exists
+az sql db create --resource-group $resourceGroup --server $server --name $database --edition GeneralPurpose --family Gen5 --capacity 4
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/move-database-between-pools/move-database-between-pools.sh b/sql-database/move-database-between-pools/move-database-between-pools.sh
index f99ad79b..869408f9 100644
--- a/sql-database/move-database-between-pools/move-database-between-pools.sh
+++ b/sql-database/move-database-between-pools/move-database-between-pools.sh
@@ -1,57 +1,44 @@
-#!/bin/bash
-
-# Set an admin login and password for your database
-export adminlogin=ServerAdmin
-export password=ChangeYourAdminPassword1
-# The logical server name has to be unique in the system
-export servername=server-$RANDOM
-
-# Create a resource group
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create a logical server in the resource group
-az sql server create \
- --name $servername \
- --resource-group myResourceGroup \
- --location westeurope \
- --admin-user $adminlogin \
- --admin-password $password
-
-# Create two pools in the logical server
-az sql elastic-pools create \
- --resource-group myResourceGroup \
- --location westeurope \
- --server $servername \
- --name myFirstPool \
- --dtu 50 \
- --database-dtu-max 20
-az sql elastic-pools create \
- --resource-group myResourceGroup \
- --location westeurope \
- --server $servername \
- --name MySecondPool \
- --dtu 50 \
- --database-dtu-max 50
-
-# Create a database in the first pool
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name mySampleDatabase \
- --elastic-pool-name myFirstPool
-
-# Move the database to the second pool - create command updates the db if it exists
-az sql db create \
- --resource-group myResourceGroup \
- --server-name $servername \
- --name mySampleDatabase \
- --elastic-pool-name mySecondPool
-
-# Move the database to standalone S1 performance level
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name mySampleDatabase \
- --service-objective S1
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Move a database in SQL Database in a SQL elastic pool
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="move-database-between-pools"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+pool="msdocs-azuresql-pool-$randomIdentifier"
+secondaryPool="msdocs-azuresql-secondary-pool-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $pool and $secondaryPool..."
+az sql elastic-pool create --resource-group $resourceGroup --server $server --name $pool --edition GeneralPurpose --family Gen5 --capacity 2
+az sql elastic-pool create --resource-group $resourceGroup --server $server --name $secondaryPool --edition GeneralPurpose --family Gen5 --capacity 2
+
+echo "Creating $database in $pool..."
+az sql db create --resource-group $resourceGroup --server $server --name $database --elastic-pool $pool
+
+echo "Moving $database to $secondaryPool..." # create command updates an existing datatabase
+az sql db create --resource-group $resourceGroup --server $server --name $database --elastic-pool $secondaryPool
+
+echo "Upgrade $database tier..."
+az sql db create --resource-group $resourceGroup --server $server --name $database --service-objective S0
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/restore-database/restore-database.sh b/sql-database/restore-database/restore-database.sh
new file mode 100644
index 00000000..9e0d4f4a
--- /dev/null
+++ b/sql-database/restore-database/restore-database.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Passed validation in Bash in Docker container on Windows 02/11/2021
+
+#
+# Restore a single database in Azure SQL Database to an earlier point in time
+
+# Use Bash rather than Cloud Shell due to its timeout at 20 minutes when no interactive activity
+# In Windows, run Bash in a Docker container to sync time zones between Azure and Bash.
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-sql-rg-$randomIdentifier"
+tag="restore-database"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+restoreServer="restoreServer-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in "$location"..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --resource-group $resourceGroup --server $server --name $database --service-objective S0
+
+# Sleeping commands to wait long enough for automatic backup to be created
+echo "Sleeping..."
+sleep 30m
+
+# Restore a server from backup to a new server
+# To specify a specific point-in-time (in UTC) to restore from, use the ISO8601 format:
+# restorePoint=“2021-07-09T13:10:00Z”
+restorePoint=$(date +%s)
+restorePoint=$(expr $restorePoint - 60)
+restorePoint=$(date -d @$restorePoint +"%Y-%m-%dT%T")
+echo $restorePoint
+
+echo "Restoring to $restoreServer"
+az sql db restore --dest-name $restoreServer --edition Standard --name $database --resource-group $resourceGroup --server $server --service-objective S0 --time $restorePoint
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/sample.bacpac b/sql-database/sample.bacpac
new file mode 100644
index 00000000..40c246c8
Binary files /dev/null and b/sql-database/sample.bacpac differ
diff --git a/sql-database/scale-pool/scale-pool.sh b/sql-database/scale-pool/scale-pool.sh
index 5bce327b..54b935fc 100644
--- a/sql-database/scale-pool/scale-pool.sh
+++ b/sql-database/scale-pool/scale-pool.sh
@@ -1,48 +1,40 @@
-#!/bin/bash
-
-# Set an admin login and password for your database
-export adminlogin=ServerAdmin
-export password=ChangeYourAdminPassword1
-# the logical server name has to be unique in the system
-export servername=server-$RANDOM
-
-# Create a resource group
-az group create \
- --name myResourceGroup \
- --location westeurope
-
-# Create a server
-az sql server create \
- --name $servername \
- --resource-group myResourceGroup \
- --location westeurope \
- --admin-user $adminlogin \
- --admin-password $password
-
-# Create a pool
-az sql elastic-pools create \
- --resource-group myResourceGroup \
- --location westeurope \
- --server $servername \
- --name samplepool \
- --dtu 50 \
- --database-dtu-max 20
-
-# Create two database in the pool
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name myFirstSampleDatabase \
- --elastic-pool-name samplepool
-az sql db create \
- --resource-group myResourceGroup \
- --server $servername \
- --name mySecondSampleDatabase \
- --elastic-pool-name samplepool
-
-# Scale up to the pool to 100 eDTU
-az sql elastic-pools update \
- --resource-group myResourceGroup \
- --server $servername \
- --name samplepool \
- --set dtu=100
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Scale an elastic pool in Azure SQL Database
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="scale-pool"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+databaseAdditional="msdocs-azuresql-additional-db-$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+pool="msdocs-azuresql-pool-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+echo "Creating $server in $location..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+
+echo "Creating $pool..."
+az sql elastic-pool create --resource-group $resourceGroup --server $server --name $pool --edition GeneralPurpose --family Gen5 --capacity 2 --db-max-capacity 1 --db-min-capacity 1 --max-size 512GB
+
+echo "Creating $database and $databaseAdditional on $server in $pool..."
+az sql db create --resource-group $resourceGroup --server $server --name $database --elastic-pool $pool
+az sql db create --resource-group $resourceGroup --server $server --name $databaseAdditional --elastic-pool $pool
+
+echo "Scaling $pool..."
+az sql elastic-pool update --resource-group $resourceGroup --server $server --name $pool --capacity 10 --max-size 1536GB
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-database-failover-group.sh b/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-database-failover-group.sh
new file mode 100644
index 00000000..bd346b47
--- /dev/null
+++ b/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-database-failover-group.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Configure a failover group for a group of databases in Azure SQL Database
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="setup-geodr-and-failover-database-failover-group"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+failoverGroup="msdocs-azuresql-failover-group-$randomIdentifier"
+failoverLocation="Central US"
+failoverResourceGroup="msdocs-azuresql-failover-rg-$randomIdentifier"
+secondaryServer="msdocs-azuresql-secondary-server-$randomIdentifier"
+
+echo "Using resource groups $resourceGroup and $failoverResourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $Location and $failoverResourceGroup in $failoverLocation..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+az group create --name $failoverResourceGroup --location "$failoverLocation"
+
+echo "Creating $server in $location and $secondaryServer in $failoverLocation..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+az sql server create --name $secondaryServer --resource-group $failoverResourceGroup --location "$failoverLocation" --admin-user $login --admin-password $password
+
+echo "Creating $database..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --service-objective S0
+
+echo "Creating failover group $failoverGroup..."
+az sql failover-group create --name $failoverGroup --partner-server $secondaryServer --resource-group $resourceGroup --server $server --partner-resource-group $failoverResourceGroup
+
+echo "Initiating failover..."
+az sql failover-group set-primary --name $failoverGroup --resource-group $failoverResourceGroup --server $secondaryServer
+
+echo "Monitoring failover..."
+az sql failover-group show --name $failoverGroup --resource-group $resourceGroup --server $server
+
+echo "Removing replication on $database..."
+az sql failover-group delete --name $failoverGroup --resource-group $failoverResourceGroup --server $secondaryServer
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $failoverResourceGroup -y
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-elastic-pool.sh b/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-elastic-pool.sh
new file mode 100644
index 00000000..d26d874c
--- /dev/null
+++ b/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-elastic-pool.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Configure active geo-replication for a pooled database in Azure SQL Database
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="setup-geodr-and-failover-elastic-pool"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+pool="pool-$randomIdentifier"
+failoverLocation="Central US"
+failoverResourceGroup="msdocs-azuresql-failover-rg-$randomIdentifier"
+secondaryServer="msdocs-azuresql-secondary-server-$randomIdentifier"
+secondaryPool="msdocs-azuresql-secondary-pool-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location and $failoverResourceGroup in $failoverLocation..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+az group create --name $failoverResourceGroup --location "$failoverLocation"
+
+echo "Creating $server in $location and $secondaryServer in $failoverLocation..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+az sql server create --name $secondaryServer --resource-group $failoverResourceGroup --location "$failoverLocation" --admin-user $login --admin-password $password
+
+echo "Creating $pool on $server and $secondaryPool on $secondaryServer..."
+az sql elastic-pool create --name $pool --resource-group $resourceGroup --server $server --capacity 50 --db-dtu-max 50 --db-dtu-min 10 --edition "Standard"
+az sql elastic-pool create --name $secondaryPool --resource-group $failoverResourceGroup --server $secondaryServer --capacity 50 --db-dtu-max 50 --db-dtu-min 10 --edition "Standard"
+
+echo "Creating $database in $pool..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --elastic-pool $pool
+
+echo "Establishing geo-replication for $database between $server and $secondaryServer..."
+az sql db replica create --name $database --partner-server $secondaryServer --resource-group $resourceGroup --server $server --elastic-pool $secondaryPool --partner-resource-group $failoverResourceGroup
+
+echo "Initiating failover to $secondaryServer..."
+az sql db replica set-primary --name $database --resource-group $failoverResourceGroup --server $secondaryServer
+
+echo "Monitoring health of $database on $secondaryServer..."
+az sql db replica list-links --name $database --resource-group $failoverResourceGroup --server $secondaryServer
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $failoverResourceGroup -y
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-single-database.sh b/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-single-database.sh
new file mode 100644
index 00000000..cd32a896
--- /dev/null
+++ b/sql-database/setup-geodr-and-failover/setup-geodr-and-failover-single-database.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 12/01/2021
+
+#
+# Configure active geo-replication for a single database in Azure SQL Database
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="setup-geodr-and-failover-single-database"
+server="msdocs-azuresql-server-$randomIdentifier"
+database="msdocsazuresqldb$randomIdentifier"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+failoverResourceGroup="msdocs-azuresql-failover-rg-$randomIdentifier"
+failoverLocation="Central US"
+secondaryServer="msdocs-azuresql-secondary-server-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+echo "Creating $resourceGroup in $location and $failoverResourceGroup in $failoverLocation..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+az group create --name $failoverResourceGroup --location "$failoverLocation"
+
+echo "Creating $server in $location and $secondaryServer in $failoverLocation..."
+az sql server create --name $server --resource-group $resourceGroup --location "$location" --admin-user $login --admin-password $password
+az sql server create --name $secondaryServer --resource-group $failoverResourceGroup --location "$failoverLocation" --admin-user $login --admin-password $password
+
+echo "Creating $database on $server..."
+az sql db create --name $database --resource-group $resourceGroup --server $server --service-objective S0
+
+echo "Establishing geo-replication on $database..."
+az sql db replica create --name $database --partner-server $secondaryServer --resource-group $resourceGroup --server $server --partner-resource-group $failoverResourceGroup
+az sql db replica list-links --name $database --resource-group $resourceGroup --server $server
+
+echo "Initiating failover..."
+az sql db replica set-primary --name $database --resource-group $failoverResourceGroup --server $secondaryServer
+
+echo "Monitoring health of $database..."
+az sql db replica list-links --name $database --resource-group $failoverResourceGroup --server $secondaryServer
+
+echo "Removing replication link after failover..."
+az sql db replica delete-link --resource-group $failoverResourceGroup --server $secondaryServer --name $database --partner-server $server --yes
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $failoverResourceGroup -y
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/sql-managed-instance-restore-geo-backup/restore-geo-backup-cli.sh b/sql-database/sql-managed-instance-restore-geo-backup/restore-geo-backup-cli.sh
new file mode 100644
index 00000000..4e18f08b
--- /dev/null
+++ b/sql-database/sql-managed-instance-restore-geo-backup/restore-geo-backup-cli.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Passed validation in Bash in Docker container on Windows 02/11/2021
+
+#
+# Restore a Managed Instance database to another geo-region
+# Use Bash rather than Cloud Shell due to its timeout at 20 minutes when no interactive activity
+# In Windows, run Bash in a Docker container to sync time zones between Azure and Bash.
+
+# Run this script after running the script in https://docs.microsoft.com/azure/azure-sql/managed-instance/scripts/create-configure-managed-instance-cli twice to create two managed instances
+# Provide the values for these three variables before running this rest of this script
+
+# Variable block for additional parameter values
+$instance = "" # add instance here
+$targetInstance = "" # add target instance here
+$resourceGroup = "" # add resource here
+
+let "randomIdentifier=$RANDOM*$RANDOM"
+$managedDatabase = "managedDatabase-$randomIdentifier"
+
+echo "Creating $($managedDatabase) on $($instance)..."
+az sql midb create -g $resourceGroup --mi $instance -n $managedDatabase
+
+# Sleeping commands to wait long enough for automatic backup to be created
+echo "Sleeping..."
+sleep 40m
+
+# To specify a specific point-in-time (in UTC) to restore from, use the ISO8601 format:
+# restorePoint=“2021-07-09T13:10:00Z”
+restorePoint=$(date +%s)
+restorePoint=$(expr $restorePoint - 60)
+restorePoint=$(date -d @$restorePoint +"%Y-%m-%dT%T")
+echo $restorePoint
+
+echo "Restoring $($managedDatabase) to $($targetInstance)..."
+az sql midb restore -g $resourceGroup --mi $instance -n $managedDatabase --dest-name $targetInstance --time $restorePoint
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/sql-database/transparent-data-encryption/setup-tde-byok-sqlmi.sh b/sql-database/transparent-data-encryption/setup-tde-byok-sqlmi.sh
new file mode 100644
index 00000000..26c76503
--- /dev/null
+++ b/sql-database/transparent-data-encryption/setup-tde-byok-sqlmi.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Passed validation in Bash in Docker container on Windows 12/01/2021
+
+#
+# Manage Transparent Data Encryption in a Managed Instance using your own key from Azure Key Vault
+
+# Run this script after the script in https://docs.microsoft.com/azure/azure-sql/managed-instance/scripts/create-configure-managed-instance-cli creates a managed instance.
+# You can use the same variables in both scripts/
+# If running this script against a different existing instance, uncomment and add appropriate values to next 3 lines of code
+# let "randomIdentifier=$RANDOM*$RANDOM"
+# instance="" # add instance here
+# resourceGroup="" # add resource here
+
+# Variable block
+location="East US"
+vault="msdocssqlvault$randomIdentifier"
+key="msdocs-azuresql-key-$randomIdentifier"
+
+# echo assigning identity to service principal in the instance
+az sql mi update --name $instance --resource-group $resourceGroup --assign-identity
+
+echo "Creating $vault..."
+az keyvault create --name $vault --resource-group $resourceGroup --location "$location"
+
+echo "Getting service principal id and setting policy on $vault..."
+instanceId=$(az sql mi show --name $instance --resource-group $resourceGroup --query identity.principalId --output tsv)
+
+echo $instanceId
+az keyvault set-policy --name $vault --object-id $instanceId --key-permissions get unwrapKey wrapKey
+
+echo "Creating $key..."
+az keyvault key create --name $key --vault-name $vault --size 2048
+
+# keyPath="C:\yourFolder\yourCert.pfx"
+# keyPassword="yourPassword"
+# az keyvault certificate import --file $keyPath --name $key --vault-name $vault --password $keyPassword
+
+echo "Setting security on $instance with $key..."
+keyId=$(az keyvault key show --name $key --vault-name $vault -o json --query key.kid | tr -d '"')
+
+az sql mi key create --kid $keyId --managed-instance $instance --resource-group $resourceGroup
+az sql mi tde-key set --server-key-type AzureKeyVault --kid $keyId --managed-instance $instance --resource-group $resourceGroup
+
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/storage/calculate-container-size/calculate-container-size.sh b/storage/calculate-container-size/calculate-container-size.sh
index 90407efa..ff1ed70d 100644
--- a/storage/calculate-container-size/calculate-container-size.sh
+++ b/storage/calculate-container-size/calculate-container-size.sh
@@ -1,36 +1,61 @@
#!/bin/bash
-export AZURE_STORAGE_ACCOUNT=
-export AZURE_STORAGE_ACCESS_KEY=
+# Passed validation in Cloud Shell 03/01/2022
+
+#
+# Calculate container size
+
+# Variables for storage
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="calculate-container-size"
+storage="msdocsstorage$randomIdentifier"
+container="msdocs-storage-container-$randomIdentifier"
# Create a resource group
-az group create --name myResourceGroup --location eastus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create storage account
+echo "Creating $storage..."
+az storage account create --name $storage --resource-group $resourceGroup --location "$location" --sku Standard_LRS
# Create a container
-az storage container create --name mycontainer
+echo "Creating $container on $storage..."
+key=$(az storage account keys list --account-name $storage --resource-group $resourceGroup -o json --query [0].value | tr -d '"')
+
+az storage container create --name $container --account-key $key --account-name $storage #--public-access container
# Create sample files to upload as blobs
for i in `seq 1 3`; do
- echo $RANDOM > container_size_sample_file_$i.txt
+ echo $randomIdentifier > container_size_sample_file_$i.txt
done
# Upload sample files to container
az storage blob upload-batch \
--pattern "container_size_sample_file_*.txt" \
--source . \
- --destination mycontainer
+ --destination $container \
+ --account-key $key \
+ --account-name $storage
# Calculate total size of container. Use the --query parameter to display only
# blob contentLength and output it in TSV format so only the values are
# returned. Then pipe the results to the paste and bc utilities to total the
-# size of the blobs in the container.
+# size of the blobs in the container. The bc utility is not supported in Cloud Shell.
bytes=`az storage blob list \
- --container-name mycontainer \
+ --container-name $container \
+ --account-key $key \
+ --account-name $storage \
--query "[*].[properties.contentLength]" \
- --output tsv |
- paste --serial --delimiters=+ | bc`
+ --output tsv | paste -s -d+ | bc`
# Display total bytes
echo "Total bytes in container: $bytes"
# Delete the sample files created by this script
rm container_size_sample_file_*.txt
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/storage/delete-containers-by-prefix/delete-containers-by-prefix.sh b/storage/delete-containers-by-prefix/delete-containers-by-prefix.sh
index 3ba56766..53f3666c 100644
--- a/storage/delete-containers-by-prefix/delete-containers-by-prefix.sh
+++ b/storage/delete-containers-by-prefix/delete-containers-by-prefix.sh
@@ -1,24 +1,48 @@
#!/bin/bash
-export AZURE_STORAGE_ACCOUNT=
-export AZURE_STORAGE_ACCESS_KEY=
+# Passed validation in Cloud Shell 03/01/2022
+
+#
+# Delete containers by prefix
+
+# Variables for storage
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="delete-containers-by-prefix"
+storage="msdocsstorage$randomIdentifier"
+container1="msdocs-test1-storage-container-$randomIdentifier"
+container2="msdocs-test2-storage-container-test2-$randomIdentifier"
+containerProd="msdocs-prod1-storage-$randomIdentifier"
# Create a resource group
-az group create --name myResourceGroup --location eastus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create storage account
+echo "Creating $storage..."
+az storage account create --name $storage --resource-group $resourceGroup --location "$location" --sku Standard_LRS
# Create some test containers
-az storage container create --name test-container-001
-az storage container create --name test-container-002
-az storage container create --name production-container-001
+echo "Creating $container1 $container2 and $containerProd on $storage..."
+key=$(az storage account keys list --account-name $storage --resource-group $resourceGroup -o json --query [0].value | tr -d '"')
-# List only the containers with a specific prefix
-az storage container list --prefix "test-" --query "[*].[name]" --output tsv
+az storage container create --name $container1 --account-key $key --account-name $storage #--public-access container
+az storage container create --name $container2 --account-key $key --account-name $storage #--public-access container
+az storage container create --name $containerProd --account-key $key --account-name $storage #--public-access container
-echo "Deleting test- containers..."
+# List only the containers with a specific prefix
+echo "List container with msdocs-test prefix"
+az storage container list --account-key $key --account-name $storage --prefix "msdocs-test" --query "[*].[name]" --output tsv
# Delete
-for container in `az storage container list --prefix "test-" --query "[*].[name]" --output tsv`; do
- az storage container delete --name $container
+echo "Deleting msdocs-test containers..."
+for container in `az storage container list --account-key $key --account-name $storage --prefix "msdocs-test" --query "[*].[name]" --output tsv`; do
+ az storage container delete --account-key $key --account-name $storage --name $container
done
-echo "Remaining containers:"
-az storage container list --output table
\ No newline at end of file
+echo "Remaining containers..."
+az storage container list --account-key $key --account-name $storage --output table
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/storage/rotate-storage-account-keys/rotate-storage-account-keys.sh b/storage/rotate-storage-account-keys/rotate-storage-account-keys.sh
index 26c0f129..ffc509fc 100644
--- a/storage/rotate-storage-account-keys/rotate-storage-account-keys.sh
+++ b/storage/rotate-storage-account-keys/rotate-storage-account-keys.sh
@@ -1,29 +1,41 @@
#!/bin/bash
+# Passed validation in Cloud Shell 03/01/2022
+
+#
+# Rotate storage account keys
+
+# Variables for storage
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-azuresql-rg-$randomIdentifier"
+tag="rotate-storage-account-keys"
+storage="msdocsstorage$randomIdentifier"
# Create a resource group
-az group create --name myResourceGroup --location eastus
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a general-purpose standard storage account
-az storage account create \
- --name mystorageaccount \
- --resource-group myResourceGroup \
- --location eastus \
- --sku Standard_RAGRS \
- --encryption blob
+echo "Creating $storage..."
+az storage account create --name $storage --resource-group $resourceGroup --location "$location" --sku Standard_RAGRS --encryption-services blob
# List the storage account access keys
az storage account keys list \
- --resource-group myResourceGroup \
- --account-name mystorageaccount
+ --resource-group $resourceGroup \
+ --account-name $storage
# Renew (rotate) the PRIMARY access key
az storage account keys renew \
- --resource-group myResourceGroup \
- --account-name mystorageaccount \
+ --resource-group $resourceGroup \
+ --account-name $storage \
--key primary
# Renew (rotate) the SECONDARY access key
az storage account keys renew \
- --resource-group myResourceGroup \
- --account-name mystorageaccount \
+ --resource-group $resourceGroup \
+ --account-name $storage \
--key secondary
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/traffic-manager/direct-traffic-for-increased-application-availability/direct-traffic-for-increased-application-availability.sh b/traffic-manager/direct-traffic-for-increased-application-availability/direct-traffic-for-increased-application-availability.sh
index 5f825d29..5221b64c 100644
--- a/traffic-manager/direct-traffic-for-increased-application-availability/direct-traffic-for-increased-application-availability.sh
+++ b/traffic-manager/direct-traffic-for-increased-application-availability/direct-traffic-for-increased-application-availability.sh
@@ -1,89 +1,111 @@
#!/bin/bash
+# Passed validation in Cloud Shell on 2/28/2022
-RgName1="MyResourceGroup1"
-RgName2="MyResourceGroup2"
-Location1="eastus"
-Location2="westeurope"
+#
+# Route traffic for high availability of applications
-# The values of the variables below must be unique (replace with your own names).
-WebApp="MyWebApp"
-WebAppL1="MyWebAppL1"
-WebAppL2="MyWebAppL2"
+# Variables for Traffic Manager resources
+let "randomIdentifier=$RANDOM*$RANDOM"
+location1="East US"
+location2="West Europe"
+resourceGroup1="msdocs-tm-rg1-$randomIdentifier"
+resourceGroup2="msdocs-tm-rg2-$randomIdentifier"
+tag="direct-traffic-for-increased-application-availability"
+webApp="msdocs-webapp-tm-$randomIdentifier"
+webAppL1="msdocs-tm-webapp-L1-$randomIdentifier"
+webAppL2="msdocs-tm-webapp-L2-$randomIdentifier"
+trafficManagerProfile="msdocs-traffic-manager-profile-$randomIdentifier"
-# Create a resource group in location one.
-az group create \
- --name $RgName1 \
- --location $Location1
+# Create a resource group in location one
+echo "Creating $resourceGroup1 in $location1..."
+az group create --name $resourceGroup1 --location "$location1" --tags $tag
-# Create a resource group in location two.
-az group create \
- --name $RgName2 \
- --location $Location2
+# Create a resource group in location two
+echo "Creating $resourceGroup2 in $location2..."
+az group create --name $resourceGroup2 --location "$location2" --tags $tag
# Create a website deployed from GitHub in both regions (replace with your own GitHub URL).
gitrepo="https://github.com/Azure-Samples/app-service-web-dotnet-get-started.git"
# Create a hosting plan and website and deploy it in location one (requires Standard 1 minimum SKU).
+echo "Creating $webAppL1 app service plan"
az appservice plan create \
- --name $WebAppL1 \
- --resource-group $RgName1 \
+ --name $webAppL1 \
+ --resource-group $resourceGroup1 \
--sku S1
-az appservice web create \
- --name $WebAppL1 \
- --resource-group $RgName1 \
- --plan $WebAppL1
-az appservice web source-control config \
- --name $WebAppL1 \
- --resource-group $RgName1 \
+
+echo "Creating $webAppL1 web app"
+az webapp create \
+ --name $webAppL1 \
+ --resource-group $resourceGroup1 \
+ --plan $webAppL1
+
+echo "Deploying $gitrepo to $webAppL1"
+az webapp deployment source config \
+ --name $webAppL1 \
+ --resource-group $resourceGroup1 \
--repo-url $gitrepo \
--branch master \
--manual-integration
# Create a hosting plan and website and deploy it in westus (requires Standard 1 minimum SKU).
+echo "Creating $webAppL2 app service plan"
az appservice plan create \
- --name $WebAppL2 \
- --resource-group $RgName2 \
+ --name $webAppL2 \
+ --resource-group $resourceGroup2 \
--sku S1
-az appservice web create \
- --name $WebAppL2 \
- --resource-group $RgName2 \
- --plan $WebAppL2
-az appservice web source-control config \
- --name $WebAppL2 \
- --resource-group $RgName2 \
+
+echo "Creating $webAppL2 web app"
+az webapp create \
+ --name $webAppL2 \
+ --resource-group $resourceGroup2 \
+ --plan $webAppL2
+
+echo "Deploying $gitrepo to $webAppL2"
+az webapp deployment source config \
+ --name $webAppL2 \
+ --resource-group $resourceGroup2 \
--repo-url $gitrepo \
--branch master --manual-integration
# Create a Traffic Manager profile.
+echo "Creating $trafficManagerProfile for $webApp"
az network traffic-manager profile create \
- --name MyTrafficManagerProfile \
- --resource-group $RgName1 \
+ --name $trafficManagerProfile \
+ --resource-group $resourceGroup1 \
--routing-method Priority \
- --unique-dns-name $WebApp
+ --unique-dns-name $webApp
-# Create an endpoint for the location one website deployment and set it as the priority target.
-L1Id=$(az appservice web show \
- --resource-group $RgName1 \
- --name $WebAppL1 \
+# Create a traffic manager endpoint for the location one website deployment and set it as the priority target.
+echo "Create traffic manager endpoint for $webAppL1"
+l1Id=$(az webapp show \
+ --resource-group $resourceGroup1 \
+ --name $webAppL1 \
--query id \
--out tsv)
az network traffic-manager endpoint create \
- --name MyEndPoint1 \
- --profile-name MyTrafficManagerProfile \
- --resource-group $RgName1 \
+ --name endPoint1 \
+ --profile-name $trafficManagerProfile \
+ --resource-group $resourceGroup1 \
--type azureEndpoints \
--priority 1 \
- --target-resource-id $L1Id
+ --target-resource-id $l1Id
-# Create an endpoint for the location two website deployment and set it as the secondary target.
-L2Id=$(az appservice web show \
- --resource-group $RgName2 \
- --name $WebAppL2 \
+# Create a traffic manager endpoint for the location two website deployment and set it as the secondary target.
+echo "Create traffic manager endpoint for $webAppL1"
+l2Id=$(az webapp show \
+ --resource-group $resourceGroup2 \
+ --name $webAppL2 \
--query id --out tsv)
az network traffic-manager endpoint create \
- --name MyEndPoint2 \
- --profile-name MyTrafficManagerProfile \
- --resource-group $RgName1 \
+ --name endPoint2 \
+ --profile-name $trafficManagerProfile \
+ --resource-group $resourceGroup1 \
--type azureEndpoints \
--priority 2 \
- --target-resource-id $L2Id
+ --target-resource-id $l2Id
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup1 -y
+# az group delete --name $resourceGroup2 -y
diff --git a/virtual-machine-scale-sets/auto-scale-host-metrics/auto-scale-host-metrics.sh b/virtual-machine-scale-sets/auto-scale-host-metrics/auto-scale-host-metrics.sh
new file mode 100644
index 00000000..c3f146e8
--- /dev/null
+++ b/virtual-machine-scale-sets/auto-scale-host-metrics/auto-scale-host-metrics.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Automatically scale a virtual machine scale set
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="auto-scale-host-metrics-vmss"
+image="Ubuntu2204"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+instanceCount="2"
+login="azureuser"
+autoscale="autoscale"
+minCount="2"
+maxCount="10"
+count="2"
+scaleOut="3"
+scaleIn="1"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a scale set
+# Network resources such as an Azure load balancer are automatically created
+echo "Creating $scaleSet with $instanceCount instances"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image $image --upgrade-policy-mode $upgradePolicyMode --instance-count $instanceCount --admin-username $login --generate-ssh-keys
+
+# Define an autoscale profile
+# The following script sets the default, and minimum, capacity of *2* VM instances, and a maximum of *10*
+echo "Setting an autoscale profile with the default, and minimum, capacity of 2 VM instances, and a maximum of 10"
+az monitor autoscale create --resource-group $resourceGroup --resource=$scaleSet --resource-type Microsoft.Compute/virtualMachineScaleSets --name $autoscale --min-count $minCount --max-count $maxCount --count $count
+
+# Create a rule to autoscale out
+# The following script increases the number of VM instances in a scale set when the average CPU load
+# is greater than 70% over a 5-minute period.
+# When the rule triggers, the number of VM instances is increased by three.
+echo "Creating an autoscale out rule"
+az monitor autoscale rule create --resource-group $resourceGroup --autoscale-name $autoscale --condition "Percentage CPU > 70 avg 5m" --scale out $scaleOut
+
+# Create a rule to autoscale in
+# The following script decreases the number of VM instances in a scale set when the average CPU load
+# then drops below 30% over a 5-minute period
+echo "Creating an autoscale in rule"
+az monitor autoscale rule create --resource-group $resourceGroup --autoscale-name $autoscale --condition "Percentage CPU < 30 avg 5m" --scale in $scaleIn
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
+
+# The script is used in the following file, adding or removing lines may require you update the range value in this files
+# articles\virtual-machine-scale-sets\tutorial-autoscale-cli.md
diff --git a/virtual-machine-scale-sets/create-single-availability-zone/create-single-availability-zone.sh b/virtual-machine-scale-sets/create-single-availability-zone/create-single-availability-zone.sh
new file mode 100644
index 00000000..c9ec4238
--- /dev/null
+++ b/virtual-machine-scale-sets/create-single-availability-zone/create-single-availability-zone.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Create a single-zone virtual machine scale set
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="create-single-availability-zone-vmss"
+image="Ubuntu2204"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+instanceCount="2"
+login="azureuser"
+zones="1"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a scale set in Availability Zone 1
+# This command also creates a 'Standard' SKU public IP address and load balancer
+# For the Load Balancer Standard SKU, a Network Security Group and rules are also created
+echo "Creating $scaleSet with $instanceCount instances"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image $image --upgrade-policy-mode $upgradePolicyMode --instance-count $instanceCount --admin-username $login --generate-ssh-keys --zones $zones
+
+# Apply the Custom Script Extension that installs a basic Nginx webserver
+echo "Installing a basic Nginx webserver"
+az vmss extension set --publisher Microsoft.Azure.Extensions --version 2.0 --name CustomScript --resource-group $resourceGroup --vmss-name $scaleSet --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"],"commandToExecute":"./automate_nginx.sh"}'
+
+# Output the public IP address to access the site in a web browser
+echo "Displaying the public IP address"
+az network public-ip show --resource-group $resourceGroup --name $scaleSet"LBPublicIP" --query [ipAddress] --output tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-machine-scale-sets/create-zone-redundant-scale-set/create-zone-redundant-scale-set.sh b/virtual-machine-scale-sets/create-zone-redundant-scale-set/create-zone-redundant-scale-set.sh
new file mode 100644
index 00000000..921b9704
--- /dev/null
+++ b/virtual-machine-scale-sets/create-zone-redundant-scale-set/create-zone-redundant-scale-set.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Create a zone-redundant virtual machine scale set
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="create-zone-redundant-scale-set-vmss"
+image="Ubuntu2204"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+instanceCount="2"
+login="azureuser"
+zones="1 2 3"
+nsgRule="msdocs-nsg-rule-vmss"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a zone-redundant scale set across zones 1, 2, and 3
+# This command also creates a 'Standard' SKU public IP address and load balancer
+# For the Load Balancer Standard SKU, a Network Security Group and rules are also created
+echo "Creating $scaleSet with $instanceCount instances"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image $image --upgrade-policy-mode $upgradePolicyMode --instance-count $instanceCount --admin-username $login --generate-ssh-keys --zones $zones
+
+# Apply the Custom Script Extension that installs a basic Nginx webserver
+echo "Installing a basic Nginx webserver"
+az vmss extension set --publisher Microsoft.Azure.Extensions --version 2.0 --name CustomScript --resource-group $resourceGroup --vmss-name $scaleSet --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"],"commandToExecute":"./automate_nginx.sh"}'
+
+# Create a Network Security Group rule to allow TCP port 80
+az network nsg rule create --resource-group $resourceGroup --nsg-name $scaleSet"NSG" --name http --protocol Tcp --direction Inbound --access allow --priority 1001 --destination-port-range 80
+
+# Output the public IP address to access the site in a web browser
+az network public-ip show --resource-group $resourceGroup --name $scaleSet"LBPublicIP" --query [ipAddress] --output tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-machine-scale-sets/install-apps/install-apps.sh b/virtual-machine-scale-sets/install-apps/install-apps.sh
new file mode 100644
index 00000000..bda4f880
--- /dev/null
+++ b/virtual-machine-scale-sets/install-apps/install-apps.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Install applications into a virtual machine scale set
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="install-apps-vmss"
+image="Ubuntu2204"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+instanceCount="2"
+login="azureuser"
+nlbWebRule="msdocs-nlb-web-rule-vmss"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a scale set
+# Network resources such as an Azure load balancer are automatically created
+echo "Creating $scaleSet with $instanceCount instances"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image $image --upgrade-policy-mode $upgradePolicyMode --instance-count $instanceCount --admin-username $login --generate-ssh-keys
+
+# Install the Azure Custom Script Extension to run an install script
+echo "Installing a basic Nginx webserver"
+az vmss extension set --publisher Microsoft.Azure.Extensions --version 2.0 --name CustomScript --resource-group $resourceGroup --vmss-name $scaleSet --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"],"commandToExecute":"./automate_nginx.sh"}'
+
+# Create a load balancer rule to allow web traffic to reach VM instances
+az network lb rule create --resource-group $resourceGroup --name $nlbWebRule --lb-name $scaleSet"LB" --backend-pool-name $scaleSet"LBBEPool" --backend-port 80 --frontend-ip-name loadBalancerFrontEnd --frontend-port 80 --protocol tcp
+
+# Output the public IP address to access the site in a web browser
+az network public-ip show --resource-group $resourceGroup --name $scaleSet"LBPublicIP" --query [ipAddress] --output tsv
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-machine-scale-sets/simple-scale-set/simple-scale-set.sh b/virtual-machine-scale-sets/simple-scale-set/simple-scale-set.sh
new file mode 100644
index 00000000..8f907b7b
--- /dev/null
+++ b/virtual-machine-scale-sets/simple-scale-set/simple-scale-set.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Create a virtual machine scale set
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="simple-scale-set-vmss"
+image="Ubuntu2204"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+instanceCount="2"
+login="azureuser"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a scale set
+# Network resources such as an Azure load balancer are automatically created
+echo "Creating $scaleSet with $instanceCount instances"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image $image --upgrade-policy-mode $upgradePolicyMode --instance-count $instanceCount --admin-username $login --generate-ssh-keys
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-machine-scale-sets/use-custom-vm-image/create-use-custom-vm-image.sh b/virtual-machine-scale-sets/use-custom-vm-image/create-use-custom-vm-image.sh
new file mode 100644
index 00000000..76e9fd75
--- /dev/null
+++ b/virtual-machine-scale-sets/use-custom-vm-image/create-use-custom-vm-image.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Create a virtual machine scale set from a custom VM image
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+subcriptionId=$(az account show --query id -o tsv)
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="create-use-custom-image-vmss"
+image="Ubuntu2204"
+virtualMachine="msdocs-vm-$randomIdentifier"
+login="azureuser"
+imageGallery="msdocsimagegalleryvmss$randomIdentifier"
+imageDefinition="msdocs-image-definition-vmss-$randomIdentifier"
+imageVersion="msdocs-image-version-$randomIdentifier"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create virtual machine from Ubuntu2204 image
+echo "Create $virtualMachine from $image image"
+az vm create --resource-group $resourceGroup --name $virtualMachine --image $image --admin-username $login --generate-ssh-keys --public-ip-sku Standard
+
+# Create a resource group for images
+# echo "Creating $resourceGroup in $location..."
+# az group create --name $resourceGroup --location "$location" --tags $tag
+# az group create --name myGalleryRG --location eastus
+
+# Create an image gallery
+echo "Creating $imageGallery"
+az sig create --resource-group $resourceGroup \
+--gallery-name $imageGallery
+
+# Create image definition
+echo "Creating $imageDefinition from $imageGallery"
+az sig image-definition create --resource-group $resourceGroup \
+--gallery-name $imageGallery \
+--gallery-image-definition $imageDefinition \
+--publisher myPublisher \
+--offer myOffer \
+--sku mySKU \
+--os-type Linux \
+--os-state specialized
+# az sig image-definition create --resource-group myGalleryRG --gallery-name myGallery --gallery-image-definition myImageDefinition --publisher myPublisher --offer myOffer --sku mySKU --os-type Linux --os-state specialized
+
+# Create image version
+echo "Creating $imageVersion from $imageDefinition"
+az sig image-version create --resource-group $resourceGroup --gallery-name $imageGallery --gallery-image-definition $imageDefinition --gallery-image-version 1.0.0 --target-regions "southcentralus=1" "eastus=1" --managed-image "/subscriptions/$subcriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Compute/virtualMachines/$virtualMachine"
+
+# Create a scale set from custom image
+echo "Creating $scaleSet from custom image"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image "/subscriptions/$subcriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Compute/galleries/$imageGallery/images/$imageDefinition" --specialized
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
+
diff --git a/virtual-machine-scale-sets/use-data-disks/use-data-disks.sh b/virtual-machine-scale-sets/use-data-disks/use-data-disks.sh
new file mode 100644
index 00000000..7d104b83
--- /dev/null
+++ b/virtual-machine-scale-sets/use-data-disks/use-data-disks.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Passed validation in Cloud Shell on 1/27/2022
+
+#
+# Attach and use data disks with a virtual machine scale set
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-vmss-rg-$randomIdentifier"
+tag="use-data-disks-vmss"
+image="Ubuntu2204"
+scaleSet="msdocs-scaleSet-$randomIdentifier"
+upgradePolicyMode="automatic"
+instanceCount="2"
+login="azureuser"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a scale set
+# Network resources such as an Azure load balancer are automatically created
+# Two data disks are created and attach - a 64Gb disk and a 128Gb disk
+echo "Creating $scaleSet with $instanceCount instances"
+az vmss create --resource-group $resourceGroup --name $scaleSet --image $image --upgrade-policy-mode $upgradePolicyMode --instance-count $instanceCount --admin-username $login --generate-ssh-keys --data-disk-sizes-gb 64 128
+
+# Executes a script from a GitHub sample repo on each VM instance that prepares all the raw attached data disks
+az vmss extension set --publisher Microsoft.Azure.Extensions --version 2.0 --name CustomScript --resource-group $resourceGroup --vmss-name $scaleSet --settings '{"fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/prepare_vm_disks.sh"],"commandToExecute":"./prepare_vm_disks.sh"}'
+
+# See the disks for the scale set
+echo "Showing the disks for the scale set"
+az vmss show --resource-group $resourceGroup --name $scaleSet --query virtualMachineProfile.storageProfile.dataDisks
+
+# Attach an additional 128 gb data disk
+echo "Attaching additional 128 gb data disk to $scaleSet"
+az vmss disk attach --resource-group $resourceGroup --vmss-name $scaleSet --size-gb 128
+
+# See the disks for your virtual machine
+echo "Showing the disks for $scaleSet"
+az vmss show --resource-group $resourceGroup --name $scaleSet --query virtualMachineProfile.storageProfile.dataDisks
+
+# Remove a managed disk from the scale set
+echo "Removing a managed disk from $scaleSet"
+az vmss disk detach --resource-group $resourceGroup --vmss-name $scaleSet --lun 2
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-machine/capture-vm-to-image/capture-vm-to-image.sh b/virtual-machine/capture-vm-to-image/capture-vm-to-image.sh
deleted file mode 100644
index 1eb0dad4..00000000
--- a/virtual-machine/capture-vm-to-image/capture-vm-to-image.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-rgname="capturerg"
-vmname="capturevm"
-
-# Get the NIC Id of the network interface attached to the VM
-nicid=$(az vm show -g $rgname -n $vmname --query [networkProfile.networkInterfaces[0].id] -o tsv)
-
-# For the NIC we got above, find the public IP address ID
-pipid=$(az network nic show --ids $nicid --query [ipConfigurations[0].publicIpAddress.id] -o tsv)
-
-# From the Public Ip address Id find the actual public ip
-az network public-ip show --ids $pipid --query [ipAddress] -o tsv
-
-# login to the VM
-ssh myadmin@13.64.76.146
-
-# Generalize the VM
-sudo waagent -deprovision+user
-
-# Deallocate
-az vm deallocate -g $rgname -n $vmname
-
-# Tell Azure that the VM has been generalized
-az vm generalize -g $rgname -n $vmname
-
-# Capture the VM which outputs a template. Note the OS Disk Uri and Os Disk type as we'll use it in the next command
-az vm capture -g $rgname -n $vmname --vhd-name-prefix capturekay
-
-# Create a new VM from the captured VM
-az vm create -n "newvm" -g $rgname --admin-username myadmin --admin-password Password@1234 --public-ip-address "newimagevmkay" --image https://vhd14860889176058.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/capturekay-osDisk.563aa2ca-bcfb-4e7d-8da1-45133add0ff6.vhd --authentication-type password --size Standard_DS2_v2 --custom-os-disk-type linux
diff --git a/virtual-machine/copy-managed-disks-to-same-or-different-subscription/copy-managed-disks-to-same-or-different-subscription.sh b/virtual-machine/copy-managed-disks-to-same-or-different-subscription/copy-managed-disks-to-same-or-different-subscription.sh
index 19821f29..1d75f3bc 100644
--- a/virtual-machine/copy-managed-disks-to-same-or-different-subscription/copy-managed-disks-to-same-or-different-subscription.sh
+++ b/virtual-machine/copy-managed-disks-to-same-or-different-subscription/copy-managed-disks-to-same-or-different-subscription.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id of the subscription where managed disk exists
-sourceSubscriptionId=dd80b94e-0463-4a65-8d04-c94f403879dc
+sourceSubscriptionId=""
#Provide the name of your resource group where managed disk exists
sourceResourceGroupName=mySourceResourceGroupName
@@ -27,4 +30,4 @@ az account set --subscription $targetSubscriptionId
#Copy managed disk to different subscription using managed disk Id
az disk create --resource-group $targetResourceGroupName --name $managedDiskName --source $managedDiskId
-
+#
diff --git a/virtual-machine/copy-managed-disks-vhd-to-storage-account/copy-managed-disks-vhd-to-storage-account.sh b/virtual-machine/copy-managed-disks-vhd-to-storage-account/copy-managed-disks-vhd-to-storage-account.sh
new file mode 100644
index 00000000..2ec12f1e
--- /dev/null
+++ b/virtual-machine/copy-managed-disks-vhd-to-storage-account/copy-managed-disks-vhd-to-storage-account.sh
@@ -0,0 +1,34 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
+#Provide the subscription Id where managed disk is created
+subscriptionId=""
+
+#Provide the name of your resource group where managed disk is created
+resourceGroupName=myResourceGroupName
+
+#Provide the managed disk name
+diskName=myDiskName
+
+#Provide Shared Access Signature (SAS) expiry duration in seconds e.g. 3600.
+#Know more about SAS here: https://docs.microsoft.com/azure/storage/storage-dotnet-shared-access-signature-part-1
+sasExpiryDuration=3600
+
+#Provide storage account name where you want to copy the underlying VHD file of the managed disk.
+storageAccountName=mystorageaccountname
+
+#Name of the storage container where the downloaded VHD will be stored
+storageContainerName=mystoragecontainername
+
+#Provide the key of the storage account where you want to copy the VHD
+storageAccountKey=mystorageaccountkey
+
+#Provide the name of the destination VHD file to which the VHD of the managed disk will be copied.
+destinationVHDFileName=myvhdfilename.vhd
+
+az account set --subscription $subscriptionId
+
+sas=$(az disk grant-access --resource-group $resourceGroupName --name $diskName --duration-in-seconds $sasExpiryDuration --query [accessSas] -o tsv)
+
+az storage blob copy start --destination-blob $destinationVHDFileName --destination-container $storageContainerName --account-name $storageAccountName --account-key $storageAccountKey --source-uri $sas
+#
diff --git a/virtual-machine/copy-snapshot-to-same-or-different-subscription/copy-snapshot-to-same-or-different-subscription.sh b/virtual-machine/copy-snapshot-to-same-or-different-subscription/copy-snapshot-to-same-or-different-subscription.sh
index 5ef8bf3e..be01f01b 100644
--- a/virtual-machine/copy-snapshot-to-same-or-different-subscription/copy-snapshot-to-same-or-different-subscription.sh
+++ b/virtual-machine/copy-snapshot-to-same-or-different-subscription/copy-snapshot-to-same-or-different-subscription.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id of the subscription where snapshot exists
-sourceSubscriptionId=dd80b94e-0463-4a65-8d04-c94f403879dc
+sourceSubscriptionId=""
#Provide the name of your resource group where snapshot exists
sourceResourceGroupName=mySourceResourceGroupName
@@ -28,5 +31,7 @@ targetResourceGroupName=mytargetResourceGroupName
az account set --subscription $targetSubscriptionId
#Copy snapshot to different subscription using the snapshot Id
-az snapshot create --resource-group $targetResourceGroupName --name $snapshotName --source $snapshotId
-
+#We recommend you to store your snapshots in Standard storage to reduce cost. Please use Standard_ZRS in regions where zone redundant storage (ZRS) is available, otherwise use Standard_LRS
+#Please check out the availability of ZRS here: https://docs.microsoft.com/azure/storage/common/storage-redundancy-zrs#support-coverage-and-regional-availability
+az snapshot create --resource-group $targetResourceGroupName --name $snapshotName --source $snapshotId --sku Standard_LRS
+#
diff --git a/virtual-machine/copy-snapshots-to-storage-account/copy-snapshots-to-storage-account.sh b/virtual-machine/copy-snapshots-to-storage-account/copy-snapshots-to-storage-account.sh
index 23d0476b..c05f8f0d 100644
--- a/virtual-machine/copy-snapshots-to-storage-account/copy-snapshots-to-storage-account.sh
+++ b/virtual-machine/copy-snapshots-to-storage-account/copy-snapshots-to-storage-account.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id where snapshot is created
-subscriptionId=dd80b94e-0463-4a65-8d04-c94f403879dc
+subscriptionId=""
#Provide the name of your resource group where snapshot is created
resourceGroupName=myResourceGroupName
@@ -8,7 +11,7 @@ resourceGroupName=myResourceGroupName
snapshotName=mySnapshotName
#Provide Shared Access Signature (SAS) expiry duration in seconds e.g. 3600.
-#Know more about SAS here: https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1
+#Know more about SAS here: https://docs.microsoft.com/azure/storage/storage-dotnet-shared-access-signature-part-1
sasExpiryDuration=3600
#Provide storage account name where you want to copy the snapshot.
@@ -28,8 +31,4 @@ az account set --subscription $subscriptionId
sas=$(az snapshot grant-access --resource-group $resourceGroupName --name $snapshotName --duration-in-seconds $sasExpiryDuration --query [accessSas] -o tsv)
az storage blob copy start --destination-blob $destinationVHDFileName --destination-container $storageContainerName --account-name $storageAccountName --account-key $storageAccountKey --source-uri $sas
-
-
-
-
-
+#
diff --git a/virtual-machine/create-docker-host/create-docker-host.sh b/virtual-machine/create-docker-host/create-docker-host.sh
deleted file mode 100644
index 89da5314..00000000
--- a/virtual-machine/create-docker-host/create-docker-host.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys
-
-# Open port 80 to allow web traffic to host.
- az vm open-port --port 80 --resource-group myResourceGroup --name myVM
-
-# Install Docker and start container.
-az vm extension set \
- --resource-group myResourceGroup \
- --vm-name myVM \
- --name DockerExtension \
- --publisher Microsoft.Azure.Extensions \
- --version 1.1 \
- --settings '{"docker": {"port": "2375"},"compose": {"web": {"image": "nginx","ports": ["80:80"]}}}'
\ No newline at end of file
diff --git a/virtual-machine/create-managed-data-disks-from-vhd/create-managed-data-disks-from-vhd.sh b/virtual-machine/create-managed-data-disks-from-vhd/create-managed-data-disks-from-vhd.sh
index 09339426..557b5ba0 100644
--- a/virtual-machine/create-managed-data-disks-from-vhd/create-managed-data-disks-from-vhd.sh
+++ b/virtual-machine/create-managed-data-disks-from-vhd/create-managed-data-disks-from-vhd.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id
-subscriptionId=mySubscriptionId
+subscriptionId=""
#Provide the name of your resource group.
#Ensure that resource group is already created
@@ -27,9 +30,14 @@ storageType=Premium_LRS
#az account list-locations
location=westus
+#If you're creating an OS disk, uncomment the following lines and replace the values
+#osType = 'yourOSType' #Acceptable values are either Windows or Linux
+#hyperVGeneration = 'yourHyperVGen' #Acceptable values are either v1 or v2
+
#Set the context to the subscription Id where Managed Disk will be created
az account set --subscription $subscriptionId
#Create the Managed disk from the VHD file
+#If you're creating an OS disk, add the following: --os-type $osType -hyper-v-generation $hyperVGeneration
az disk create --resource-group $resourceGroupName --name $diskName --sku $storageType --location $location --size-gb $diskSize --source $vhdUri
-
+#
diff --git a/virtual-machine/create-managed-disks-from-snapshot/create-managed-disks-from-snapshot.sh b/virtual-machine/create-managed-disks-from-snapshot/create-managed-disks-from-snapshot.sh
index d1b59b71..415a9234 100644
--- a/virtual-machine/create-managed-disks-from-snapshot/create-managed-disks-from-snapshot.sh
+++ b/virtual-machine/create-managed-disks-from-snapshot/create-managed-disks-from-snapshot.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id of the subscription where you want to create Managed Disks
-subscriptionId=dd80b94e-0463-4a65-8d04-c94f403879dc
+subscriptionId=""
#Provide the name of your resource group
resourceGroupName=myResourceGroupName
@@ -13,9 +16,13 @@ diskName=myDiskName
#Provide the size of the disks in GB. It should be greater than the VHD file size.
diskSize=128
-#Provide the storage type for Managed Disk. Premium_LRS or Standard_LRS.
+#Provide the storage type for Managed Disk. Acceptable values are Standard_LRS, Premium_LRS, PremiumV2_LRS, StandardSSD_LRS, UltraSSD_LRS, Premium_ZRS, and StandardSSD_ZRS.
storageType=Premium_LRS
+#Required for Premium SSD v2 and Ultra Disks
+#Provide the Availability Zone you'd like the disk to be created in, default is 1
+zone=1
+
#Set the context to the subscription Id where Managed Disk will be created
az account set --subscription $subscriptionId
@@ -24,6 +31,6 @@ snapshotId=$(az snapshot show --name $snapshotName --resource-group $resourceGro
#Create a new Managed Disks using the snapshot Id
#Note that managed disk will be created in the same location as the snapshot
+#If you're creating a Premium SSD v2 or an Ultra Disk, add "--zone $zone" to the end of the command
az disk create --resource-group $resourceGroupName --name $diskName --sku $storageType --size-gb $diskSize --source $snapshotId
-
-
+#
diff --git a/virtual-machine/create-scaleset-php-ansible/README.md b/virtual-machine/create-scaleset-php-ansible/README.md
deleted file mode 100644
index 6e7c4764..00000000
--- a/virtual-machine/create-scaleset-php-ansible/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# PHP app tier provisioned with Ansible
-
-Create an Azure Scale Set with Azure CLI 2.0 using a custom script extension to bootstrap
-virtual machine instances running CentOS. The custom script extension installs the prerequisites
-for Ansible, and then installs an extremely simple PHP app running on Apache.
-
-## To run
-`./build-stack`
-
-## To teardown
-`az group delete -n php-stack`
diff --git a/virtual-machine/create-scaleset-php-ansible/build-stack.sh b/virtual-machine/create-scaleset-php-ansible/build-stack.sh
deleted file mode 100644
index 8177b1fe..00000000
--- a/virtual-machine/create-scaleset-php-ansible/build-stack.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# Create the resource group if it doesn't exist
-az group create -n myResourceGroup -l westus
-
-
-# Build the Scale Set
-az vmss create -n myScaleSet -g myResourceGroup --public-ip-address-dns-name my-lamp-sample \
- --image CentOS --storage-sku Premium_LRS --admin-username deploy --vm-sku Standard_DS3_v2
-
-# Add a load balanced endpoint on port 80 routed to the backend servers on port 80
-az network lb rule create -g myResourceGroup -n http-rule --backend-pool-name myScaleSetLBBEPool \
- --backend-port 80 --frontend-ip-name LoadBalancerFrontEnd --frontend-port 80 --lb-name myScaleSetLB \
- --protocol Tcp
-
-# Create a virtual machine scale set custom script extension. This extension will provide configuration
-# to each of the virtual machines within the scale set on how to provision their software stack.
-# The configuration (./projected_config.json) contains commands to be executed upon provisioning
-# of instances. This is helpful for hooking into configuration management software or simply
-# provisioning your software stack directly.
-az vmss extension set -n CustomScript --publisher Microsoft.Azure.Extensions --version 2.0 \
- -g myResourceGroup --vmss-name myScaleSet --protected-settings ./protected_config.json --no-auto-upgrade
-
-# The instances that we have were created before the extension was added.
-# Update these instances to run the new configuration on each of them.
-az vmss update-instances --instance-ids "*" -n myScaleSet -g myResourceGroup
-
-# Scaling adds new instances. These instances will run the configuration when they're provisioned.
-az vmss scale --new-capacity 2 -n myScaleSet -g myResourceGroup
diff --git a/virtual-machine/create-scaleset-php-ansible/how-to-access.sh b/virtual-machine/create-scaleset-php-ansible/how-to-access.sh
deleted file mode 100644
index 53705262..00000000
--- a/virtual-machine/create-scaleset-php-ansible/how-to-access.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-FQDN=$(az network public-ip list -g myResourceGroup --query \
- "[?starts_with(dnsSettings.fqdn, 'my-lamp-')].dnsSettings.fqdn | [0]" -o tsv)
-
-PORTS=$(az network lb show -g myResourceGroup -n myScaleSetLB \
- --query "inboundNatRules[].{backend: backendPort, frontendPort: frontendPort}" -o tsv)
-while read CMD; do
- read _ frontend <<< "${CMD}"
- echo "'ssh deploy@${FQDN} -p ${frontend}'"
-done <<< "${PORTS}"
-
-echo ""
-echo "You can now reach the scale set by opening your browser to: 'http://${FQDN}'."
\ No newline at end of file
diff --git a/virtual-machine/create-scaleset-php-ansible/php/common/handlers/main.yml b/virtual-machine/create-scaleset-php-ansible/php/common/handlers/main.yml
deleted file mode 100644
index d5286157..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/common/handlers/main.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-# Handler to handle common notifications. Handlers are called by other plays.
-# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
-
-- name: restart ntp
- service: name=ntpd state=restarted
-
-- name: restart iptables
- service: name=iptables state=restarted
diff --git a/virtual-machine/create-scaleset-php-ansible/php/common/tasks/main.yml b/virtual-machine/create-scaleset-php-ansible/php/common/tasks/main.yml
deleted file mode 100644
index ec21026d..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/common/tasks/main.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-# This playbook contains common plays that will be run on all nodes.
-
-- name: Install ntp
- yum: name=ntp state=present
- tags: ntp
-
-- name: Configure ntp file
- template: src=ntp.conf.j2 dest=/etc/ntp.conf
- tags: ntp
- notify: restart ntp
-
-- name: Start the ntp service
- service: name=ntpd state=started enabled=yes
- tags: ntp
-
-- name: test to see if selinux is running
- command: getenforce
- register: sestatus
- changed_when: false
diff --git a/virtual-machine/create-scaleset-php-ansible/php/common/templates/ntp.conf.j2 b/virtual-machine/create-scaleset-php-ansible/php/common/templates/ntp.conf.j2
deleted file mode 100644
index 71374755..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/common/templates/ntp.conf.j2
+++ /dev/null
@@ -1,10 +0,0 @@
-driftfile /var/lib/ntp/drift
-
-restrict 127.0.0.1
-restrict -6 ::1
-
-server {{ ntpserver }}
-
-includefile /etc/ntp/crypto/pw
-
-keys /etc/ntp/keys
diff --git a/virtual-machine/create-scaleset-php-ansible/php/group_vars/all b/virtual-machine/create-scaleset-php-ansible/php/group_vars/all
deleted file mode 100644
index 7e33958a..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/group_vars/all
+++ /dev/null
@@ -1,6 +0,0 @@
----
-# Variables listed here are applicable to all host groups
-
-httpd_port: 80
-ntpserver: 192.168.1.2
-repository: https://github.com/devigned/php-do-work.git
diff --git a/virtual-machine/create-scaleset-php-ansible/php/hosts b/virtual-machine/create-scaleset-php-ansible/php/hosts
deleted file mode 100644
index 3d38776d..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/hosts
+++ /dev/null
@@ -1,2 +0,0 @@
-[webservers]
-localhost ansible_connection=local
diff --git a/virtual-machine/create-scaleset-php-ansible/php/site.yml b/virtual-machine/create-scaleset-php-ansible/php/site.yml
deleted file mode 100644
index 14ea5fd3..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/site.yml
+++ /dev/null
@@ -1,16 +0,0 @@
----
-# This playbook deploys the whole application stack in this site.
-
-- name: apply common configuration to all nodes
- hosts: all
- remote_user: deploy
-
- roles:
- - common
-
-- name: configure and deploy the webservers and application code
- hosts: webservers
- remote_user: deploy
-
- roles:
- - web
diff --git a/virtual-machine/create-scaleset-php-ansible/php/web/handlers/main.yml b/virtual-machine/create-scaleset-php-ansible/php/web/handlers/main.yml
deleted file mode 100644
index acb90a38..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/web/handlers/main.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-# Handler for the webtier: handlers are called by other plays.
-# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
-
-- name: restart iptables
- service: name=iptables state=restarted
diff --git a/virtual-machine/create-scaleset-php-ansible/php/web/tasks/copy_code.yml b/virtual-machine/create-scaleset-php-ansible/php/web/tasks/copy_code.yml
deleted file mode 100644
index bba2d09c..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/web/tasks/copy_code.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-# These tasks are responsible for copying the latest dev/production code from
-# the version control system.
-
-- name: Copy the code from repository
- git: repo={{ repository }} dest=/var/www/html/
diff --git a/virtual-machine/create-scaleset-php-ansible/php/web/tasks/install_httpd.yml b/virtual-machine/create-scaleset-php-ansible/php/web/tasks/install_httpd.yml
deleted file mode 100644
index ac29195d..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/web/tasks/install_httpd.yml
+++ /dev/null
@@ -1,24 +0,0 @@
----
-# These tasks install http and the php modules.
-
-- name: Install http and php etc
- yum: name={{ item }} state=present
- with_items:
- - httpd
- - php
- - php-mysql
- - git
- - libsemanage-python
- - libselinux-python
-
-- name: insert iptables rule for httpd
- lineinfile: dest=/etc/sysconfig/iptables create=yes state=present regexp="{{ httpd_port }}" insertafter="^:OUTPUT "
- line="-A INPUT -p tcp --dport {{ httpd_port }} -j ACCEPT"
- notify: restart iptables
-
-- name: http service state
- service: name=httpd state=started enabled=yes
-
-- name: Configure SELinux to allow httpd to connect to remote database
- seboolean: name=httpd_can_network_connect_db state=true persistent=yes
- when: sestatus.rc != 0
diff --git a/virtual-machine/create-scaleset-php-ansible/php/web/tasks/main.yml b/virtual-machine/create-scaleset-php-ansible/php/web/tasks/main.yml
deleted file mode 100644
index 796842ed..00000000
--- a/virtual-machine/create-scaleset-php-ansible/php/web/tasks/main.yml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-- include: install_httpd.yml
-- include: copy_code.yml
diff --git a/virtual-machine/create-scaleset-php-ansible/protected_config.json b/virtual-machine/create-scaleset-php-ansible/protected_config.json
deleted file mode 100644
index 76e098a0..00000000
--- a/virtual-machine/create-scaleset-php-ansible/protected_config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "commandToExecute": "yum update -y --exclude=WALinuxAgent && yum install -y epel-release && yum install -y ansible git iptables-services && git clone https://github.com/Azure/azure-docs-cli-python-samples.git && cd azure-docs-cli-python-samples/virtual-machine/create-scaleset-php-ansible/php && ansible-playbook site.yml -i hosts --connection=local"
-}
diff --git a/virtual-machine/create-site-to-site-vpn/create-site-to-site-vpn.sh b/virtual-machine/create-site-to-site-vpn/create-site-to-site-vpn.sh
deleted file mode 100644
index f6125dd0..00000000
--- a/virtual-machine/create-site-to-site-vpn/create-site-to-site-vpn.sh
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/bin/bash
-
-# Variables
-resourceGroupName=Vnet-Vnet
-
-location1=westus
-VNET1=TestVnet1
-VNET1Prefix=10.1.0.0/16
-VNET1Subnet=vNet1SubnetName
-VNET1SubnetPrefix=10.1.1.0/24
-GW1=GWVNet1
-GW1Subnet=10.1.255.0/27
-GW1PubIP=GWVNet1-PubIP
-Conn1=GW1GW2
-
-location2=eastus
-VNET2=TestVnet2
-VNET2Prefix=10.11.0.0/16
-VNET2Subnet=vNet2SubnetName
-VNET2SubnetPrefix=10.11.1.0/24
-GW2=GWVNet2
-GW2Subnet=10.11.255.0/27
-GW2PubIP=GWVNet2-PubIP
-Conn2=GW2GW1
-
-SharedKey="connection"
-
-# Create a resource group.
-az group create --name $resourceGroupName --location $location1
-
-# Create VNet1
-az network vnet create \
- --resource-group $resourceGroupName \
- --location $location1 \
- --name $VNET1 \
- --address-prefix $VNET1Prefix \
- --subnet-name $VNET1Subnet \
- --subnet-prefix $VNET1SubnetPrefix
-
-# Create Vnet 2
-az network vnet create \
- --resource-group $resourceGroupName \
- --location $location2 \
- --name $VNET2 \
- --address-prefix \
- $VNET2Prefix \
- --subnet-name $VNET2Subnet \
- --subnet-prefix $VNET2SubnetPrefix
-
-# Create the public IPs for the Gateways in the two regions
-az network public-ip create -n $GW1PubIP -g $resourceGroupName -l $location1
-az network public-ip create -n $GW2PubIP -g $resourceGroupName -l $location2
-
-# Create the Gateway Subnets on each of the two vnets
-az network vnet subnet create \
- --address-prefix $GW1Subnet \
- -n GatewaySubnet \
- -g $resourceGroupName \
- --vnet-name $VNET1
-
-az network vnet subnet create \
- --address-prefix $GW2Subnet
- -n GatewaySubnet
- -g $resourceGroupName
- --vnet-name $VNET2
-
-# Create the VPN Gateways on each vnet
-az network vnet-gateway create \
- -n $GW1 \
- --public-ip-address $GW1PubIP \
- -l $location1 \
- -g $resourceGroupName \
- --vnet $VNET1 \
- --gateway-type Vpn \
- --sku Standard
-
-az network vnet-gateway create \
- -n $GW2 \
- --public-ip-address $GW2PubIP \
- -l $location2 \
- -g $resourceGroupName \
- --vnet $VNET2 \
- --gateway-type Vpn \
- --sku Standard
-
-# Establish connetion between
-az network vpn-connection create \
- -n $Conn1 \
- -g $resourceGroupName \
- --vnet-gateway1 $GW1 \
- -l $location1 \
- --shared-key $SharedKey \
- --vnet-gateway2 $GW2
-
-az network vpn-connection create \
- -n $Conn2 \
- -g $resourceGroupName \
- --vnet-gateway1 $GW2 \
- -l $location2 \
- --shared-key $SharedKey \
- --vnet-gateway2 $GW1
diff --git a/virtual-machine/create-vm-apache/create-vm-apache.sh b/virtual-machine/create-vm-apache/create-vm-apache.sh
deleted file mode 100644
index 0d3e2feb..00000000
--- a/virtual-machine/create-vm-apache/create-vm-apache.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual machine.
-az vm create \
- --image UbuntuLTS \
- --admin-username azureuser \
- --ssh-key-value ~/.ssh/id_rsa.pub \
- --resource-group myResourceGroup \
- --location westeurope \
- --name myVM
-
-# Open port 80 to allow web traffic to host.
-az vm open-port \
- --port 80 \
- --priority 300 \
- --resource-group myResourceGroup \
- --name myVM
-
-# Use CustomScript extension to install Apache.
-az vm extension set \
- --publisher Microsoft.Azure.Extensions \
- --version 2.0 \
- --name CustomScript \
- --vm-name myVM \
- --resource-group myResourceGroup \
- --settings '{"fileUris":["https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/apache2-on-ubuntu-vm/install_apache.sh"], "commandToExecute":"sh install_apache.sh" }'
\ No newline at end of file
diff --git a/virtual-machine/create-vm-apache/install_apache.sh b/virtual-machine/create-vm-apache/install_apache.sh
deleted file mode 100644
index c250516c..00000000
--- a/virtual-machine/create-vm-apache/install_apache.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-apt-get -y update
-
-# install Apache2
-apt-get -y install apache2
-
-# write some HTML
-echo \\My Demo App\
\
\ > /var/www/html/demo.html
-
-# restart Apache
-apachectl restart
\ No newline at end of file
diff --git a/virtual-machine/create-vm-attach-existing-managed-os-disk/create-vm-attach-existing-managed-os-disk.sh b/virtual-machine/create-vm-attach-existing-managed-os-disk/create-vm-attach-existing-managed-os-disk.sh
index 36a78565..9588591a 100644
--- a/virtual-machine/create-vm-attach-existing-managed-os-disk/create-vm-attach-existing-managed-os-disk.sh
+++ b/virtual-machine/create-vm-attach-existing-managed-os-disk/create-vm-attach-existing-managed-os-disk.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id
-subscriptionId=6492b1f7-f219-446b-b509-314e17e1efb0
+subscriptionId=""
#Provide the name of your resource group
resourceGroupName=myResourceGroupName
@@ -21,6 +24,4 @@ managedDiskId=$(az disk show --name $managedDiskName --resource-group $resourceG
#Create VM by attaching existing managed disks as OS
az vm create --name $virtualMachineName --resource-group $resourceGroupName --attach-os-disk $managedDiskId --os-type $osType
-
-
-
+#
diff --git a/virtual-machine/create-vm-customdata/create-vm-customdata.sh b/virtual-machine/create-vm-customdata/create-vm-customdata.sh
deleted file mode 100644
index 8d7600ac..00000000
--- a/virtual-machine/create-vm-customdata/create-vm-customdata.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location eastus
-
-# Create a new virtual machine, this creates SSH keys if not present. Installs the cloud-init file that was previously created.
-az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys --custom-data cloud-init.txt
-
-# Open port 80 to allow web traffic to host.
-az vm open-port --port 80 --resource-group myResourceGroup --name myVM
\ No newline at end of file
diff --git a/virtual-machine/create-vm-detailed/create-vm-detailed.sh b/virtual-machine/create-vm-detailed/create-vm-detailed.sh
deleted file mode 100644
index 71eaa922..00000000
--- a/virtual-machine/create-vm-detailed/create-vm-detailed.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual network.
-az network vnet create --resource-group myResourceGroup --name myVnet --subnet-name mySubnet
-
-# Create a public IP address.
-az network public-ip create --resource-group myResourceGroup --name myPublicIP
-
-# Create a network security group.
-az network nsg create --resource-group myResourceGroup --name myNetworkSecurityGroup
-
-# Create a virtual network card and associate with public IP address and NSG.
-az network nic create \
- --resource-group myResourceGroup \
- --name myNic \
- --vnet-name myVnet \
- --subnet mySubnet \
- --network-security-group myNetworkSecurityGroup \
- --public-ip-address myPublicIP
-
-# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group myResourceGroup --name myVM --nics myNic --image UbuntuLTS --generate-ssh-keys
-
-# Open port 22 to allow SSh traffic to host.
-az vm open-port --port 22 --resource-group myResourceGroup --name myVM
\ No newline at end of file
diff --git a/virtual-machine/create-vm-detailed/create-windows-vm-detailed.sh b/virtual-machine/create-vm-detailed/create-windows-vm-detailed.sh
deleted file mode 100644
index 9e1b9505..00000000
--- a/virtual-machine/create-vm-detailed/create-windows-vm-detailed.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-# Update for your admin password
-AdminPassword=ChangeYourAdminPassword1
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual network.
-az network vnet create --resource-group myResourceGroup --name myVnet --subnet-name mySubnet
-
-# Create a public IP address.
-az network public-ip create --resource-group myResourceGroup --name myPublicIP
-
-# Create a network security group.
-az network nsg create --resource-group myResourceGroup --name myNetworkSecurityGroup
-
-# Create a virtual network card and associate with public IP address and NSG.
-az network nic create \
- --resource-group myResourceGroup \
- --name myNic \
- --vnet-name myVnet \
- --subnet mySubnet \
- --network-security-group myNetworkSecurityGroup \
- --public-ip-address myPublicIP
-
-# Create a virtual machine.
-az vm create \
- --resource-group myResourceGroup \
- --name myVM \
- --location westeurope \
- --nics myNic \
- --image win2016datacenter \
- --admin-username azureuser \
- --admin-password $AdminPassword
-
-# Open port 3389 to allow RDP traffic to host.
-az vm open-port --port 3389 --resource-group myResourceGroup --name myVM
diff --git a/virtual-machine/create-vm-from-snapshot/create-vm-from-snapshot.sh b/virtual-machine/create-vm-from-snapshot/create-vm-from-snapshot.sh
index 9891418b..891d1ae5 100644
--- a/virtual-machine/create-vm-from-snapshot/create-vm-from-snapshot.sh
+++ b/virtual-machine/create-vm-from-snapshot/create-vm-from-snapshot.sh
@@ -1,5 +1,8 @@
+# Verified per Raman Kumar as of 2/23/2022
+
+#
#Provide the subscription Id of the subscription where you want to create Managed Disks
-subscriptionId=dd80b94e-0463-4a65-8d04-c94f403879dc
+subscriptionId=""
#Provide the name of your resource group
resourceGroupName=myResourceGroupName
@@ -34,6 +37,4 @@ az disk create --resource-group $resourceGroupName --name $osDiskName --sku $sto
#Create VM by attaching created managed disks as OS
az vm create --name $virtualMachineName --resource-group $resourceGroupName --attach-os-disk $osDiskName --os-type $osType
-
-
-
+#
diff --git a/virtual-machine/create-vm-monitor-oms/create-vm-monitor-oms.sh b/virtual-machine/create-vm-monitor-oms/create-vm-monitor-oms.sh
deleted file mode 100644
index 7fa0d95a..00000000
--- a/virtual-machine/create-vm-monitor-oms/create-vm-monitor-oms.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-# OMS Id and OMS key.
-omsid=
-omskey=
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys
-
-# Install and configure the OMS agent.
-az vm extension set \
- --resource-group myResourceGroup \
- --vm-name myVM \
- --name OmsAgentForLinux \
- --publisher Microsoft.EnterpriseCloud.Monitoring \
- --version 1.0 --protected-settings '{"workspaceKey": "'"$omskey"'"}' \
- --settings '{"workspaceId": "'"$omsid"'"}'
diff --git a/virtual-machine/create-vm-monitor-oms/create-windows-vm-monitor-oms.sh b/virtual-machine/create-vm-monitor-oms/create-windows-vm-monitor-oms.sh
deleted file mode 100644
index a5697642..00000000
--- a/virtual-machine/create-vm-monitor-oms/create-windows-vm-monitor-oms.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-# Update for your admin password
-AdminPassword=ChangeYourAdminPassword1
-
-# OMS Id and OMS key.
-omsid=
-omskey=
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual machine.
-az vm create \
- --resource-group myResourceGroup \
- --name myVM \
- --image win2016datacenter \
- --admin-username azureuser \
- --admin-password $AdminPassword
-
-# Install and configure the OMS agent.
-az vm extension set \
- --resource-group myResourceGroup \
- --vm-name myVM --name MicrosoftMonitoringAgent \
- --publisher Microsoft.EnterpriseCloud.Monitoring \
- --version 1.0 --protected-settings '{"workspaceKey": "'"$omskey"'"}' \
- --settings '{"workspaceId": "'"$omsid"'"}'
\ No newline at end of file
diff --git a/virtual-machine/create-vm-nginx/create-vm-nginx.sh b/virtual-machine/create-vm-nginx/create-vm-nginx.sh
deleted file mode 100644
index 3d248e0f..00000000
--- a/virtual-machine/create-vm-nginx/create-vm-nginx.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys
-
-# Open port 80 to allow web traffic to host.
-az vm open-port --port 80 --resource-group myResourceGroup --name myVM
-
-# Use CustomScript extension to install NGINX.
-az vm extension set \
- --publisher Microsoft.Azure.Extensions \
- --version 2.0 \
- --name CustomScript \
- --vm-name myVM \
- --resource-group myResourceGroup \
- --settings '{"commandToExecute":"apt-get -y update && apt-get -y install nginx"}'
\ No newline at end of file
diff --git a/virtual-machine/create-vm-nlb/create-vm-nlb.sh b/virtual-machine/create-vm-nlb/create-vm-nlb.sh
deleted file mode 100644
index 2ade350f..00000000
--- a/virtual-machine/create-vm-nlb/create-vm-nlb.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual network.
-az network vnet create --resource-group myResourceGroup --location westeurope --name myVnet --subnet-name mySubnet
-
-# Create a public IP address.
-az network public-ip create --resource-group myResourceGroup --name myPublicIP
-
-# Create an Azure Load Balancer.
-az network lb create --resource-group myResourceGroup --name myLoadBalancer --public-ip-address myPublicIP \
- --frontend-ip-name myFrontEndPool --backend-pool-name myBackEndPool
-
-# Creates an LB probe on port 80.
-az network lb probe create --resource-group myResourceGroup --lb-name myLoadBalancer \
- --name myHealthProbe --protocol tcp --port 80
-
-# Creates an LB rule for port 80.
-az network lb rule create --resource-group myResourceGroup --lb-name myLoadBalancer --name myLoadBalancerRuleWeb \
- --protocol tcp --frontend-port 80 --backend-port 80 --frontend-ip-name myFrontEndPool \
- --backend-pool-name myBackEndPool --probe-name myHealthProbe
-
-# Create three NAT rules for port 22.
-for i in `seq 1 3`; do
- az network lb inbound-nat-rule create \
- --resource-group myResourceGroup --lb-name myLoadBalancer \
- --name myLoadBalancerRuleSSH$i --protocol tcp \
- --frontend-port 422$i --backend-port 22 \
- --frontend-ip-name myFrontEndPool
-done
-
-# Create a network security group
-az network nsg create --resource-group myResourceGroup --name myNetworkSecurityGroup
-
-# Create a network security group rule for port 22.
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroup --name myNetworkSecurityGroupRuleSSH \
- --protocol tcp --direction inbound --source-address-prefix '*' --source-port-range '*' \
- --destination-address-prefix '*' --destination-port-range 22 --access allow --priority 1000
-
-# Create a network security group rule for port 80.
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroup --name myNetworkSecurityGroupRuleHTTP \
---protocol tcp --direction inbound --priority 1001 --source-address-prefix '*' --source-port-range '*' \
---destination-address-prefix '*' --destination-port-range 80 --access allow --priority 2000
-
-# Create three virtual network cards and associate with public IP address and NSG.
-for i in `seq 1 3`; do
- az network nic create \
- --resource-group myResourceGroup --name myNic$i \
- --vnet-name myVnet --subnet mySubnet \
- --network-security-group myNetworkSecurityGroup --lb-name myLoadBalancer \
- --lb-address-pools myBackEndPool --lb-inbound-nat-rules myLoadBalancerRuleSSH$i
-done
-
-# Create an availability set.
-az vm availability-set create --resource-group myResourceGroup --name myAvailabilitySet --platform-fault-domain-count 3 --platform-update-domain-count 3
-
-# Create three virtual machines, this creates SSH keys if not present.
-for i in `seq 1 3`; do
- az vm create \
- --resource-group myResourceGroup \
- --name myVM$i \
- --availability-set myAvailabilitySet \
- --nics myNic$i \
- --image UbuntuLTS \
- --generate-ssh-keys \
- --no-wait
-done
\ No newline at end of file
diff --git a/virtual-machine/create-vm-nlb/create-windows-vm-nlb.sh b/virtual-machine/create-vm-nlb/create-windows-vm-nlb.sh
deleted file mode 100644
index 262cfeca..00000000
--- a/virtual-machine/create-vm-nlb/create-windows-vm-nlb.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash
-
-# Update for your admin password
-AdminPassword=ChangeYourAdminPassword1
-
-# Create a resource group.
-az group create --name myResourceGroup --location westus
-
-# Create a virtual network.
-az network vnet create --resource-group myResourceGroup --name myVnet \
- --address-prefix 192.168.0.0/16 --subnet-name mySubnet --subnet-prefix 192.168.1.0/24
-
-# Create a public IP address.
-az network public-ip create --resource-group myResourceGroup --name myPublicIP
-
-# Create an Azure Load Balancer.
-az network lb create --resource-group myResourceGroup --name myLoadBalancer --public-ip-address myPublicIP \
- --frontend-ip-name myFrontEndPool --backend-pool-name myBackEndPool
-
-# Creates an LB probe on port 80.
-az network lb probe create --resource-group myResourceGroup --lb-name myLoadBalancer \
- --name myHealthProbe --protocol tcp --port 80
-
-# Creates an LB rule for port 80.
-az network lb rule create --resource-group myResourceGroup --lb-name myLoadBalancer --name myLoadBalancerRuleWeb \
- --protocol tcp --frontend-port 80 --backend-port 80 --frontend-ip-name myFrontEndPool \
- --backend-pool-name myBackEndPool --probe-name myHealthProbe
-
-# Create three NAT rules for port 3389.
-for i in `seq 1 3`; do
- az network lb inbound-nat-rule create \
- --resource-group myResourceGroup --lb-name myLoadBalancer \
- --name myLoadBalancerRuleSSH$i --protocol tcp \
- --frontend-port 422$i --backend-port 3389 \
- --frontend-ip-name myFrontEndPool
-done
-
-# Create a network security group
-az network nsg create --resource-group myResourceGroup --name myNetworkSecurityGroup
-
-# Create a network security group rule for port 3389.
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroup --name myNetworkSecurityGroupRuleSSH \
- --protocol tcp --direction inbound --source-address-prefix '*' --source-port-range '*' \
- --destination-address-prefix '*' --destination-port-range 3389 --access allow --priority 1000
-
-# Create a network security group rule for port 80.
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroup --name myNetworkSecurityGroupRuleHTTP \
---protocol tcp --direction inbound --priority 1001 --source-address-prefix '*' --source-port-range '*' \
---destination-address-prefix '*' --destination-port-range 80 --access allow --priority 2000
-
-# Create three virtual network cards and associate with public IP address and NSG.
-for i in `seq 1 3`; do
- az network nic create \
- --resource-group myResourceGroup --name myNic$i \
- --vnet-name myVnet --subnet mySubnet \
- --network-security-group myNetworkSecurityGroup --lb-name myLoadBalancer \
- --lb-address-pools myBackEndPool --lb-inbound-nat-rules myLoadBalancerRuleSSH$i
-done
-
-# Create an availability set.
-az vm availability-set create --resource-group myResourceGroup --name myAvailabilitySet --platform-fault-domain-count 3 --platform-update-domain-count 3
-
-# Create three virtual machines.
-for i in `seq 1 3`; do
- az vm create \
- --resource-group myResourceGroup \
- --name myVM$i \
- --availability-set myAvailabilitySet \
- --nics myNic$i \
- --image win2016datacenter \
- --admin-password $AdminPassword \
- --admin-username azureuser \
- --no-wait
-done
diff --git a/virtual-machine/create-vm-nsg/create-vm-nsg.sh b/virtual-machine/create-vm-nsg/create-vm-nsg.sh
deleted file mode 100644
index 4f857d49..00000000
--- a/virtual-machine/create-vm-nsg/create-vm-nsg.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual network and front-end subnet.
-az network vnet create --resource-group myResourceGroup --name myVnet --address-prefix 10.0.0.0/16 \
---subnet-name mySubnetFrontEnd --subnet-prefix 10.0.1.0/24
-
-# Create a back-end subnet and associate with virtual network.
-az network vnet subnet create --resource-group myResourceGroup --vnet-name myVnet \
- --name mySubnetBackEnd --address-prefix 10.0.2.0/24
-
-# Create a front-end virtual machine.
-az vm create --resource-group myResourceGroup --name myVMFrontEnd --image UbuntuLTS \
- --vnet-name myVnet --subnet mySubnetFrontEnd --nsg myNetworkSecurityGroupFrontEnd \
- --generate-ssh-keys --no-wait
-
-# Create a back-end virtual machine without a public IP address.
-az vm create --resource-group myResourceGroup --name myVMBackEnd --image UbuntuLTS \
- --vnet-name myVnet --subnet mySubnetBackEnd --nsg myNetworkSecurityGroupBackEnd \
- --public-ip-address "" --generate-ssh-keys
-
-# Create front-end NSG rule to allow traffic on port 80.
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupFrontEnd \
- --name http --access allow --protocol Tcp --direction Inbound --priority 200 \
- --source-address-prefix "*" --source-port-range "*" --destination-address-prefix "*" --destination-port-range 80
-
-# Get default back-end SSH rule.
-nsgrule=$(az network nsg rule list --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupBackEnd --query [0].name -o tsv)
-
-# Update back-end network security group rule to limit SSH to source prefix (priority 100).
-az network nsg rule update --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupBackEnd \
- --name $nsgrule --protocol tcp --direction inbound --priority 100 \
- --source-address-prefix 10.0.2.0/24 --source-port-range '*' --destination-address-prefix '*' \
- --destination-port-range 22 --access allow
-
-# Create backend NSG rule to block all incoming traffic (priority 200).
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupBackEnd \
- --name denyAll --access Deny --protocol Tcp --direction Inbound --priority 200 \
- --source-address-prefix "*" --source-port-range "*" --destination-address-prefix "*" --destination-port-range "*"
\ No newline at end of file
diff --git a/virtual-machine/create-vm-nsg/create-windows-vm-nsg.sh b/virtual-machine/create-vm-nsg/create-windows-vm-nsg.sh
deleted file mode 100644
index c6958255..00000000
--- a/virtual-machine/create-vm-nsg/create-windows-vm-nsg.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-
-# Update for your admin password
-AdminPassword=ChangeYourAdminPassword1
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual network and front-end subnet.
-az network vnet create --resource-group myResourceGroup --name myVnet --address-prefix 10.0.0.0/16 \
---subnet-name mySubnetFrontEnd --subnet-prefix 10.0.1.0/24
-
-# Create a back-end subnet and associate with virtual network.
-az network vnet subnet create --resource-group myResourceGroup --vnet-name myVnet \
- --name mySubnetBackEnd --address-prefix 10.0.2.0/24
-
-# Create a front-end virtual machine.
-az vm create --resource-group myResourceGroup --name myVMFrontEnd --image win2016datacenter \
- --admin-username azureuser --admin-password $AdminPassword --vnet-name myVnet --subnet mySubnetFrontEnd \
- --nsg myNetworkSecurityGroupFrontEnd --no-wait
-
-# Create a back-end virtual machine without a public IP address.
-az vm create --resource-group myResourceGroup --name myVMBackEnd --image win2016datacenter \
- --admin-username azureuser --admin-password $AdminPassword --public-ip-address "" --vnet-name myVnet \
- --subnet mySubnetBackEnd --nsg myNetworkSecurityGroupBackEnd
-
-# Create front-end NSG rule to allow traffic on port 80.
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupFrontEnd \
- --name http --access allow --protocol Tcp --direction Inbound --priority 200 \
- --source-address-prefix "*" --source-port-range "*" --destination-address-prefix "*" --destination-port-range 80
-
-# Get nsg rule name.
-nsgrule=$(az network nsg rule list --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupBackEnd --query [0].name -o tsv)
-
-# Update back-end network security group rule to limit SSH to source prefix (priority 100).
-az network nsg rule update --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupBackEnd \
- --name $nsgrule --protocol tcp --direction inbound --priority 100 \
- --source-address-prefix 10.0.1.0/24 --source-port-range '*' --destination-address-prefix '*' \
- --destination-port-range 22 --access allow
-
-# Create backend NSG rule to block all incoming traffic (priority 200).
-az network nsg rule create --resource-group myResourceGroup --nsg-name myNetworkSecurityGroupBackEnd \
- --name denyAll --access Deny --protocol Tcp --direction Inbound --priority 200 \
- --source-address-prefix "*" --source-port-range "*" --destination-address-prefix "*" --destination-port-range "*"
-
\ No newline at end of file
diff --git a/virtual-machine/create-vm-quick/create-vm-quick.sh b/virtual-machine/create-vm-quick/create-vm-quick.sh
index 0e38309a..2a6bcdb4 100644
--- a/virtual-machine/create-vm-quick/create-vm-quick.sh
+++ b/virtual-machine/create-vm-quick/create-vm-quick.sh
@@ -4,4 +4,4 @@
az group create --name myResourceGroup --location westeurope
# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys
\ No newline at end of file
+az vm create --resource-group myResourceGroup --name myVM --image Ubuntu2204 --generate-ssh-keys
\ No newline at end of file
diff --git a/virtual-machine/create-vm-vhd/README.md b/virtual-machine/create-vm-vhd/README.md
deleted file mode 100644
index 2cb6c2e8..00000000
--- a/virtual-machine/create-vm-vhd/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Create a Virtual Machine with a custom .VHD
-
-This example creates a virtual machine based off a custom VHD. The prepared VHD is uploaded to a
-newly created storage account and container and the VM user's (deploy user) ssh public key is
-replaced with the executor of the scripts public key.
-
-You can download the custom VHD at https://azclisamples.blob.core.windows.net/vhds/sample.vhd.
-
-## To run this sample
-`./create-vm-vhd`
-
-## To tear down this sample
-`az group delete -n az-cli-vhd`
\ No newline at end of file
diff --git a/virtual-machine/create-vm-vhd/create-vm-vhd.sh b/virtual-machine/create-vm-vhd/create-vm-vhd.sh
deleted file mode 100644
index 05ef2eaf..00000000
--- a/virtual-machine/create-vm-vhd/create-vm-vhd.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-# Create a resource group
-az group create -n myResourceGroup -l westus
-
-# Create the storage account to upload the vhd
-az storage account create -g myResourceGroup -n mystorageaccount -l westus --sku PREMIUM_LRS
-
-# Get a storage key for the storage account
-STORAGE_KEY=$(az storage account keys list -g myResourceGroup -n mystorageaccount --query "[?keyName=='key1'] | [0].value" -o tsv)
-
-# Create the container for the vhd
-az storage container create -n vhds --account-name mystorageaccount --account-key ${STORAGE_KEY}
-
-# Upload the vhd to a blob
-az storage blob upload -c vhds -f ~/sample.vhd -n sample.vhd --account-name mystorageaccount --account-key ${STORAGE_KEY}
-
-# Create the vm from the vhd
-az vm create -g myResourceGroup -n myVM --image "https://myStorageAccount.blob.core.windows.net/vhds/sample.vhd" \
- --os-type linux --admin-username deploy --generate-ssh-keys
-
-# Update the deploy user with your ssh key
-az vm user update --resource-group myResourceGroup -n custom-vm -u deploy --ssh-key-value "$(< ~/.ssh/id_rsa.pub)"
-
-# Get public IP address for the VM
-IP_ADDRESS=$(az vm list-ip-addresses -g az-cli-vhd -n custom-vm \
- --query "[0].virtualMachine.network.publicIpAddresses[0].ipAddress" -o tsv)
-
-echo "You can now connect using 'ssh deploy@${IP_ADDRESS}'"
\ No newline at end of file
diff --git a/virtual-machine/create-vm-windows-iis/create-vm-windows-iis.sh b/virtual-machine/create-vm-windows-iis/create-vm-windows-iis.sh
deleted file mode 100644
index f44d8569..00000000
--- a/virtual-machine/create-vm-windows-iis/create-vm-windows-iis.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-# Update for your admin password
-AdminPassword=ChangeYourAdminPassword1
-
-# Create a resource group.
-az group create --name myResourceGroup --location westeurope
-
-# Create a virtual machine.
-az vm create \
- --resource-group myResourceGroup \
- --name myVM \
- --image win2016datacenter \
- --admin-username azureuser \
- --admin-password $AdminPassword
-
-# Open port 80 to allow web traffic to host.
-az vm open-port --port 80 --resource-group myResourceGroup --name myVM
-
-# Use CustomScript extension to install IIS.
-az vm extension set \
- --publisher Microsoft.Compute \
- --version 1.8 \
- --name CustomScriptExtension \
- --vm-name myVM \
- --resource-group myResourceGroup \
- --settings '{"commandToExecute":"powershell.exe Install-WindowsFeature -Name Web-Server"}'
\ No newline at end of file
diff --git a/virtual-machine/create-windows-iis-using-dsc/create-windows-iis-using-dsc.sh b/virtual-machine/create-windows-iis-using-dsc/create-windows-iis-using-dsc.sh
deleted file mode 100644
index 107acb44..00000000
--- a/virtual-machine/create-windows-iis-using-dsc/create-windows-iis-using-dsc.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-
-# Update for your admin password
-AdminPassword=ChangeYourAdminPassword1
-
-# Create a resource group.
-az group create --name myResourceGroup --location westus
-
-# Create a VM
-az vm create \
- --resource-group myResourceGroup \
- --name myVM \
- --image win2016datacenter \
- --admin-username azureuser \
- --admin-password $AdminPassword
-
-# Start a CustomScript extension to use a simple bash script to update, download and install WordPress and MySQL
-az vm extension set \
- --name DSC \
- --publisher Microsoft.Powershell \
- --version 2.19 \
- --vm-name myVM \
- --resource-group myResourceGroup \
- --settings '{"ModulesURL":"https://github.com/Azure/azure-quickstart-templates/raw/master/dsc-extension-iis-server-windows-vm/ContosoWebsite.ps1.zip", "configurationFunction": "ContosoWebsite.ps1\\ContosoWebsite", "Properties": {"MachineName": "myVM"} }'
-
- # open port 80 to allow web traffic to host
- az vm open-port \
- --port 80 \
- --resource-group myResourceGroup \
- --name myVM
-
\ No newline at end of file
diff --git a/virtual-machine/create-wordpress-mysql/create-wordpress-mysql.sh b/virtual-machine/create-wordpress-mysql/create-wordpress-mysql.sh
deleted file mode 100644
index f1f50056..00000000
--- a/virtual-machine/create-wordpress-mysql/create-wordpress-mysql.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-# Create a resource group.
-az group create --name myResourceGroup --location westus
-
-# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group myResourceGroup --name myVM --image Canonical:UbuntuServer:14.04.5-LTS:latest --generate-ssh-keys
-
-# Open port 80 to allow web traffic to host.
-az vm open-port --port 80 --resource-group myResourceGroup --name myVM
-
-# Start a CustomScript extension to use a simple bash script to update, download and install WordPress and MySQL
-az vm extension set \
- --publisher Microsoft.Azure.Extensions \
- --version 2.0 \
- --name CustomScript \
- --vm-name myVM \
- --resource-group myResourceGroup \
- --settings '{"fileUris":["https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/wordpress-single-vm-ubuntu/install_wordpress.sh"],"commandToExecute":"sh install_wordpress.sh"}'
\ No newline at end of file
diff --git a/virtual-machine/encrypt-disks/encrypt_vm.sh b/virtual-machine/encrypt-disks/encrypt_vm.sh
deleted file mode 100644
index 189de758..00000000
--- a/virtual-machine/encrypt-disks/encrypt_vm.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-
-# Provide your own unique Key Vault name
-keyvault_name=
-
-# Register the Key Vault provider and create a resource group.
-az provider register -n Microsoft.KeyVault
-az group create --name myResourceGroup --location eastus
-
-# Create a Key Vault for storing keys and enabled for disk encryption.
-az keyvault create --name $keyvault_name --resource-group myResourceGroup --location eastus \
- --enabled-for-disk-encryption True
-
-# Create a key within the Key Vault.
-az keyvault key create --vault-name $keyvault_name --name myKey --protection software
-
-# Create an Azure Active Directory service principal for authenticating requests to Key Vault.
-# Read in the service principal ID and password for use in later commands.
-read sp_id sp_password <<< $(az ad sp create-for-rbac --query [appId,password] -o tsv)
-
-# Grant permissions on the Key Vault to the AAD service principal.
-az keyvault set-policy --name $keyvault_name --spn $sp_id \
- --key-permissions all \
- --secret-permissions all
-
-# Create a virtual machine.
-az vm create \
- --resource-group myResourceGroup \
- --name myVM \
- --image OpenLogic:CentOS:7.2n:7.2.20160629 \
- --admin-username azureuser \
- --generate-ssh-keys
-
-# Encrypt the VM disks.
-az vm encryption enable --resource-group myResourceGroup --name myVM \
- --aad-client-id $sp_id \
- --aad-client-secret $sp_password \
- --disk-encryption-keyvault $keyvault_name \
- --key-encryption-key myKey \
- --volume-type all
-
-# Output how to monitor the encryption status and next steps.
-echo "The encryption process can take some time. View status with:
-
- az vm encryption show --resource-group myResourceGroup --name myVM --query [osDisk] -o tsv
-
-When encryption status shows \`VMRestartPending\`, restart the VM with:
-
- az vm restart --resource-group myResourceGroup --name myVM"
\ No newline at end of file
diff --git a/virtual-machine/encrypt-disks/encrypt_windows_vm.sh b/virtual-machine/encrypt-disks/encrypt_windows_vm.sh
deleted file mode 100644
index b7b2ca6d..00000000
--- a/virtual-machine/encrypt-disks/encrypt_windows_vm.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-
-# Provide your own unique Key Vault name
-keyvault_name=
-
-# Register the Key Vault provider and create a resource group.
-az provider register -n Microsoft.KeyVault
-az group create --name myResourceGroup --location eastus
-
-# Create a Key Vault for storing keys and enabled for disk encryption.
-az keyvault create --name $keyvault_name --resource-group myResourceGroup --location eastus \
- --enabled-for-disk-encryption True
-
-# Create a key within the Key Vault.
-az keyvault key create --vault-name $keyvault_name --name myKey --protection software
-
-# Create an Azure Active Directory service principal for authenticating requests to Key Vault.
-# Read in the service principal ID and password for use in later commands.
-read sp_id sp_password <<< $(az ad sp create-for-rbac --query [appId,password] -o tsv)
-
-# Grant permissions on the Key Vault to the AAD service principal.
-az keyvault set-policy --name $keyvault_name --spn $sp_id \
- --key-permissions all \
- --secret-permissions all
-
-# Create a virtual machine.
-az vm create \
- --resource-group myResourceGroup \
- --name myVM \
- --name myVM --image win2016datacenter \
- --admin-username azureuser \
- --admin-password myPassword12
-
-# Encrypt the VM disks.
-az vm encryption enable --resource-group myResourceGroup2 --name myVM \
- --aad-client-id $sp_id \
- --aad-client-secret $sp_password \
- --disk-encryption-keyvault $keyvault_name \
- --key-encryption-key myKey \
- --volume-type all
-
-# Output how to monitor the encryption status and next steps.
-echo "The encryption process can take some time. View status with:
-
- az vm encryption show --resource-group myResourceGroup --name myVM --query [osDisk] -o tsv
-
-When encryption status shows \`Encrypted\`, restart the VM with:
-
- az vm restart --resource-group myResourceGroup --name myVM"
\ No newline at end of file
diff --git a/virtual-machine/mount-os-disk/mount-os-disk.sh b/virtual-machine/mount-os-disk/mount-os-disk.sh
deleted file mode 100644
index 868ff142..00000000
--- a/virtual-machine/mount-os-disk/mount-os-disk.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-# Source virtual machine details.
-sourcevm=
-resourcegroup=
-
-# Get the disk id for the source VM operating system disk.
-diskid="$(az vm show -g $resourcegroup -n $sourcevm --query [storageProfile.osDisk.managedDisk.id] -o tsv)"
-
-# Delete the source virtual machine, this will not delete the disk.
-az vm delete -g $resourcegroup -n $sourcevm --yes
-
-# Create a new virtual machine, this creates SSH keys if not present.
-az vm create --resource-group $resourcegroup --name myVM --image UbuntuLTS --generate-ssh-keys
-
-# Attach disk as a data disk to the newly created VM.
-az vm disk attach --resource-group $resourcegroup --vm-name myVM --disk $diskid
-
-# Configure disk on new VM.
-ip=$(az vm list-ip-addresses --resource-group $resourcegroup --name myVM --query '[].virtualMachine.network.publicIpAddresses[0].ipAddress' -o tsv)
-ssh $ip 'sudo mkdir /mnt/remountedOsDisk'
-ssh $ip 'sudo mount -t ext4 /dev/sdc1 /mnt/remountedOsDisk'
diff --git a/virtual-machine/restart-by-tag/README.md b/virtual-machine/restart-by-tag/README.md
deleted file mode 100644
index 834cf190..00000000
--- a/virtual-machine/restart-by-tag/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Restart VMs by Tag
-
-This example creates a virtual machines in multiple resource groups with a given tag. Creation of the
-virtual machines is done in parallel via `--no-wait` to illustrate how to start multiple VM creations
-and to then wait for their collective completion.
-
-After the virtual machines have been created, they are restarted using using two different query
-mechanisms.
-
-The first restarts the VMs using the query used to wait on their asynchronous creation.
-
-```bash
-az vm restart --ids $(az vm list --resource-group myResourceGroup --query "[].id" -o tsv)
-```
-
-The second uses a generic resource listing and query to fetch their IDs by tag.
-
-```bash
-az vm restart --ids $(az resource list --tag "restart-tag" --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o tsv)
-```
-
-## To run this sample
-
-Provision the VMs, wait for them to complete provisioning, then restart the VMs.
-
-```bash
-./provision.sh
-./wait.sh
-./restart.sh
-```
-
-## To tear down this sample
-```bash
-az group delete -n myResourceGroup --no-wait --yes
-```
\ No newline at end of file
diff --git a/virtual-machine/restart-by-tag/provision.sh b/virtual-machine/restart-by-tag/provision.sh
deleted file mode 100644
index ffa0faed..00000000
--- a/virtual-machine/restart-by-tag/provision.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-# Create a resource group where we'll create the VMs that we'll start
-az group create -n myResourceGroup -l westus
-
-# Create the VMs. Two are tagged and one is not. --generated-ssh-keys will create ssh keys if not present
-az vm create -g myResourceGroup -n myVM1 --image UbuntuLTS --admin-username deploy --tags "restart-tag" --generate-ssh-keys --no-wait
-az vm create -g myResourceGroup -n myVM2 --image UbuntuLTS --admin-username deploy --tags "restart-tag" --no-wait
-az vm create -g myResourceGroup -n myVM3 --image UbuntuLTS --admin-username deploy --no-wait
\ No newline at end of file
diff --git a/virtual-machine/restart-by-tag/restart-by-tag.sh b/virtual-machine/restart-by-tag/restart-by-tag.sh
deleted file mode 100644
index e8c9b3a0..00000000
--- a/virtual-machine/restart-by-tag/restart-by-tag.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-DEFAULT_TAG='restart-tag'
-LOCATION='westus'
-TAG=${1:-$DEFAULT_TAG}
-
-RESOURCE_GROUPS=('GROUP1' 'GROUP2' 'GROUP3')
-
-for group in ${RESOURCE_GROUPS[@]}; do
- # Create the resource group if it doesn't exist
- echo "Creating resource group ${group} in ${LOCATION}"
- az group create -n ${group} -l ${LOCATION} 1>/dev/null
-
- echo "Deploying vm named ${group}-vm in ${group} with no waiting"
- az vm create -g ${group} -n "${group}-vm" --image UbuntuLTS --admin-username deploy --tags ${DEFAULT_TAG} --no-wait $1>/dev/null
- # If you don't have an ssh key, you can add the --generate-ssh-keys parameter to the az vm create command
- # az vm create -g ${group} -n "${group}-vm" --image UbuntuLTS --admin-username deploy --tags ${DEFAULT_TAG} --generate-ssh-keys --no-wait $1>/dev/null
-done
-
-echo "Waiting for the vms to complete provisioning"
-
-GROUP_QUERY=''
-for group in ${RESOURCE_GROUPS[@]}; do
- if [[ ${GROUP_QUERY} ]]; then
- GROUP_QUERY="${GROUP_QUERY} || resourceGroup=='${group}'"
- else
- GROUP_QUERY="[?resourceGroup=='${group}'"
- fi
-done
-
-SUCCESS_GROUP_QUERY="length(${GROUP_QUERY}] | [?provisioningState=='Succeeded'])"
-FAILED_GROUP_QUERY="length(${GROUP_QUERY}] | [?provisioningState=='Failed'])"
-
-echo ""
-while [[ $(az vm list --query "${SUCCESS_GROUP_QUERY}") != ${#RESOURCE_GROUPS[@]} ]]; do
- echo "Still not provisioned. Sleeping for 20 seconds."
- sleep 20
- if [[ $(az vm list --query "${FAILED_GROUP_QUERY}") != 0 ]]; then
- echo "At least one of the vms failed to provision successfully!!"
- exit 1
- fi
-done
-
-echo ""
-echo "Restarting virtual machines with ids via the group query"
-az vm restart --ids $(az vm list --query "join(' ', ${GROUP_QUERY}] | [].id)" -o tsv) $1>/dev/null
-
-echo ""
-echo "Restarting virtual machines with a given tag"
-az vm restart --ids $(az resource list --tag ${TAG} --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o tsv) $1>/dev/null
-
-
-echo ""
-echo "To delete the created resource groups run the following."
-DELETE_CMD=''
-for group in ${RESOURCE_GROUPS[@]}; do
- if [[ ${DELETE_CMD} ]]; then
- DELETE_CMD="${DELETE_CMD} && az group delete -n ${group} --no-wait --yes"
- else
- DELETE_CMD="az group delete -n ${group} --no-wait --yes"
- fi
-done
-
-echo "'${DELETE_CMD}'"
diff --git a/virtual-machine/restart-by-tag/restart.sh b/virtual-machine/restart-by-tag/restart.sh
deleted file mode 100644
index 64c33b72..00000000
--- a/virtual-machine/restart-by-tag/restart.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-# Get the IDs of all the VMs in the resource group and restart those
-az vm restart --ids $(az vm list --resource-group myResourceGroup --query "[].id" -o tsv)
-
-# Get the IDs of the tagged VMs and restart those
-az vm restart --ids $(az resource list --tag "restart-tag" --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o tsv)
diff --git a/virtual-machine/restart-by-tag/wait.sh b/virtual-machine/restart-by-tag/wait.sh
deleted file mode 100644
index aafb749c..00000000
--- a/virtual-machine/restart-by-tag/wait.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-# Wait for the VMs to be provisioned
-while [[ $(az vm list --resource-group myResourceGroup --query "length([?provisioningState=='Succeeded'])") != 3 ]]; do
- echo "The VMs are still not provisioned. Trying again in 20 seconds."
- sleep 20
- if [[ $(az vm list --resource-group myResorceGroup --query "length([?provisioningState=='Failed'])") != 0 ]]; then
- echo "At least one of the VMs failed to be provisioned."
- exit 1
- fi
-done
-echo "The VMs are provisioned."
diff --git a/virtual-network/create-nat-gateway/create-nat-gateway-cli.sh b/virtual-network/create-nat-gateway/create-nat-gateway-cli.sh
new file mode 100644
index 00000000..64dd9dcd
--- /dev/null
+++ b/virtual-network/create-nat-gateway/create-nat-gateway-cli.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 02/03/2022
+
+#
+# Create NAT gateway
+
+#
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="create-nat-gateway-cli"
+publicIp="msdocs-public-ip-$randomIdentifier"
+zone="1"
+sku="standard"
+allocationMethod="static"
+zone="1"
+natGateway="msdocs-nat-gateway-$randomIdentifier"
+vNet="msdocs-vnet-$randomIdentifier"
+addressPrefix="10.1.0.0/16"
+subnet="msdocs-subnet-$randomIdentifier"
+subnetPrefix="10.1.0.0/24"
+bastionSubnet="AzureBastionSubnet"
+addressPrefixBastion="10.1.1.0/24"
+bastionPublicIp="msdocs-bastion-public-ip-$randomIdentifier"
+bastionHost="msdocs-bastion-host-$randomIdentifier"
+vm="msdocvm$randomIdentifier"
+login="azureuser"
+image="win2019datacenter"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+#
+#
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+#
+#
+# Create public IP address
+echo "Creating $publicIP"
+az network public-ip create --resource-group $resourceGroup --location "$location" --name $publicIp --sku $sku --allocation-method $allocationMethod --zone $zone
+#
+#
+# Create NAT gateway resource
+echo "Creating $natGateway using $publicIp"
+az network nat gateway create --resource-group $resourceGroup --name $natGateway --public-ip-addresses $publicIp --idle-timeout 10
+#
+#
+# Create virtual network
+echo "Creating $vNet using $addressPrefix"
+az network vnet create --resource-group $resourceGroup --location "$location" --name $vNet --address-prefix $addressPrefix --subnet-name $subnet --subnet-prefix $subnetPrefix
+#
+#
+# Create bastion subnet
+echo "Creating $bastionSubnet in $vNet"
+az network vnet subnet create --resource-group $resourceGroup --name $bastionSubnet --vnet-name $vNet --address-prefixes $addressPrefixBastion
+#
+#
+# Create a public IP address for the bastion host
+echo "Creating $bastionPublicIp"
+az network public-ip create --resource-group $resourceGroup --name $bastionPublicIp --sku $sku --zone $zone
+#
+#
+# Create the bastion host
+echo "Creating $bastionHost using $bastionPublicIp"
+az network bastion create --resource-group $resourceGroup --name $bastionHost --public-ip-address $bastionPublicIp --vnet-name $vNet --location "$location"
+#
+#
+# Configure NAT service for source subnet
+echo "Creating $natGateway for $subnet"
+az network vnet subnet update --resource-group $resourceGroup --vnet-name $vNet --name $subnet --nat-gateway $natGateway
+#
+#
+# Create virtual machine
+echo "Creating $vm"
+az vm create --name $vm --resource-group $resourceGroup --admin-username $login --admin-password $password --image $image --public-ip-address "" --subnet $subnet --vnet-name $vNet --public-ip-sku $sku
+#
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/filter-network-traffic/filter-network-traffic.sh b/virtual-network/filter-network-traffic/filter-network-traffic.sh
index 8dc0976e..4b876ae6 100644
--- a/virtual-network/filter-network-traffic/filter-network-traffic.sh
+++ b/virtual-network/filter-network-traffic/filter-network-traffic.sh
@@ -1,134 +1,89 @@
#!/bin/bash
-
-RgName="MyResourceGroup"
-Location="eastus"
-
-# Create a resource group.
-az group create \
- --name $RgName \
- --location $Location
+# Passed validation in Cloud Shell 02/03/2022
+
+#
+# Filter network traffic
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="filter-network-traffic-virtual-network"
+vNet="msdocs-vNet-$randomIdentifier"
+addressPrefixVNet="10.0.0.0/16"
+subnetFrontEnd="msdocs-frontend-subnet-$randomIdentifier"
+subnetPrefixFrontEnd="10.0.1.0/24"
+subnetBackEnd="msdocs-backend-subnet-$randomIdentifier"
+subnetPrefixBackEnd="10.0.2.0/24"
+nsgFrontEnd="msdocs-nsg-frontend-$randomIdentifier"
+nsgBackEnd="msdocs-nsg-frontend-$randomIdentifier"
+publicIpFrontEnd="msdocs-public-ip-frontend-$randomIdentifier"
+nicFrontEnd="msdocs-nic-front-end-$randomIdentifier"
+nicBackEnd="msdocs-nic-backend-$randomIdentifier"
+image="Ubuntu2204"
+login="azureuser"
+vm="msdocs-vm-$randomIdentifier"
+sku="BASIC"
+
+echo "Using resource group $resourceGroup with login: $login"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create a virtual network and a front-end subnet.
-az network vnet create \
- --resource-group $RgName \
- --name MyVnet \
- --address-prefix 10.0.0.0/16 \
- --location $Location \
- --subnet-name MySubnet-FrontEnd \
- --subnet-prefix 10.0.1.0/24
-
-# Create a back-end subnet.
-az network vnet subnet create \
- --address-prefix 10.0.2.0/24 \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --vnet-name MyVnet
+echo "Creating $vNet and $subnetFrontEnd"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefix $addressPrefixVNet --location "$location" --subnet-name $subnetFrontEnd --subnet-prefix $subnetPrefixFrontEnd
+
+# Create a backend subnet.
+echo "Creating $subnetBackEnd for $vNet"
+az network vnet subnet create --address-prefix $subnetPrefixBackEnd --name $subnetBackEnd --resource-group $resourceGroup --vnet-name $vNet
# Create a network security group (NSG) for the front-end subnet.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-FrontEnd \
- --location $Location
+echo "Creating $nsgFrontEnd for $subnetFrontEnd"
+az network nsg create --resource-group $resourceGroup --name $nsgFrontEnd --location "$location"
# Create NSG rules to allow HTTP & HTTPS traffic inbound.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTP-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 80
-
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTPS-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 200 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 443
+echo "Creating NSG rules in $nsgFrontEnd to allow HTTP and HTTPS inbound traffic"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-HTTP-All --access Allow --protocol Tcp --direction Inbound --priority 100 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 80
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-HTTPS-All --access Allow --protocol Tcp --direction Inbound --priority 200 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 443
# Create an NSG rule to allow SSH traffic in from the Internet to the front-end subnet.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-SSH-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 300 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 22
+echo "Creating NSG rule in $nsgFrontEnd to allow inbound SSH traffic"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-SSH-All --access Allow --protocol Tcp --direction Inbound --priority 300 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 22
# Associate the front-end NSG to the front-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-FrontEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-FrontEnd
-
-# Create a network security group for the back-end subnet.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-BackEnd \
- --location $Location
-
-# Create an NSG rule to block all outbound traffic from the back-end subnet to the Internet (inbound blocked by default).
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-BackEnd \
- --name Deny-Internet-All \
- --access Deny --protocol Tcp \
- --direction Outbound --priority 100 \
- --source-address-prefix "*" \
- --source-port-range "*" \
- --destination-address-prefix "Internet" \
- --destination-port-range "*"
-
-# Associate the back-end NSG to the back-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-BackEnd
+echo "Associate $nsgFrontEnd to $subnetFrontEnd"
+az network vnet subnet update --vnet-name $vNet --name $subnetFrontEnd --resource-group $resourceGroup --network-security-group $nsgFrontEnd
+
+# Create a network security group for the backend subnet.
+echo "Creating $nsgBackEnd for $subnetBackEnd"
+az network nsg create --resource-group $resourceGroup --name $nsgBackEnd --location "$location"
+
+# Create an NSG rule to block all outbound traffic from the backend subnet to the Internet (inbound blocked by default).
+echo "Creating NSG rule in $nsgBackEnd to block all outbound traffic from $subnetBackEnd"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgBackEnd --name Deny-Internet-All --access Deny --protocol Tcp --direction Outbound --priority 100 --source-address-prefix "*" --source-port-range "*" --destination-address-prefix "Internet" --destination-port-range "*"
+
+# Associate the backend NSG to the backend subnet.
+echo "Associate $nsgBackEnd to $subnetBackEnd"
+az network vnet subnet update --vnet-name $vNet --name $subnetBackEnd --resource-group $resourceGroup --network-security-group $nsgBackEnd
# Create a public IP address for the VM front-end network interface.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-FrontEnd \
- --allocation-method Dynamic
+echo "Creating $publicIpFrontEnd address for $publicIpFrontEnd"
+az network public-ip create --resource-group $resourceGroup --name $publicIpFrontEnd --allocation-method Dynamic
# Create a network interface for the VM attached to the front-end subnet.
-az network nic create \
- --resource-group $RgName \
- --vnet-name MyVnet \
- --subnet MySubnet-FrontEnd \
- --name MyNic-FrontEnd \
- --public-ip-address MyPublicIp-FrontEnd
-
-# Create a network interface for the VM attached to the back-end subnet.
-az network nic create \
- --resource-group $RgName \
- --vnet-name MyVnet \
- --subnet MySubnet-BackEnd \
- --name MyNic-BackEnd
+echo "Creating $nicFrontEnd for $subnetFrontEnd"
+az network nic create --resource-group $resourceGroup --vnet-name $vNet --subnet $subnetFrontEnd --name $nicFrontEnd --public-ip-address $publicIpFrontEnd
+
+# Create a network interface for the VM attached to the backend subnet.
+echo "Creating $nicBackEnd for $subnetBackEnd"
+az network nic create --resource-group $resourceGroup --vnet-name $vNet --subnet $subnetBackEnd --name $nicBackEnd
# Create the VM with both the FrontEnd and BackEnd NICs.
-az vm create \
- --resource-group $RgName \
- --name MyVm \
- --nics MyNic-FrontEnd MyNic-BackEnd \
- --image UbuntuLTS \
- --admin-username azureadmin \
- --generate-ssh-keys
+echo "Creating $vm with both NICs"
+az vm create --resource-group $resourceGroup --name $vm --nics $nicFrontEnd $nicBackEnd --image $image --admin-username $login --generate-ssh-keys --public-ip-sku $sku
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/peer-two-virtual-networks/peer-two-virtual-networks.sh b/virtual-network/peer-two-virtual-networks/peer-two-virtual-networks.sh
index fda18374..eff4b184 100644
--- a/virtual-network/peer-two-virtual-networks/peer-two-virtual-networks.sh
+++ b/virtual-network/peer-two-virtual-networks/peer-two-virtual-networks.sh
@@ -1,52 +1,49 @@
#!/bin/bash
+# Passed validation in Cloud Shell 02/03/2022
-RgName="MyResourceGroup"
-Location="eastus"
+#
+# Peer two virtual networks
-# Create a resource group.
-az group create \
- --name $RgName \
- --location $Location
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="peer-two-virtual-networks"
+vNet1="msdocs-vNet-$randomIdentifier"
+addressPrefixVNet1="10.0.0.0/16"
+vNet2="msdocs-vNet2-$randomIdentifier"
+addressPrefixVNet2="10.1.0.0/16"
+
+echo "Using resource group $resourceGroup with login: $login"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
# Create virtual network 1.
-az network vnet create \
- --name Vnet1 \
- --resource-group $RgName \
- --location $Location \
- --address-prefix 10.0.0.0/16
+echo "Creating $vNet1"
+az network vnet create --name $vNet1 --resource-group $resourceGroup --location "$location" --address-prefix $addressPrefixVNet1
# Create virtual network 2.
-az network vnet create \
- --name Vnet2 \
- --resource-group $RgName \
- --location $Location \
- --address-prefix 10.1.0.0/16
+echo "Creating $vNet2"
+az network vnet create --name $vNet2 --resource-group $resourceGroup --location "$location" --address-prefix $addressPrefixVNet2
# Get the id for VNet1.
-VNet1Id=$(az network vnet show \
- --resource-group $RgName \
- --name Vnet1 \
- --query id --out tsv)
+echo "Getting the id for $vNet1"
+VNet1Id=$(az network vnet show --resource-group $resourceGroup --name $vNet1 --query id --out tsv)
# Get the id for VNet2.
-VNet2Id=$(az network vnet show \
- --resource-group $RgName \
- --name Vnet2 \
- --query id \
- --out tsv)
+echo "Getting the id for $vNet2"
+VNet2Id=$(az network vnet show --resource-group $resourceGroup --name $vNet2 --query id --out tsv)
# Peer VNet1 to VNet2.
-az network vnet peering create \
- --name LinkVnet1ToVnet2 \
- --resource-group $RgName \
- --vnet-name VNet1 \
- --remote-vnet-id $VNet2Id \
- --allow-vnet-access
+echo "Peering $vNet1 to $vNet2"
+az network vnet peering create --name "Link"$vNet1"To"$vNet2 --resource-group $resourceGroup --vnet-name $vNet1 --remote-vnet $VNet2Id --allow-vnet-access
# Peer VNet2 to VNet1.
-az network vnet peering create \
- --name LinkVnet2ToVnet1 \
- --resource-group $RgName \
- --vnet-name VNet2 \
- --remote-vnet-id $VNet1Id \
- --allow-vnet-access
+echo "Peering $vNet2 to $vNet1"
+az network vnet peering create --name "Link"$vNet2"To"$vNet1 --resource-group $resourceGroup --vnet-name $vNet2 --remote-vnet $VNet1Id --allow-vnet-access
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/route-traffic-through-nva/route-traffic-through-nva.sh b/virtual-network/route-traffic-through-nva/route-traffic-through-nva.sh
index 30521e18..56944fe7 100644
--- a/virtual-network/route-traffic-through-nva/route-traffic-through-nva.sh
+++ b/virtual-network/route-traffic-through-nva/route-traffic-through-nva.sh
@@ -1,160 +1,116 @@
#!/bin/bash
-
-RgName="MyResourceGroup"
-Location="eastus"
-
-# Create a resource group.
-az group create \
- --name $RgName \
- --location $Location
-
-# Create a virtual network with a front-end subnet.
-az network vnet create \
- --name MyVnet \
- --resource-group $RgName \
- --location $Location \
- --address-prefix 10.0.0.0/16 \
- --subnet-name MySubnet-FrontEnd \
- --subnet-prefix 10.0.1.0/24
-
-# Create a network security group for the front-end subnet allowing HTTP and HTTPS inbound.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-FrontEnd \
- --location $Location
+# Passed validation in Cloud Shell 02/03/2022
+
+#
+# Route traffic through NVA
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="route-traffic-through-nva-virtual-networks"
+vNet="msdocs-vNet-$randomIdentifier"
+addressPrefixVNet="10.0.0.0/16"
+subnetFrontEnd="msdocs-frontend-subnet-$randomIdentifier"
+subnetPrefixFrontEnd="10.0.1.0/24"
+nsgFrontEnd="msdocs-nsg-frontend-$randomIdentifier"
+subnetBackEnd="msdocs-backend-subnet-$randomIdentifier"
+subnetPrefixBackEnd="10.0.2.0/24"
+dmzSubnet="msdocs-dmz-$randomIdentifier"
+dmzPrefix="10.0.0.0/24"
+publicIpFirewall="msdocs-publicIpFirewall-$randomIdentifier"
+nicFirewall="msdocs-nic-firewall-$randomIdentifier"
+vmFirewall="msdocs-vm-$randomIdentifier"
+sku="BASIC"
+image="Ubuntu2204"
+login="azureuser"
+routeTableFrontEndSubnet="msdocs-route-table-frontend-subnet-$randomIdentifier"
+routeToBackEnd="msdocs-route-backend-$randomIdentifier"
+routeToInternetFrontEnd="msdocs-route-internet-frontend-$randomIdentifier"
+routeToInternetPrefix="0.0.0.0/0"
+routeTableBackEndSubnet="msdocs-route-table-backend-subnet-$randomIdentifier"
+routeToFrontEnd="msdocs-route-frontend-$randomIdentifier"
+routeToInternetBackEnd="msdocs-route-internet-backend-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network and a front-end subnet.
+echo "Creating $vNet and $subnetFrontEnd"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefix $addressPrefixVNet --location "$location" --subnet-name $subnetFrontEnd --subnet-prefix $subnetPrefixFrontEnd
+
+# Create a network security group (NSG) for the front-end subnet.
+echo "Creating $nsgFrontEnd for $subnetFrontEnd"
+az network nsg create --resource-group $resourceGroup --name $nsgFrontEnd --location "$location"
# Create NSG rules to allow HTTP & HTTPS traffic inbound.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTP-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 80
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTPS-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 200 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 443
+echo "Creating NSG rules in $nsgFrontEnd to allow HTTP and HTTPS inbound traffic"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-HTTP-All --access Allow --protocol Tcp --direction Inbound --priority 100 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 80
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-HTTPS-All --access Allow --protocol Tcp --direction Inbound --priority 200 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 443
# Associate the front-end NSG to the front-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-FrontEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-FrontEnd
-
-# Create the back-end subnet.
-az network vnet subnet create \
- --address-prefix 10.0.2.0/24 \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --vnet-name MyVnet
+echo "Associate $nsgFrontEnd to $subnetFrontEnd"
+az network vnet subnet update --vnet-name $vNet --name $subnetFrontEnd --resource-group $resourceGroup --network-security-group $nsgFrontEnd
+
+# Create a backend subnet.
+echo "Creating $subnetBackEnd for $vNet"
+az network vnet subnet create --address-prefix $subnetPrefixBackEnd --name $subnetBackEnd --resource-group $resourceGroup --vnet-name $vNet
#Create the DMZ subnet.
-az network vnet subnet create \
- --address-prefix 10.0.0.0/24 \
- --name MySubnet-Dmz \
- --resource-group $RgName \
- --vnet-name MyVnet
+echo "Creating $dmzSubnet for $vNet"
+az network vnet subnet create --address-prefix $dmzPrefix --name $dmzSubnet --resource-group $resourceGroup --vnet-name $vNet
# Create a public IP address for the firewall VM.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIP-Firewall
+echo "Creating $publicIpFirewall"
+az network public-ip create --resource-group $resourceGroup --name $publicIpFirewall
# Create a NIC for the firewall VM and enable IP forwarding.
-az network nic create \
- --resource-group $RgName \
- --name MyNic-Firewall \
- --vnet-name MyVnet \
- --subnet MySubnet-Dmz \
- --public-ip-address MyPublicIp-Firewall \
- --ip-forwarding
-
-#Create a firewall VM to accept all traffic between the front and back-end subnets.
-az vm create \
- --resource-group $RgName \
- --name MyVm-Firewall \
- --nics MyNic-Firewall \
- --image UbuntuLTS \
- --admin-username azureadmin \
- --generate-ssh-keys
+echo "Creating $nicFirewall with IP forwarding"
+az network nic create --resource-group $resourceGroup --name $nicFirewall --vnet-name $vNet --subnet $dmzSubnet --public-ip-address $publicIpFirewall --ip-forwarding
+
+#Create a firewall VM to accept all traffic between the front and backend subnets.
+echo "Creating $vmFirewall"
+az vm create --resource-group $resourceGroup --name $vmFirewall --nics $nicFirewall --image $image --admin-username $login --generate-ssh-keys --public-ip-sku $sku
# Get the private IP address from the VM for the user-defined route.
-Fw1Ip=$(az vm list-ip-addresses \
- --resource-group $RgName \
- --name MyVm-Firewall \
- --query [].virtualMachine.network.privateIpAddresses[0] --out tsv)
+echo "Get the private IP address from $vmFirewall"
+Fw1Ip=$(az vm list-ip-addresses --resource-group $resourceGroup --name $vmFirewall --query [].virtualMachine.network.privateIpAddresses[0] --out tsv)
# Create route table for the FrontEnd subnet.
-az network route-table create \
- --name MyRouteTable-FrontEnd \
- --resource-group $RgName
-
-# Create a route for traffic from the front-end to the back-end subnet through the firewall VM.
-az network route-table route create \
- --name RouteToBackEnd \
- --resource-group $RgName \
- --route-table-name MyRouteTable-FrontEnd \
- --address-prefix 10.0.2.0/24 \
- --next-hop-type VirtualAppliance \
- --next-hop-ip-address $Fw1Ip
+echo "Creating $routeTableFrontEndSubnet"
+az network route-table create --name $routeTableFrontEndSubnet --resource-group $resourceGroup
+
+# Create a route for traffic from the front-end to the backend subnet through the firewall VM.
+echo "Creating $routeToBackEnd to $subnetPrefixBackEnd in $routeTableFrontEndSubnet"
+az network route-table route create --name $routeToBackEnd --resource-group $resourceGroup --route-table-name $routeTableFrontEndSubnet --address-prefix $subnetPrefixBackEnd --next-hop-type VirtualAppliance --next-hop-ip-address $Fw1Ip
# Create a route for traffic from the front-end subnet to the Internet through the firewall VM.
-az network route-table route create \
- --name RouteToInternet \
- --resource-group $RgName \
- --route-table-name MyRouteTable-FrontEnd \
- --address-prefix 0.0.0.0/0 \
- --next-hop-type VirtualAppliance \
- --next-hop-ip-address $Fw1Ip
+echo "Creating route $routeToInternetFrontEnd to Internet in $routeTableFrontEndSubnet"
+az network route-table route create --name $routeToInternetFrontEnd --resource-group $resourceGroup --route-table-name $routeTableFrontEndSubnet --address-prefix $routeToInternetPrefix --next-hop-type VirtualAppliance --next-hop-ip-address $Fw1Ip
# Associate the route table to the FrontEnd subnet.
-az network vnet subnet update \
- --name MySubnet-FrontEnd \
- --vnet-name MyVnet \
- --resource-group $RgName \
- --route-table MyRouteTable-FrontEnd
+echo "Associate $routeTableFrontEndSubnet to $subnetFrontEnd"
+az network vnet subnet update --name $subnetFrontEnd --vnet-name $vNet --resource-group $resourceGroup --route-table $routeTableFrontEndSubnet
# Create route table for the BackEnd subnet.
-az network route-table create \
- --name MyRouteTable-BackEnd \
- --resource-group $RgName
-
-# Create a route for traffic from the back-end subnet to the front-end subnet through the firewall VM.
-az network route-table route create \
- --name RouteToFrontEnd \
- --resource-group $RgName \
- --route-table-name MyRouteTable-BackEnd \
- --address-prefix 10.0.1.0/24 \
- --next-hop-type VirtualAppliance \
- --next-hop-ip-address $Fw1Ip
-
-# Create a route for traffic from the back-end subnet to the Internet through the firewall VM.
-az network route-table route create \
- --name RouteToInternet \
- --resource-group $RgName \
- --route-table-name MyRouteTable-BackEnd \
- --address-prefix 0.0.0.0/0 \
- --next-hop-type VirtualAppliance \
- --next-hop-ip-address $Fw1Ip
+echo "Creating $routeTableBackEndSubnet"
+az network route-table create --name $routeTableBackEndSubnet --resource-group $resourceGroup
+
+# Create a route for traffic from the backend subnet to the front-end subnet through the firewall VM.
+echo "Creating $routeToFrontEnd to $subnetPrefixBackEnd in $routeTableBackEndSubnet"
+az network route-table route create --name $routeToFrontEnd --resource-group $resourceGroup --route-table-name $routeTableBackEndSubnet --address-prefix $subnetPrefixBackEnd --next-hop-type VirtualAppliance --next-hop-ip-address $Fw1Ip
+
+# Create a route for traffic from the backend subnet to the Internet through the firewall VM.
+echo "Creating route $routeToInternetBackEnd to Internet in $routeTableBackEndSubnet"
+az network route-table route create --name $routeToInternetBackEnd --resource-group $resourceGroup --route-table-name $routeTableBackEndSubnet --address-prefix $routeToInternetPrefix --next-hop-type VirtualAppliance --next-hop-ip-address $Fw1Ip
# Associate the route table to the BackEnd subnet.
-az network vnet subnet update \
- --name MySubnet-BackEnd \
- --vnet-name MyVnet \
- --resource-group $RgName \
- --route-table MyRouteTable-BackEnd
+echo "Associate $routeTableBackEndSubnet to $subnetBackEnd"
+az network vnet subnet update --name $subnetBackEnd --vnet-name $vNet --resource-group $resourceGroup --route-table $routeTableBackEndSubnet
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer/virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer.sh b/virtual-network/virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer/virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer.sh
new file mode 100644
index 00000000..ddb2f9ff
--- /dev/null
+++ b/virtual-network/virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer/virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer.sh
@@ -0,0 +1,143 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 02/03/2022
+
+#
+# Use IPv6 for vNet with standard SKU
+
+# IMPORTANT
+# To use the IPv6 for Azure virtual network feature,
+# you must configure your subscription only once as follows:
+#
+# az feature register --name AllowIPv6VirtualNetwork --namespace Microsoft.Network
+# az feature register --name AllowIPv6CAOnStandardLB --namespace Microsoft.Network
+#
+# It takes up to 30 minutes for feature registration to complete.
+# You can check your registration status by running the following Azure CLI command:
+#
+# az feature show --name AllowIPv6VirtualNetwork --namespace Microsoft.Network
+# az feature show --name AllowIPv6CAOnStandardLB --namespace Microsoft.Network
+#
+# After the registration is complete, run the following command:
+#
+# az provider register --namespace Microsoft.Network
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="virtual-network-cli-sample-ipv6-dual-stack-standard-load-balancer"
+ipV4PublicIp="msdocs-ipV4-public-ip-address-$randomIdentifier"
+ipV6PublicIp="msdocs-ipV6-public-ip-address-$randomIdentifier"
+zone="1"
+ipV4RemoteAccessVm0="msdocs-ipV4-pubic-ip-for-vm0-remote-access-$randomIdentifier"
+ipV4RemoteAccessVm1="msdocs-ipV4-pubic-ip-for-vm1-remote-access-$randomIdentifier"
+sku="STANDARD"
+allocationMethod="static"
+loadBalancer="msdocs-load-balancer-$randomIdentifier"
+lbFrontEndV4="msdocs-frontend-ip--$randomIdentifier"
+lbPublicIpV4="msdocs-public-ip-$randomIdentifier"
+lbBackEndPoolV4="msdocs-backend-pool-$randomIdentifier"
+loadBalancerFrontEnd_v6="msdocs-load-balancer-frontend-ip-v6-$randomIdentifier"
+loadBalancerBackEndPool_v6="msdocs-load-balancer-backend-pool-v6-$randomIdentifier"
+loadBalancerRule_v4="msdocs-lb-rule-v4-$randomIdentifier"
+loadBalancerRule_v6="msdocs-lb-rule-v6-$randomIdentifier"
+availabilitySet="msdocs-availability-set-$randomIdentifier"
+nsg="msdocs-network-security-group-$randomIdentifier"
+vNet="msdocs-virtual-network-$randomIdentifier"
+vNetAddressPrefixes="10.0.0.0/16 fd00:db8:deca::/48"
+subnet="msdocs-single-dual-stack-subnet-$randomIdentifier"
+subnetAddressPrefixes="10.0.0.0/16 fd00:db8:deca:deed::/64"
+nic0="msdocs-nic0-$randomIdentifier"
+nic1="msdocs-nic1-$randomIdentifier"
+nic0ConfigIpV6="msdocs-ipV6-config-nic0-$randomIdentifier"
+nic1ConfigIpV6="msdocs-ipV6-config-nic1-$randomIdentifier"
+vm0="docvm0$randomIdentifier"
+vm1="docvm1$randomIdentifier"
+image="MicrosoftWindowsServer:WindowsServer:2016-Datacenter:latest"
+vmSize="Standard_A2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an IPV4 IP address
+echo "Creating $ipV4PublicIp"
+az network public-ip create --name $ipV4PublicIp --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv4 --zone $zone
+
+# Create an IPV6 IP address
+echo "Creating $ipV6PublicIp"
+az network public-ip create --name $ipV6PublicIp --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv6 --zone $zone
+
+# Create public IP addresses for remote access to VMs
+echo "Creating $ipV4RemoteAccessVm0 and $ipV4RemoteAccessVm1"
+az network public-ip create --name $ipV4RemoteAccessVm0 --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv4 --zone $zone
+az network public-ip create --name $ipV4RemoteAccessVm1 --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv4 --zone $zone
+
+# Create load balancer
+echo "Creating $loadBalancer"
+az network lb create --name $loadBalancer --resource-group $resourceGroup --sku $sku --location "$location" --frontend-ip-name $lbFrontEndV4 --public-ip-address $lbPublicIpV4 --backend-pool-name $lbBackEndPoolV4
+
+# Create IPv6 front-end
+echo "Creating $ipV6PublicIp"
+az network lb frontend-ip create --lb-name $loadBalancer --name $loadBalancerFrontEnd_v6 --resource-group $resourceGroup --public-ip-address $ipV6PublicIp
+
+# Configure IPv6 back-end address pool
+echo "Creating $loadBalancerBackEndPool_v6"
+az network lb address-pool create --lb-name $loadBalancer --name $loadBalancerBackEndPool_v6 --resource-group $resourceGroup
+
+# Create a load balancer rules
+echo "Creating $loadBalancerRule_v4"
+az network lb rule create --lb-name $loadBalancer --name $loadBalancerRule_v4 --resource-group $resourceGroup --frontend-ip-name $lbFrontEndV4 --protocol Tcp --frontend-port 80 --backend-port 80 --backend-pool-name $lbBackEndPoolV4
+az network lb rule create --lb-name $loadBalancer --name $loadBalancerRule_v6 --resource-group $resourceGroup --frontend-ip-name $loadBalancerFrontEnd_v6 --protocol Tcp --frontend-port 80 --backend-port 80 --backend-pool-name $loadBalancerBackEndPool_v6
+
+# Create an availability set
+echo "Creating $availabilitySet"
+az vm availability-set create --name $availabilitySet --resource-group $resourceGroup --location "$location" --platform-fault-domain-count 2 --platform-update-domain-count 2
+
+# Create network security group
+echo "Creating $nsg"
+az network nsg create --name $nsg --resource-group $resourceGroup --location "$location"
+
+# Create inbound rule for port 3389
+echo "Creating inbound rule in $nsg for port 3389"
+az network nsg rule create --name allowRdpIn --nsg-name $nsg --resource-group $resourceGroup --priority 100 --description "Allow Remote Desktop In" --access Allow --protocol "*" --direction Inbound --source-address-prefixes "*" --source-port-ranges 3389 --destination-address-prefixes "*" --destination-port-ranges 3389
+
+# Create inbound rule for port 80
+echo "Creating inbound rule in $nsg for port 80"
+az network nsg rule create --name allowRdpIn --nsg-name $nsg --resource-group $resourceGroup --priority 200 --description "Allow HTTP In" --access Allow --protocol "*" --direction Inbound --source-address-prefixes "*" --source-port-ranges 80 --destination-address-prefixes "*" --destination-port-ranges 80
+
+# Create outbound rule
+echo "Creating outbound rule in $nsg to allow all"
+az network nsg rule create --name allowAllOut --nsg-name $nsg --resource-group $resourceGroup --priority 300 --description "Allow All Out" --access Allow --protocol "*" --direction Outbound --source-address-prefixes "*" --source-port-ranges "*" --destination-address-prefixes "*" --destination-port-ranges "*"
+
+# Create the virtual network with IPv4 and IPv6 addresses
+echo "Creating $vNet"
+az network vnet create --name $vNet --resource-group $resourceGroup --location "$location" --address-prefixes $vNetAddressPrefixes
+
+# Create a single dual stack subnet with IPv4 and IPv6 addresses
+echo "Creating $subnet"
+az network vnet subnet create --name $subnet --resource-group $resourceGroup --vnet-name $vNet --address-prefixes $subnetAddressPrefixes --network-security-group $nsg
+
+# Create NICs
+echo "Creating $nic0 and $nic1"
+az network nic create --name $nic0 --resource-group $resourceGroup --network-security-group $nsg --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv4 --lb-address-pools $lbBackEndPoolV4 --lb-name $loadBalancer --public-ip-address $ipV4RemoteAccessVm1
+az network nic create --name $nic1 --resource-group $resourceGroup --network-security-group $nsg --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv4 --lb-address-pools $lbBackEndPoolV4 --lb-name $loadBalancer --public-ip-address $ipV4RemoteAccessVm0
+
+# Create IPV6 configurations for each NIC
+echo "Creating $nic0ConfigIpV6 and $nic1ConfigIpV6"
+az network nic ip-config create --name $nic0ConfigIpV6 --nic-name $nic0 --resource-group $resourceGroup --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv6 --lb-address-pools $loadBalancerBackEndPool_v6 --lb-name $loadBalancer
+az network nic ip-config create --name $nic1ConfigIpV6 --nic-name $nic1 --resource-group $resourceGroup --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv6 --lb-address-pools $loadBalancerBackEndPool_v6 --lb-name $loadBalancer
+
+# Create virtual machines
+# When prompted, provide a complex password for the admin account for each Windows virtual machine
+Creating "$vm0 and $vm1"
+az vm create --name $vm0 --resource-group $resourceGroup --nics $nic0 --size $vmSize --availability-set $availabilitySet --image $image --public-ip-sku $sku --admin-user $login --admin-password $password
+az vm create --name $vm1 --resource-group $resourceGroup --nics $nic1 --size $vmSize --availability-set $availabilitySet --image $image --public-ip-sku $sku --admin-user $login --admin-password $password
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/virtual-network-cli-sample-ipv6-dual-stack/virtual-network-cli-sample-ipv6-dual-stack.sh b/virtual-network/virtual-network-cli-sample-ipv6-dual-stack/virtual-network-cli-sample-ipv6-dual-stack.sh
new file mode 100644
index 00000000..fcb433c9
--- /dev/null
+++ b/virtual-network/virtual-network-cli-sample-ipv6-dual-stack/virtual-network-cli-sample-ipv6-dual-stack.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+# Passed validation in Cloud Shell 02/03/2022
+
+#
+# Use IPv6 for vNet with basic SKU
+
+# IMPORTANT
+# To use the IPv6 for Azure virtual network feature,
+# you must configure your subscription only once as follows:
+#
+# az feature register --name AllowIPv6VirtualNetwork --namespace Microsoft.Network
+# az feature register --name AllowIPv6CAOnStandardLB --namespace Microsoft.Network
+#
+# It takes up to 30 minutes for feature registration to complete.
+# You can check your registration status by running the following Azure CLI command:
+#
+# az feature show --name AllowIPv6VirtualNetwork --namespace Microsoft.Network
+# az feature show --name AllowIPv6CAOnStandardLB --namespace Microsoft.Network
+#
+# After the registration is complete, run the following command:
+#
+# az provider register --namespace Microsoft.Network
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="virtual-network-cli-sample-ipv6-dual-stack"
+ipV4PublicIp="msdocs-ipV4-public-ip-address-$randomIdentifier"
+ipV6PublicIp="msdocs-ipV6-public-ip-address-$randomIdentifier"
+ipV4RemoteAccessVm0="msdocs-ipV4-pubic-ip-for-vm0-remote-access-$randomIdentifier"
+ipV4RemoteAccessVm1="msdocs-ipV4-pubic-ip-for-vm1-remote-access-$randomIdentifier"
+sku="BASIC"
+allocationMethod="dynamic"
+loadBalancer="msdocs-load-balancer-$randomIdentifier"
+lbFrontEndV4="msdocs-frontend-ip--$randomIdentifier"
+lbPublicIpV4="msdocs-public-ip-$randomIdentifier"
+lbBackEndPoolV4="msdocs-backend-pool-$randomIdentifier"
+loadBalancerFrontEnd_v6="msdocs-load-balancer-frontend-ip-v6-$randomIdentifier"
+loadBalancerBackEndPool_v6="msdocs-load-balancer-backend-pool-v6-$randomIdentifier"
+loadBalancerRule_v4="msdocs-lb-rule-v4-$randomIdentifier"
+loadBalancerRule_v6="msdocs-lb-rule-v6-$randomIdentifier"
+availabilitySet="msdocs-availability-set-$randomIdentifier"
+nsg="msdocs-network-security-group-$randomIdentifier"
+vNet="msdocs-virtual-network-$randomIdentifier"
+vNetAddressPrefixes="10.0.0.0/16 fd00:db8:deca::/48"
+subnet="msdocs-single-dual-stack-subnet-$randomIdentifier"
+subnetAddressPrefixes="10.0.0.0/24 fd00:db8:deca:deed::/64"
+nic0="msdocs-nic0-$randomIdentifier"
+nic1="msdocs-nic1-$randomIdentifier"
+nic0ConfigIpV6="msdocs-ipV6-config-nic0-$randomIdentifier"
+nic1ConfigIpV6="msdocs-ipV6-config-nic1-$randomIdentifier"
+vm0="docvm0$randomIdentifier"
+vm1="docvm1$randomIdentifier"
+image="MicrosoftWindowsServer:WindowsServer:2016-Datacenter:latest"
+vmSize="Standard_A2"
+login="azureuser"
+password="Pa$$w0rD-$randomIdentifier"
+
+echo "Using resource group $resourceGroup with login: $login, password: $password..."
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create an IPV4 IP address
+echo "Creating $ipV4PublicIp"
+az network public-ip create --name $ipV4PublicIp --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv4
+
+# Create an IPV6 IP address
+echo "Creating $ipV6PublicIp"
+az network public-ip create --name $ipV6PublicIp --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv6
+
+# Create public IP addresses for remote access to VMs
+echo "Creating $ipV4RemoteAccessVm0 and $ipV4RemoteAccessVm1"
+az network public-ip create --name $ipV4RemoteAccessVm0 --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv4
+az network public-ip create --name $ipV4RemoteAccessVm1 --resource-group $resourceGroup --location "$location" --sku $sku --allocation-method $allocationMethod --version IPv4
+
+# Create load balancer
+echo "Creating $loadBalancer"
+az network lb create --name $loadBalancer --resource-group $resourceGroup --sku $sku --location "$location" --frontend-ip-name $lbFrontEndV4 --public-ip-address $lbPublicIpV4 --backend-pool-name $lbBackEndPoolV4
+
+# Create IPv6 front-end
+echo "Creating $ipV6PublicIp"
+az network lb frontend-ip create --lb-name $loadBalancer --name $loadBalancerFrontEnd_v6 --resource-group $resourceGroup --public-ip-address $ipV6PublicIp
+
+# Configure IPv6 back-end address pool
+echo "Creating $loadBalancerBackEndPool_v6"
+az network lb address-pool create --lb-name $loadBalancer --name $loadBalancerBackEndPool_v6 --resource-group $resourceGroup
+
+# Create a load balancer rules
+echo "Creating $loadBalancerRule_v4"
+az network lb rule create --lb-name $loadBalancer --name $loadBalancerRule_v4 --resource-group $resourceGroup --frontend-ip-name $lbFrontEndV4 --protocol Tcp --frontend-port 80 --backend-port 80 --backend-pool-name $lbBackEndPoolV4
+az network lb rule create --lb-name $loadBalancer --name $loadBalancerRule_v6 --resource-group $resourceGroup --frontend-ip-name $loadBalancerFrontEnd_v6 --protocol Tcp --frontend-port 80 --backend-port 80 --backend-pool-name $loadBalancerBackEndPool_v6
+
+# Create an availability set
+echo "Creating $availabilitySet"
+az vm availability-set create --name $availabilitySet --resource-group $resourceGroup --location "$location" --platform-fault-domain-count 2 --platform-update-domain-count 2
+
+# Create network security group
+echo "Creating $nsg"
+az network nsg create --name $nsg --resource-group $resourceGroup --location "$location"
+
+# Create inbound rule for port 3389
+echo "Creating inbound rule in $nsg for port 3389"
+az network nsg rule create --name allowRdpIn --nsg-name $nsg --resource-group $resourceGroup --priority 100 --description "Allow Remote Desktop In" --access Allow --protocol "*" --direction Inbound --source-address-prefixes "*" --source-port-ranges 3389 --destination-address-prefixes "*" --destination-port-ranges 3389
+
+# Create outbound rule
+echo "Creating outbound rule in $nsg to allow all"
+az network nsg rule create --name allowAllOut --nsg-name $nsg --resource-group $resourceGroup --priority 100 --description "Allow All Out" --access Allow --protocol "*" --direction Outbound --source-address-prefixes "*" --source-port-ranges "*" --destination-address-prefixes "*" --destination-port-ranges "*"
+
+# Create the virtual network with IPv4 and IPv6 addresses
+echo "Creating $vNet"
+az network vnet create --name $vNet --resource-group $resourceGroup --location "$location" --address-prefixes $vNetAddressPrefixes
+
+# Create a single dual stack subnet with IPv4 and IPv6 addresses
+echo "Creating $subnet"
+az network vnet subnet create --name $subnet --resource-group $resourceGroup --vnet-name $vNet --address-prefixes $subnetAddressPrefixes --network-security-group $nsg
+
+# Create NICs
+echo "Creating $nic0 and $nic1"
+az network nic create --name $nic0 --resource-group $resourceGroup --network-security-group $nsg --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv4 --lb-address-pools $lbBackEndPoolV4 --lb-name $loadBalancer --public-ip-address $ipV4RemoteAccessVm1
+az network nic create --name $nic1 --resource-group $resourceGroup --network-security-group $nsg --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv4 --lb-address-pools $lbBackEndPoolV4 --lb-name $loadBalancer --public-ip-address $ipV4RemoteAccessVm0
+
+# Create IPV6 configurations for each NIC
+echo "Creating $nic0ConfigIpV6 and $nic1ConfigIpV6"
+az network nic ip-config create --name $nic0ConfigIpV6 --nic-name $nic0 --resource-group $resourceGroup --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv6 --lb-address-pools $loadBalancerBackEndPool_v6 --lb-name $loadBalancer
+az network nic ip-config create --name $nic1ConfigIpV6 --nic-name $nic1 --resource-group $resourceGroup --vnet-name $vNet --subnet $subnet --private-ip-address-version IPv6 --lb-address-pools $loadBalancerBackEndPool_v6 --lb-name $loadBalancer
+
+# Create virtual machines
+Creating "$vm0 and $vm1"
+az vm create --name $vm0 --resource-group $resourceGroup --nics $nic0 --size $vmSize --availability-set $availabilitySet --image $image --public-ip-sku $sku --admin-user $login --admin-password $password
+az vm create --name $vm1 --resource-group $resourceGroup --nics $nic1 --size $vmSize --availability-set $availabilitySet --image $image --public-ip-sku $sku --admin-user $login --admin-password $password
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/virtual-network-multi-tier-application/virtual-network-multi-tier-application.sh b/virtual-network/virtual-network-multi-tier-application/virtual-network-multi-tier-application.sh
index 969fb5de..a8d59ad9 100644
--- a/virtual-network/virtual-network-multi-tier-application/virtual-network-multi-tier-application.sh
+++ b/virtual-network/virtual-network-multi-tier-application/virtual-network-multi-tier-application.sh
@@ -1,164 +1,107 @@
#!/bin/bash
-
-RgName="MyResourceGroup"
-Location="eastus"
-
-# Create a resource group.
-az group create \
- --name $RgName \
- --location $Location
-
-# Create a virtual network with a front-end subnet.
-az network vnet create \
- --name MyVnet \
- --resource-group $RgName \
- --location $Location \
- --address-prefix 10.0.0.0/16 \
- --subnet-name MySubnet-FrontEnd \
- --subnet-prefix 10.0.1.0/24
-
-# Create a back-end subnet.
-az network vnet subnet create \
- --address-prefix 10.0.2.0/24 \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --vnet-name MyVnet
-
-# Create a network security group for the front-end subnet.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-FrontEnd \
- --location $Location
-
-# Create an NSG rule to allow HTTP traffic in from the Internet to the front-end subnet.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTP-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 80
+# Passed validation in Cloud Shell 02/03/2022
+
+#
+# Create vNet for multi-tier application
+
+# Variable block
+let "randomIdentifier=$RANDOM*$RANDOM"
+location="East US"
+resourceGroup="msdocs-virtual-network-rg-$randomIdentifier"
+tag="virtual-network-multi-tier-application"
+vNet="msdocs-vNet-$randomIdentifier"
+addressPrefixVNet="10.0.0.0/16"
+subnetFrontEnd="msdocs-frontend-subnet-$randomIdentifier"
+subnetPrefixFrontEnd="10.0.1.0/24"
+nsgFrontEnd="msdocs-nsg-frontend-$randomIdentifier"
+subnetBackEnd="msdocs-backend-subnet-$randomIdentifier"
+subnetPrefixBackEnd="10.0.2.0/24"
+nsgBackEnd="msdocs-nsg-backend-$randomIdentifier"
+publicIpWeb="msdocs-public-ip-web-$randomIdentifier"
+publicIpSql="msdocs-public-ip-sql-$randomIdentifier"
+nicWeb="msdocs-nic-web-$randomIdentifier"
+nicSql="msdocs-nic-sql-$randomIdentifier"
+image="Ubuntu2204"
+login="azureuser"
+vmWeb="msdocs-vm-web$randomIdentifier"
+vmSql="msdocs-vm-sql$randomIdentifier"
+sku="BASIC"
+
+echo "Using resource group $resourceGroup with login: $login"
+
+# Create a resource group
+echo "Creating $resourceGroup in $location..."
+az group create --name $resourceGroup --location "$location" --tags $tag
+
+# Create a virtual network and a front-end subnet.
+echo "Creating $vNet and $subnetFrontEnd"
+az network vnet create --resource-group $resourceGroup --name $vNet --address-prefix $addressPrefixVNet --location "$location" --subnet-name $subnetFrontEnd --subnet-prefix $subnetPrefixFrontEnd
+
+# Create a backend subnet.
+echo "Creating $subnetBackEnd"
+az network vnet subnet create --address-prefix $subnetPrefixBackEnd --name $subnetBackEnd --resource-group $resourceGroup --vnet-name $vNet
+
+# Create a network security group (NSG) for the front-end subnet.
+echo "Creating $nsgFrontEnd for $subnetFrontEnd"
+az network nsg create --resource-group $resourceGroup --name $nsgFrontEnd --location "$location"
+
+# Create NSG rules to allow HTTP & HTTPS traffic inbound.
+echo "Creating $nsgFrontEnd rules in $nsgFrontEnd to allow HTTP and HTTPS inbound traffic"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-HTTP-All --access Allow --protocol Tcp --direction Inbound --priority 100 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 80
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-HTTPS-All --access Allow --protocol Tcp --direction Inbound --priority 200 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 443
# Create an NSG rule to allow SSH traffic in from the Internet to the front-end subnet.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-SSH-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 300 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 22
+echo "Creating NSG rule in $nsgFrontEnd to allow inbound SSH traffic"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgFrontEnd --name Allow-SSH-All --access Allow --protocol Tcp --direction Inbound --priority 300 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 22
# Associate the front-end NSG to the front-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-FrontEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-FrontEnd
-
-# Create a network security group for back-end subnet.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-BackEnd \
- --location $Location
-
-# Create an NSG rule to allow MySQL traffic from the front-end subnet to the back-end subnet.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-BackEnd \
- --name Allow-MySql-FrontEnd \
- --access Allow --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix 10.0.1.0/24 \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 3306
-
-# Create an NSG rule to allow SSH traffic from the Internet to the front-end subnet.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-BackEnd \
- --name Allow-SSH-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 200 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 22
-
-# Create an NSG rule to block all outbound traffic from the back-end subnet to the Internet (NOTE: If you run the MySQL installation below this rule will be disabled and then re-enabled).
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-BackEnd \
- --name Deny-Internet-All \
- --access Deny --protocol Tcp \
- --direction Outbound --priority 300 \
- --source-address-prefix "*" \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range "*"
-
-# Associate the back-end NSG to the back-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-BackEnd
+echo "Associate $nsgFrontEnd to $subnetFrontEnd"
+az network vnet subnet update --vnet-name $vNet --name $subnetFrontEnd --resource-group $resourceGroup --network-security-group $nsgFrontEnd
+
+# Create a network security group for the backend subnet.
+echo "Creating $nsgBackEnd for $subnetBackEnd"
+az network nsg create --resource-group $resourceGroup --name $nsgBackEnd --location "$location"
+
+# Create an NSG rule to allow MySQL traffic from the front-end subnet to the backend subnet.
+echo "Creating NSG rule in $nsgBackEnd to allow MySQL traffic from $subnetFrontEnd to $subnetBackEnd"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgBackEnd --name Allow-MySql-FrontEnd --access Allow --protocol Tcp --direction Inbound --priority 100 --source-address-prefix $subnetPrefixFrontEnd --source-port-range "*" --destination-address-prefix "*" --destination-port-range 3306
+
+# Create an NSG rule to allow SSH traffic from the Internet to the backend subnet.
+echo "Creating NSG rule in $nsgBackEnd to allow SSH traffic from the Internet to $subnetBackEnd"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgBackEnd --name Allow-SSH-All --access Allow --protocol Tcp --direction Inbound --priority 200 --source-address-prefix Internet --source-port-range "*" --destination-address-prefix "*" --destination-port-range 22
+
+# Create an NSG rule to block all outbound traffic from the backend subnet to the Internet (NOTE: If you run the MySQL installation below this rule will be disabled and then re-enabled).
+echo "Creating NSG rule in $nsgBackEnd to block all outbound traffic from $subnetBackEnd"
+az network nsg rule create --resource-group $resourceGroup --nsg-name $nsgBackEnd --name Deny-Internet-All --access Deny --protocol Tcp --direction Outbound --priority 300 --source-address-prefix "*" --source-port-range "*" --destination-address-prefix "*" --destination-port-range "*"
+
+# Associate the backend NSG to the backend subnet.
+echo "Associate $nsgBackEnd to $subnetBackEnd"
+az network vnet subnet update --vnet-name $vNet --name $subnetBackEnd --resource-group $resourceGroup --network-security-group $nsgBackEnd
# Create a public IP address for the web server VM.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIP-Web
+echo "Creating $publicIpWeb for $vmWeb"
+az network public-ip create --resource-group $resourceGroup --name $publicIpWeb
# Create a NIC for the web server VM.
-az network nic create \
- --resource-group $RgName \
- --name MyNic-Web \
- --vnet-name MyVnet \
- --subnet MySubnet-FrontEnd \
- --network-security-group MyNsg-FrontEnd \
- --public-ip-address MyPublicIP-Web
+echo "Creating $nicWeb for $vmWeb"
+az network nic create --resource-group $resourceGroup --name $nicWeb --vnet-name $vNet --subnet $subnetFrontEnd --network-security-group $nsgFrontEnd --public-ip-address $publicIpWeb
# Create a Web Server VM in the front-end subnet.
-az vm create \
- --resource-group $RgName \
- --name MyVm-Web \
- --nics MyNic-Web \
- --image UbuntuLTS \
- --admin-username azureadmin \
- --generate-ssh-keys
+echo "Creating $vmWeb in $subnetFrontEnd"
+az vm create --resource-group $resourceGroup --name $vmWeb --nics $nicWeb --image $image --admin-username $login --generate-ssh-keys --public-ip-sku $sku
# Create a public IP address for the MySQL VM.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIP-Sql
+echo "Creating $publicIpSql for $vmSql"
+az network public-ip create --resource-group $resourceGroup --name $publicIpSql
# Create a NIC for the MySQL VM.
-az network nic create \
- --resource-group $RgName \
- --name MyNic-Sql \
- --vnet-name MyVnet \
- --subnet MySubnet-BackEnd \
- --network-security-group MyNsg-BackEnd \
- --public-ip-address MyPublicIP-Sql
-
-# Create a MySQL VM in the back-end subnet.
-az vm create \
- --resource-group $RgName \
- --name MyVm-Sql \
- --nics MyNic-Sql \
- --image UbuntuLTS \
- --admin-username azureadmin \
- --generate-ssh-keys
+echo "Creating $nicSql for $vmSql"
+az network nic create --resource-group $resourceGroup --name $nicSql --vnet-name $vNet --subnet $subnetBackEnd --network-security-group $nsgBackEnd --public-ip-address $publicIpSql
+
+# Create a MySQL VM in the backend subnet.
+echo "Creating $vmSql in $subnetBackEnd"
+az vm create --resource-group $resourceGroup --name $vmSql --nics $nicSql --image $image --admin-username $login --generate-ssh-keys --public-ip-sku $sku
+#
+
+# echo "Deleting all resources"
+# az group delete --name $resourceGroup -y
diff --git a/virtual-network/vm-with-two-nics/vm-with-two-nics.sh b/virtual-network/vm-with-two-nics/vm-with-two-nics.sh
deleted file mode 100644
index 076c98c9..00000000
--- a/virtual-network/vm-with-two-nics/vm-with-two-nics.sh
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/bin/bash
-
-RgName="MyResourceGroup"
-Location="eastus"
-
-# Create a resource group.
-az group create --name $RgName --location $Location
-
-# Create a virtual network and a front-end subnet.
-az network vnet create \
- --resource-group $RgName \
- --name MyVnet \
- --address-prefix 10.0.0.0/16 \
- --location $Location \
- --subnet-name MySubnet-FrontEnd \
- --subnet-prefix 10.0.1.0/24
-
-# Create a back-end subnet.
-az network vnet subnet create \
- --address-prefix 10.0.2.0/24 \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --vnet-name MyVnet
-
-# Create a network security group for the front-end subnet.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-FrontEnd \
- --location $Location
-
-# Create NSG rules to allow HTTP & HTTPS traffic inbound.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTP-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 80
-
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-HTTPS-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 200 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 443
-
-# Create an NSG rule to allow SSH traffic in from the Internet to the front-end subnet.
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-FrontEnd \
- --name Allow-SSH-All \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 300 \
- --source-address-prefix Internet \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range 22
-
-# Associate the front-end NSG to the front-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-FrontEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-FrontEnd
-
-# Create a network security group for the back-end subnet.
-az network nsg create \
- --resource-group $RgName \
- --name MyNsg-BackEnd \
- --location $Location
-
-# Create an NSG rule to block all outbound traffic from the back-end subnet to the Internet (inbound blocked by default).
-az network nsg rule create \
- --resource-group $RgName \
- --nsg-name MyNsg-BackEnd \
- --name Deny-Internet-All \
- --access Deny --protocol Tcp \
- --direction Outbound --priority 100 \
- --source-address-prefix "*" \
- --source-port-range "*" \
- --destination-address-prefix "*" \
- --destination-port-range "*"
-
-# Associate the back-end NSG to the back-end subnet.
-az network vnet subnet update \
- --vnet-name MyVnet \
- --name MySubnet-BackEnd \
- --resource-group $RgName \
- --network-security-group MyNsg-BackEnd
-
-# Create a public IP addresses for the VM front-end network interface.
-az network public-ip create \
- --resource-group $RgName \
- --name MyPublicIp-FrontEnd \
- --allocation-method Dynamic
-
-# Create a network interface for the VM attached to the front-end subnet.
-az network nic create \
- --resource-group $RgName \
- --vnet-name MyVnet \
- --subnet MySubnet-FrontEnd \
- --name MyNic-FrontEnd \
- --public-ip-address MyPublicIp-FrontEnd
-
-# Create a network interface for the VM attached to the back-end subnet.
-az network nic create \
- --resource-group $RgName \
- --vnet-name MyVnet \
- --subnet MySubnet-BackEnd \
- --name MyNic-BackEnd
-
-# Create the VM with both the FrontEnd and BackEnd NICs.
-az vm create \
- --resource-group $RgName \
- --name MyVm \
- --nics MyNic-FrontEnd MyNic-BackEnd \
- --image UbuntuLTS \
- --admin-username azureadmin \
- --generate-ssh-keys
-