diff --git a/scenarios/ocd/CreateAKSDeployment/README.md b/scenarios/ocd/CreateAKSDeployment/README.md
deleted file mode 100644
index abb781b9..00000000
--- a/scenarios/ocd/CreateAKSDeployment/README.md
+++ /dev/null
@@ -1,390 +0,0 @@
-# Quickstart: Deploy a Scalable & Secure Azure Kubernetes Service cluster using the Azure CLI
-
-Welcome to this tutorial where we will take you step by step in creating an Azure Kubernetes Web Application that is secured via https. This tutorial assumes you are logged into Azure CLI already and have selected a subscription to use with the CLI. It also assumes that you have Helm installed ([Instructions can be found here](https://helm.sh/docs/intro/install/)).
-
-## Define Environment Variables
-
-The first step in this tutorial is to define environment variables.
-
-```bash
-export RANDOM_ID="$(openssl rand -hex 3)"
-export NETWORK_PREFIX="$(($RANDOM % 254 + 1))"
-export SSL_EMAIL_ADDRESS="$(az account show --query user.name --output tsv)"
-export MY_RESOURCE_GROUP_NAME="myAKSResourceGroup$RANDOM_ID"
-export REGION="eastus"
-export MY_AKS_CLUSTER_NAME="myAKSCluster$RANDOM_ID"
-export MY_PUBLIC_IP_NAME="myPublicIP$RANDOM_ID"
-export MY_DNS_LABEL="mydnslabel$RANDOM_ID"
-export MY_VNET_NAME="myVNet$RANDOM_ID"
-export MY_VNET_PREFIX="10.$NETWORK_PREFIX.0.0/16"
-export MY_SN_NAME="mySN$RANDOM_ID"
-export MY_SN_PREFIX="10.$NETWORK_PREFIX.0.0/22"
-export FQDN="${MY_DNS_LABEL}.${REGION}.cloudapp.azure.com"
-```
-
-## Create a resource group
-
-A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $MY_RESOURCE_GROUP_NAME and $REGION parameters.
-
-```bash
-az group create --name $MY_RESOURCE_GROUP_NAME --location $REGION
-```
-
-Results:
-
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myAKSResourceGroupxxxxxx",
- "location": "eastus",
- "managedBy": null,
- "name": "testResourceGroup",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Create a virtual network and subnet
-
-A virtual network is the fundamental building block for private networks in Azure. Azure Virtual Network enables Azure resources like VMs to securely communicate with each other and the internet.
-
-```bash
-az network vnet create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION \
- --name $MY_VNET_NAME \
- --address-prefix $MY_VNET_PREFIX \
- --subnet-name $MY_SN_NAME \
- --subnet-prefixes $MY_SN_PREFIX
-```
-
-Results:
-
-
-
-```JSON
-{
- "newVNet": {
- "addressSpace": {
- "addressPrefixes": [
- "10.xxx.0.0/16"
- ]
- },
- "enableDdosProtection": false,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/myAKSResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxx",
- "location": "eastus",
- "name": "myVNetxxx",
- "provisioningState": "Succeeded",
- "resourceGroup": "myAKSResourceGroupxxxxxx",
- "subnets": [
- {
- "addressPrefix": "10.xxx.0.0/22",
- "delegations": [],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/myAKSResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxx/subnets/mySNxxx",
- "name": "mySNxxx",
- "privateEndpointNetworkPolicies": "Disabled",
- "privateLinkServiceNetworkPolicies": "Enabled",
- "provisioningState": "Succeeded",
- "resourceGroup": "myAKSResourceGroupxxxxxx",
- "type": "Microsoft.Network/virtualNetworks/subnets"
- }
- ],
- "type": "Microsoft.Network/virtualNetworks",
- "virtualNetworkPeerings": []
- }
-}
-```
-
-## Register to AKS Azure Resource Providers
-
-Verify Microsoft.OperationsManagement and Microsoft.OperationalInsights providers are registered on your subscription. These are Azure resource providers required to support [Container insights](https://docs.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-overview). To check the registration status, run the following commands
-
-```bash
-az provider register --namespace Microsoft.Insights
-az provider register --namespace Microsoft.OperationsManagement
-az provider register --namespace Microsoft.OperationalInsights
-```
-
-## Create AKS Cluster
-
-Create an AKS cluster using the az aks create command with the --enable-addons monitoring parameter to enable Container insights. The following example creates an autoscaling, availability zone enabled cluster.
-
-This will take a few minutes.
-
-```bash
-export MY_SN_ID=$(az network vnet subnet list --resource-group $MY_RESOURCE_GROUP_NAME --vnet-name $MY_VNET_NAME --query "[0].id" --output tsv)
-az aks create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_AKS_CLUSTER_NAME \
- --auto-upgrade-channel stable \
- --enable-cluster-autoscaler \
- --enable-addons monitoring \
- --location $REGION \
- --node-count 1 \
- --min-count 1 \
- --max-count 3 \
- --network-plugin azure \
- --network-policy azure \
- --vnet-subnet-id $MY_SN_ID \
- --no-ssh-key \
- --node-vm-size Standard_DS2_v2 \
- --zones 1 2 3
-```
-
-## Connect to the cluster
-
-To manage a Kubernetes cluster, use the Kubernetes command-line client, kubectl. kubectl is already installed if you use Azure Cloud Shell.
-
-1. Install az aks CLI locally using the az aks install-cli command
-
- ```bash
- if ! [ -x "$(command -v kubectl)" ]; then az aks install-cli; fi
- ```
-
-2. Configure kubectl to connect to your Kubernetes cluster using the az aks get-credentials command. The following command:
-
- - Downloads credentials and configures the Kubernetes CLI to use them.
- - Uses ~/.kube/config, the default location for the Kubernetes configuration file. Specify a different location for your Kubernetes configuration file using --file argument.
-
- > [!WARNING]
- > This will overwrite any existing credentials with the same entry
-
- ```bash
- az aks get-credentials --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_AKS_CLUSTER_NAME --overwrite-existing
- ```
-
-3. Verify the connection to your cluster using the kubectl get command. This command returns a list of the cluster nodes.
-
- ```bash
- kubectl get nodes
- ```
-
-## Install NGINX Ingress Controller
-
-```bash
-export MY_STATIC_IP=$(az network public-ip create --resource-group MC_${MY_RESOURCE_GROUP_NAME}_${MY_AKS_CLUSTER_NAME}_${REGION} --location ${REGION} --name ${MY_PUBLIC_IP_NAME} --dns-name ${MY_DNS_LABEL} --sku Standard --allocation-method static --version IPv4 --zone 1 2 3 --query publicIp.ipAddress -o tsv)
-helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
-helm repo update
-helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
- --namespace ingress-nginx \
- --create-namespace \
- --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$MY_DNS_LABEL \
- --set controller.service.loadBalancerIP=$MY_STATIC_IP \
- --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
- --wait
-```
-
-## Deploy the Application
-
-A Kubernetes manifest file defines a cluster's desired state, such as which container images to run.
-
-In this quickstart, you will use a manifest to create all objects needed to run the Azure Vote application. This manifest includes two Kubernetes deployments:
-
-- The sample Azure Vote Python applications.
-- A Redis instance.
-
-Two Kubernetes Services are also created:
-
-- An internal service for the Redis instance.
-- An external service to access the Azure Vote application from the internet.
-
-Finally, an Ingress resource is created to route traffic to the Azure Vote application.
-
-A test voting app YML file is already prepared. To deploy this app run the following command
-
-```bash
-kubectl apply -f azure-vote-start.yml
-```
-
-## Test The Application
-
-Validate that the application is running by either visiting the public ip or the application url. The application url can be found by running the following command:
-
-> [!Note]
-> It often takes 2-3 minutes for the PODs to be created and the site to be reachable via HTTP
-
-```bash
-runtime="5 minute";
-endtime=$(date -ud "$runtime" +%s);
-while [[ $(date -u +%s) -le $endtime ]]; do
- STATUS=$(kubectl get pods -l app=azure-vote-front -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}'); echo $STATUS;
- if [ "$STATUS" == 'True' ]; then
- break;
- else
- sleep 10;
- fi;
-done
-```
-
-```bash
-curl "http://$FQDN"
-```
-
-Results:
-
-
-
-```HTML
-
-
-
-
- Azure Voting App
-
-
-
-
-
-
-
-
-
-```
-
-## Add HTTPS termination to custom domain
-
-At this point in the tutorial you have an AKS web app with NGINX as the Ingress controller and a custom domain you can use to access your application. The next step is to add an SSL certificate to the domain so that users can reach your application securely via HTTPS.
-
-## Set Up Cert Manager
-
-In order to add HTTPS we are going to use Cert Manager. Cert Manager is an open source tool used to obtain and manage SSL certificate for Kubernetes deployments. Cert Manager will obtain certificates from a variety of Issuers, both popular public Issuers as well as private Issuers, and ensure the certificates are valid and up-to-date, and will attempt to renew certificates at a configured time before expiry.
-
-1. In order to install cert-manager, we must first create a namespace to run it in. This tutorial will install cert-manager into the cert-manager namespace. It is possible to run cert-manager in a different namespace, although you will need to make modifications to the deployment manifests.
-
- ```bash
- kubectl create namespace cert-manager
- ```
-
-2. We can now install cert-manager. All resources are included in a single YAML manifest file. This can be installed by running the following:
-
- ```bash
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.0/cert-manager.crds.yaml
- ```
-
-3. Add the certmanager.k8s.io/disable-validation: "true" label to the cert-manager namespace by running the following. This will allow the system resources that cert-manager requires to bootstrap TLS to be created in its own namespace.
-
- ```bash
- kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
- ```
-
-## Obtain certificate via Helm Charts
-
-Helm is a Kubernetes deployment tool for automating creation, packaging, configuration, and deployment of applications and services to Kubernetes clusters.
-
-Cert-manager provides Helm charts as a first-class method of installation on Kubernetes.
-
-1. Add the Jetstack Helm repository
-
- This repository is the only supported source of cert-manager charts. There are some other mirrors and copies across the internet, but those are entirely unofficial and could present a security risk.
-
- ```bash
- helm repo add jetstack https://charts.jetstack.io
- ```
-
-2. Update local Helm Chart repository cache
-
- ```bash
- helm repo update
- ```
-
-3. Install Cert-Manager addon via helm by running the following:
-
- ```bash
- helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.7.0
- ```
-
-4. Apply Certificate Issuer YAML File
-
- ClusterIssuers are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request.
- The issuer we are using can be found in the `cluster-issuer-prod.yml file`
-
- ```bash
- cluster_issuer_variables=$(
-
-
-## Browse your AKS Deployment Secured via HTTPS
-
-Run the following command to get the HTTPS endpoint for your application:
-
-> [!Note]
-> It often takes 2-3 minutes for the SSL certificate to propogate and the site to be reachable via HTTPS.
-
-```bash
-runtime="5 minute";
-endtime=$(date -ud "$runtime" +%s);
-while [[ $(date -u +%s) -le $endtime ]]; do
- STATUS=$(kubectl get svc --namespace=ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}');
- echo $STATUS;
- if [ "$STATUS" == "$MY_STATIC_IP" ]; then
- break;
- else
- sleep 10;
- fi;
-done
-```
-
-```bash
-echo "You can now visit your web server at https://$FQDN"
-```
-
-## Next Steps
-
-- [Azure Kubernetes Service Documentation](https://learn.microsoft.com/en-us/azure/aks/)
-- [Create an Azure Container Registry](https://learn.microsoft.com/en-us/azure/aks/tutorial-kubernetes-prepare-acr?tabs=azure-cli)
-- [Scale your Applciation in AKS](https://learn.microsoft.com/en-us/azure/aks/tutorial-kubernetes-scale?tabs=azure-cli)
-- [Update your application in AKS](https://learn.microsoft.com/en-us/azure/aks/tutorial-kubernetes-app-update?tabs=azure-cli)
diff --git a/scenarios/ocd/CreateAKSDeployment/azure-vote-nginx-ssl.yml b/scenarios/ocd/CreateAKSDeployment/azure-vote-nginx-ssl.yml
deleted file mode 100644
index 070e2014..00000000
--- a/scenarios/ocd/CreateAKSDeployment/azure-vote-nginx-ssl.yml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-# INGRESS WITH SSL PROD
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: vote-ingress
- namespace: default
- annotations:
- kubernetes.io/tls-acme: "true"
- nginx.ingress.kubernetes.io/ssl-redirect: "true"
- cert-manager.io/cluster-issuer: letsencrypt-prod
-spec:
- ingressClassName: nginx
- tls:
- - hosts:
- - $FQDN
- secretName: azure-vote-nginx-secret
- rules:
- - host: $FQDN
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: azure-vote-front
- port:
- number: 80
diff --git a/scenarios/ocd/CreateAKSDeployment/azure-vote-start.yml b/scenarios/ocd/CreateAKSDeployment/azure-vote-start.yml
deleted file mode 100644
index 492a394e..00000000
--- a/scenarios/ocd/CreateAKSDeployment/azure-vote-start.yml
+++ /dev/null
@@ -1,106 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: azure-vote-back
- namespace: default
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: azure-vote-back
- template:
- metadata:
- labels:
- app: azure-vote-back
- spec:
- nodeSelector:
- "kubernetes.io/os": linux
- containers:
- - name: azure-vote-back
- image: docker.io/bitnami/redis:6.0.8
- env:
- - name: ALLOW_EMPTY_PASSWORD
- value: "yes"
- resources:
- requests:
- cpu: 100m
- memory: 128Mi
- limits:
- cpu: 250m
- memory: 256Mi
- ports:
- - containerPort: 6379
- name: redis
----
-apiVersion: v1
-kind: Service
-metadata:
- name: azure-vote-back
- namespace: default
-spec:
- ports:
- - port: 6379
- selector:
- app: azure-vote-back
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: azure-vote-front
- namespace: default
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: azure-vote-front
- template:
- metadata:
- labels:
- app: azure-vote-front
- spec:
- nodeSelector:
- "kubernetes.io/os": linux
- containers:
- - name: azure-vote-front
- image: mcr.microsoft.com/azuredocs/azure-vote-front:v1
- resources:
- requests:
- cpu: 100m
- memory: 128Mi
- limits:
- cpu: 250m
- memory: 256Mi
- ports:
- - containerPort: 80
- env:
- - name: REDIS
- value: "azure-vote-back"
----
-apiVersion: v1
-kind: Service
-metadata:
- name: azure-vote-front
- namespace: default
-spec:
- ports:
- - port: 80
- selector:
- app: azure-vote-front
----
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: vote-ingress
- namespace: default
-spec:
- ingressClassName: nginx
- rules:
- - http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: azure-vote-front
- port:
- number: 80
\ No newline at end of file
diff --git a/scenarios/ocd/CreateAKSDeployment/cluster-issuer-prod.yml b/scenarios/ocd/CreateAKSDeployment/cluster-issuer-prod.yml
deleted file mode 100644
index e4a37bab..00000000
--- a/scenarios/ocd/CreateAKSDeployment/cluster-issuer-prod.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#kubectl apply -f - <, which is also referenced in step 1 of the video walkthrough. The updated sample is at: .
-
-## Next Steps
-
-* [Azure Container Apps Documentation](https://learn.microsoft.com/en-us/azure/container-apps/)
-* [Scaling an Azure Container App](https://learn.microsoft.com/en-us/azure/container-apps/scale-app?pivots=azure-cli)
-* [Manage Secrets in Container Apps](https://learn.microsoft.com/en-us/azure/container-apps/manage-secrets?tabs=azure-cli)
-* [Health Probes in Azure Container Apps](https://learn.microsoft.com/en-us/azure/container-apps/health-probes?tabs=arm-cli)
\ No newline at end of file
diff --git a/scenarios/ocd/CreateContainerAppDeploymentFromSource/README.md b/scenarios/ocd/CreateContainerAppDeploymentFromSource/README.md
deleted file mode 100644
index 7c524515..00000000
--- a/scenarios/ocd/CreateContainerAppDeploymentFromSource/README.md
+++ /dev/null
@@ -1,635 +0,0 @@
-# Create a Container App leveraging Blob Store, SQL, and Computer Vision
-
-In this guide, we'll be walking through deploying the necessary resources for a web app that allows users to cast votes using their name, email and an image. Users can vote for their preference of cat or dog, using an image of a cat or a dog that will be analyzed by our infrastructure. For this to work, we will be deploying resources across several different Azure services:
-
-- **Azure Storage Account** to store the images
-- **Azure Database for PostgreSQL** to store users and votes
-- **Azure Computer Vision** to analyze the images for cats or dogs
-- **Azure Container App** to deploy our code
-
-Note: If you've never created a Computer Vision resource before, you will not be able to create one using the Azure CLI. You must create your first Computer Vision resource from the Azure portal to review and acknowledge the Responsible AI terms and conditions. You can do so here: [Create a Computer Vision Resource](https://portal.azure.com/#create/Microsoft.CognitiveServicesComputerVision). After that, you can create subsequent resources using any deployment tool (SDK, CLI, or ARM template, etc) under the same Azure subscription.
-
-## Define Environment Variables
-
-The first step in this tutorial is to define environment variables. **Replace the values on the right with your own unique values.** These values will be used throughout the tutorial to create resources and configure the application. Use lowercase and no special characters for the storage account name.
-
-```bash
-export SUFFIX=$(cat /dev/urandom | LC_ALL=C tr -dc 'a-z0-9' | fold -w 8 | head -n 1)
-export MY_RESOURCE_GROUP_NAME=rg$SUFFIX
-export REGION=westus
-export MY_STORAGE_ACCOUNT_NAME=storage$SUFFIX
-export MY_DATABASE_SERVER_NAME=dbserver$SUFFIX
-export MY_DATABASE_NAME=db$SUFFIX
-export MY_DATABASE_USERNAME=dbuser$SUFFIX
-export MY_DATABASE_PASSWORD=dbpass$SUFFIX
-export MY_COMPUTER_VISION_NAME=computervision$SUFFIX
-export MY_CONTAINER_APP_NAME=containerapp$SUFFIX
-export MY_CONTAINER_APP_ENV_NAME=containerappenv$SUFFIX
-```
-
-## Clone the sample repository
-
-First, we're going to clone this repository onto our local machines. This will provide the starter code required to provide the functionality for the simple application outlined above. We can clone with a simple git command.
-
-```bash
-git clone https://github.com/Azure/computer-vision-nextjs-webapp.git
-```
-
-To preserve saved environment variables, it's important that this terminal window stays open for the duration of the deployment.
-
-## Login to Azure using the CLI
-
-In order to run commands against Azure using [the CLI ](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)you need to login. This is done though the `az login` command:
-
-## Create a resource group
-
-A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $MY_RESOURCE_GROUP_NAME and $REGION parameters.
-
-```bash
-az group create --name $MY_RESOURCE_GROUP_NAME --location $REGION
-```
-
-Results:
-
-
-```json
-{
- "id": "/subscriptions/ab9d8365-2f65-47a4-8df4-7e40db70c8d2/resourceGroups/$MY_RESOURCE_GROUP_NAME",
- "location": "$REGION",
- "managedBy": null,
- "name": "$MY_RESOURCE_GROUP_NAME",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Create the storage account
-
-To create a storage account in this resource group we need to run a simple command. To this command, we are passing the name of the storage account, the resource group to deploy it in, the physical region to deploy it in, and the SKU of the storage account. All values are configured using environment variables.
-
-```bash
-az storage account create --name $MY_STORAGE_ACCOUNT_NAME --resource-group $MY_RESOURCE_GROUP_NAME --location $REGION --sku Standard_LRS
-```
-
-Results:
-
-
-```json
-{
- "accessTier": "Hot",
- "allowBlobPublicAccess": false,
- "allowCrossTenantReplication": null,
- "allowSharedKeyAccess": null,
- "allowedCopyScope": null,
- "azureFilesIdentityBasedAuthentication": null,
- "blobRestoreStatus": null,
- "creationTime": "2023-08-10T14:37:41.276351+00:00",
- "customDomain": null,
- "defaultToOAuthAuthentication": null,
- "dnsEndpointType": null,
- "enableHttpsTrafficOnly": true,
- "enableNfsV3": null,
- "encryption": {
- "encryptionIdentity": null,
- "keySource": "Microsoft.Storage",
- "keyVaultProperties": null,
- "requireInfrastructureEncryption": null,
- "services": {
- "blob": {
- "enabled": true,
- "keyType": "Account",
- "lastEnabledTime": "2023-08-10T14:37:41.370163+00:00"
- },
- "file": {
- "enabled": true,
- "keyType": "Account",
- "lastEnabledTime": "2023-08-10T14:37:41.370163+00:00"
- },
- "queue": null,
- "table": null
- }
- },
- "extendedLocation": null,
- "failoverInProgress": null,
- "geoReplicationStats": null,
- "id": "/subscriptions/ab9d8365-2f65-47a4-8df4-7e40db70c8d2/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/$MY_STORAGE_ACCOUNT_NAME",
- "identity": null,
- "immutableStorageWithVersioning": null,
- "isHnsEnabled": null,
- "isLocalUserEnabled": null,
- "isSftpEnabled": null,
- "keyCreationTime": {
- "key1": "2023-08-10T14:37:41.370163+00:00",
- "key2": "2023-08-10T14:37:41.370163+00:00"
- },
- "keyPolicy": null,
- "kind": "StorageV2",
- "largeFileSharesState": null,
- "lastGeoFailoverTime": null,
- "location": "$REGION",
- "minimumTlsVersion": "TLS1_0",
- "name": "$MY_STORAGE_ACCOUNT_NAME",
- "networkRuleSet": {
- "bypass": "AzureServices",
- "defaultAction": "Allow",
- "ipRules": [],
- "resourceAccessRules": null,
- "virtualNetworkRules": []
- },
- "primaryEndpoints": {
- "blob": "https://$MY_STORAGE_ACCOUNT_NAME.blob.core.windows.net/",
- "dfs": "https://$MY_STORAGE_ACCOUNT_NAME.dfs.core.windows.net/",
- "file": "https://$MY_STORAGE_ACCOUNT_NAME.file.core.windows.net/",
- "internetEndpoints": null,
- "microsoftEndpoints": null,
- "queue": "https://$MY_STORAGE_ACCOUNT_NAME.queue.core.windows.net/",
- "table": "https://$MY_STORAGE_ACCOUNT_NAME.table.core.windows.net/",
- "web": "https://$MY_STORAGE_ACCOUNT_NAME.z22.web.core.windows.net/"
- },
- "primaryLocation": "$REGION",
- "privateEndpointConnections": [],
- "provisioningState": "Succeeded",
- "publicNetworkAccess": null,
- "resourceGroup": "$MY_RESOURCE_GROUP_NAME",
- "routingPreference": null,
- "sasPolicy": null,
- "secondaryEndpoints": null,
- "secondaryLocation": null,
- "sku": {
- "name": "Standard_LRS",
- "tier": "Standard"
- },
- "statusOfPrimary": "available",
- "statusOfSecondary": null,
- "storageAccountSkuConversionStatus": null,
- "tags": {},
- "type": "Microsoft.Storage/storageAccounts"
-}
-```
-
-We also need to store one of the API keys for the storage account into an environment variable for later use (to create a container, and put it into an environment file for the code). We are calling the `keys list` command on the storage account and storing the first one in a `STORAGE_ACCOUNT_KEY` environment variable.
-
-```bash
-export STORAGE_ACCOUNT_KEY=$(az storage account keys list --account-name $MY_STORAGE_ACCOUNT_NAME --resource-group $MY_RESOURCE_GROUP_NAME --query "[0].value" --output tsv)
-```
-
-## Create a container in the storage account
-
-Run the following command to create an `images` container in the storage account we just created. User uploaded images will be stored as blobs in this container.
-
-```bash
-az storage container create --name images --account-name $MY_STORAGE_ACCOUNT_NAME --account-key $STORAGE_ACCOUNT_KEY --public-access blob
-```
-
-Results:
-
-
-```json
-{
- "created": true
-}
-```
-
-## Create a database
-
-We will be creating an Azure Database for PostgreSQL flexible server for the application to store users and their votes. We are passing several arguments to the `create` command:
-
-- The basics: database name, resource group, and physical region to deploy in.
-- The tier (which determines the capabilities of the server) as `burstable`, which is for workloads that don't need full CPU continuously.
-- The SKU as `Standard_B1ms`.
- - `Standard` for the performance tier.
- - `B` for burstable workload.
- - `1` for a single vCore.
- - `ms` for memory optimized.
-- The storage size, 32 GiB
-- The PostgreSQL major version, 15
-- The datatabase credentials: username and password
-
-```bash
-az postgres flexible-server create \
- --name $MY_DATABASE_SERVER_NAME \
- --database-name $MY_DATABASE_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION \
- --tier Burstable \
- --sku-name Standard_B1ms \
- --storage-size 32 \
- --version 15 \
- --admin-user $MY_DATABASE_USERNAME \
- --admin-password $MY_DATABASE_PASSWORD \
- --yes
-```
-
-Results:
-
-
-```json
-{
- "connectionString": "postgresql://$MY_DATABASE_USERNAME:$MY_DATABASE_PASSWORD@$MY_DATABASE_NAME.postgres.database.azure.com/flexibleserverdb?sslmode=require",
- "databaseName": "$MY_DATABASE_NAME",
- "firewallName": "FirewallIPAddress_2023-8-10_10-53-21",
- "host": "$MY_DATABASE_NAME.postgres.database.azure.com",
- "id": "/subscriptions/ab9d8365-2f65-47a4-8df4-7e40db70c8d2/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.DBforPostgreSQL/flexibleServers/$MY_DATABASE_NAME",
- "location": "$REGION",
- "password": "$MY_DATABASE_PASSWORD",
- "resourceGroup": "$MY_RESOURCE_GROUP_NAME",
- "skuname": "Standard_B1ms",
- "username": "$MY_DATABASE_USERNAME",
- "version": "15"
-}
-```
-
-We also need to store the connection string to the database into an environment variable for later use. This URL will allow us to access the database within the resource we just created.
-
-```bash
-export DATABASE_URL="postgres://$MY_DATABASE_USERNAME:$MY_DATABASE_PASSWORD@$MY_DATABASE_SERVER_NAME.postgres.database.azure.com/$MY_DATABASE_NAME"
-```
-
-## Create a Computer Vision resource
-
-We will be creating a Computer Vision resource to be able to identify cats or dogs in the pictures users upload. Creating a Computer Vision resource can be done with a single command. We are passing several arguments to the `create` command:
-
-- The basics: resource name, resource group, the region, and to create a Computer Vision resource.
-- The SKU as `S1`, or the most cost-effective paid performance tier.
-
-```bash
-az cognitiveservices account create \
- --name $MY_COMPUTER_VISION_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION \
- --kind ComputerVision \
- --sku S1 \
- --yes
-```
-
-Results:
-
-
-```json
-{
- "etag": "\"090ac83c-0000-0700-0000-64d4fcd80000\"",
- "id": "/subscriptions/ab9d8365-2f65-47a4-8df4-7e40db70c8d2/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.CognitiveServices/accounts/$MY_COMPUTER_VISION_NAME",
- "identity": null,
- "kind": "ComputerVision",
- "location": "$REGION",
- "name": "$MY_COMPUTER_VISION_NAME",
- "properties": {
- "allowedFqdnList": null,
- "apiProperties": null,
- "callRateLimit": {
- "count": null,
- "renewalPeriod": null,
- "rules": [
- {
- "count": 30.0,
- "dynamicThrottlingEnabled": true,
- "key": "vision.recognizeText",
- "matchPatterns": [
- {
- "method": "POST",
- "path": "vision/recognizeText"
- },
- {
- "method": "GET",
- "path": "vision/textOperations/*"
- },
- {
- "method": "*",
- "path": "vision/read/*"
- }
- ],
- "minCount": null,
- "renewalPeriod": 1.0
- },
- {
- "count": 15.0,
- "dynamicThrottlingEnabled": true,
- "key": "vision",
- "matchPatterns": [
- {
- "method": "*",
- "path": "vision/*"
- }
- ],
- "minCount": null,
- "renewalPeriod": 1.0
- },
- {
- "count": 500.0,
- "dynamicThrottlingEnabled": null,
- "key": "container.billing",
- "matchPatterns": [
- {
- "method": "*",
- "path": "billing/*"
- }
- ],
- "minCount": null,
- "renewalPeriod": 10.0
- },
- {
- "count": 20.0,
- "dynamicThrottlingEnabled": true,
- "key": "default",
- "matchPatterns": [
- {
- "method": "*",
- "path": "*"
- }
- ],
- "minCount": null,
- "renewalPeriod": 1.0
- }
- ]
- },
- "capabilities": [
- {
- "name": "DynamicThrottling",
- "value": null
- },
- {
- "name": "VirtualNetworks",
- "value": null
- },
- {
- "name": "Container",
- "value": "ComputerVision.VideoAnalytics,ComputerVision.ComputerVisionRead,ComputerVision.ocr,ComputerVision.readfile,ComputerVision.readfiledsd,ComputerVision.recognizetext,ComputerVision.ComputerVision,ComputerVision.ocrlayoutworker,ComputerVision.ocrcontroller,ComputerVision.ocrdispatcher,ComputerVision.ocrbillingprocessor,ComputerVision.ocranalyzer,ComputerVision.ocrpagesplitter,ComputerVision.ocrapi,ComputerVision.ocrengineworker"
- }
- ],
- "customSubDomainName": null,
- "dateCreated": "2023-08-10T15:06:00.4272845Z",
- "deletionDate": null,
- "disableLocalAuth": null,
- "dynamicThrottlingEnabled": null,
- "encryption": null,
- "endpoint": "https://$REGION.api.cognitive.microsoft.com/",
- "endpoints": {
- "Computer Vision": "https://$REGION.api.cognitive.microsoft.com/",
- "Container": "https://$REGION.api.cognitive.microsoft.com/"
- },
- "internalId": "93645816f9594fe49a8f4023c0bf34b4",
- "isMigrated": false,
- "migrationToken": null,
- "networkAcls": null,
- "privateEndpointConnections": [],
- "provisioningState": "Succeeded",
- "publicNetworkAccess": "Enabled",
- "quotaLimit": null,
- "restore": null,
- "restrictOutboundNetworkAccess": null,
- "scheduledPurgeDate": null,
- "skuChangeInfo": null,
- "userOwnedStorage": null
- },
- "resourceGroup": "$MY_RESOURCE_GROUP_NAME",
- "sku": {
- "capacity": null,
- "family": null,
- "name": "S1",
- "size": null,
- "tier": null
- },
- "systemData": {
- "createdAt": "2023-08-10T15:06:00.107300+00:00",
- "createdBy": "username@domain.com",
- "createdByType": "User",
- "lastModifiedAt": "2023-08-10T15:06:00.107300+00:00",
- "lastModifiedBy": "username@domain.com",
- "lastModifiedByType": "User"
- },
- "tags": null,
- "type": "Microsoft.CognitiveServices/accounts"
-}
-```
-
-To access our computer vision resource, we need both the endpoint and the key. With the Azure CLI, we have access to two `az cognitiveservices account` commands: `show` and `keys list`, which give us what we need.
-
-```bash
-export COMPUTER_VISION_ENDPOINT=$(az cognitiveservices account show --name $MY_COMPUTER_VISION_NAME --resource-group $MY_RESOURCE_GROUP_NAME --query "properties.endpoint" --output tsv)
-export COMPUTER_VISION_KEY=$(az cognitiveservices account keys list --name $MY_COMPUTER_VISION_NAME --resource-group $MY_RESOURCE_GROUP_NAME --query "key1" --output tsv)
-```
-
-## Deploy the code into a Container App
-
-Now that we've got our storage, database, and Computer Vision resources all set up, we are ready to deploy the application code. To do this, we're going to use Azure Container Apps to host a containerized build of our Next.js app. The `Dockerfile` is already created at the root of the repository, so all we need to do is run a single command to deploy the code. Before running this command, we first need to install the containerapp extension for the Azure CLI.
-
-```bash
-az extension add --upgrade -n containerapp
-```
-
-This command will create an Azure Container Registry resource to host our Docker image, an Azure Container App resource which runs the image, and an Azure Container App Environment resource for our image. Let's break down what we're passing into the command.
-
-- The basics: resource name, resource group, and the region
-- The name of the Azure Container App Environment resource to use or create
-- The path to the source code
-
-```bash
-az containerapp up \
- --name $MY_CONTAINER_APP_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION \
- --environment $MY_CONTAINER_APP_ENV_NAME \
- --context-path computer-vision-nextjs-webapp \
- --source computer-vision-nextjs-webapp \
- --target-port 3000 \
- --ingress external \
- --env-vars \
- AZURE_DATABASE_URL=$DATABASE_URL \
- AZURE_COMPUTER_VISION_KEY=$COMPUTER_VISION_KEY \
- AZURE_COMPUTER_VISION_ENDPOINT=$COMPUTER_VISION_ENDPOINT \
- AZURE_STORAGE_ACCOUNT_NAME=$MY_STORAGE_ACCOUNT_NAME \
- AZURE_STORAGE_ACCOUNT_KEY=$STORAGE_ACCOUNT_KEY
-```
-
-We can verify that the command was successful by using:
-
-```bash
-az containerapp show --name $MY_CONTAINER_APP_NAME --resource-group $MY_RESOURCE_GROUP_NAME
-```
-
-Results:
-
-
-```json
-{
- "id": "/subscriptions/fake3265-2f64-47a4-8df4-7e41ab70c8dh/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.App/containerapps/$MY_CONTAINER_APP_NAME",
- "identity": {
- "type": "None"
- },
- "location": "West US",
- "name": "$MY_CONTAINER_APP_NAME",
- "properties": {
- "configuration": {
- "activeRevisionsMode": "Single",
- "dapr": null,
- "ingress": {
- "allowInsecure": false,
- "clientCertificateMode": null,
- "corsPolicy": null,
- "customDomains": null,
- "exposedPort": 0,
- "external": true,
- "fqdn": "$MY_CONTAINER_APP_NAME.kindocean-a506af76.$REGION.azurecontainerapps.io",
- "ipSecurityRestrictions": null,
- "stickySessions": null,
- "targetPort": 3000,
- "traffic": [
- {
- "latestRevision": true,
- "weight": 100
- }
- ],
- "transport": "Auto"
- },
- "maxInactiveRevisions": null,
- "registries": null,
- "secrets": null,
- "service": null
- },
- "customDomainVerificationId": "06C64CD176439F8B6CCBBE1B531758828A5CACEABFB30B4DC9750641532924F6",
- "environmentId": "/subscriptions/fake3265-2f64-47a4-8df4-7e41ab70c8dh/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.App/managedEnvironments/$MY_CONTAINER_APP_ENV_NAME",
- "eventStreamEndpoint": "https://$REGION.azurecontainerapps.dev/subscriptions/eb9d8265-2f64-47a4-8df4-7e41db70c8d8/resourceGroups/$MY_RESOURCE_GROUP_NAME/containerApps/$MY_CONTAINER_APP_NAME/eventstream",
- "latestReadyRevisionName": "$MY_CONTAINER_APP_NAME--jl6fh75",
- "latestRevisionFqdn": "$MY_CONTAINER_APP_NAME--jl6fh75.kindocean-a506af76.$REGION.azurecontainerapps.io",
- "latestRevisionName": "$MY_CONTAINER_APP_NAME--jl6fh75",
- "managedEnvironmentId": "/subscriptions/eb9d8265-2f64-47a4-8df4-7e41db70c8d8/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.App/managedEnvironments/$MY_CONTAINER_APP_ENV_NAME",
- "outboundIpAddresses": ["20.237.221.47"],
- "provisioningState": "Succeeded",
- "runningStatus": "Running",
- "template": {
- "containers": [
- {
- "env": [
- {
- "name": "AZURE_DATABASE_URL",
- "value": "$DATABASE_URL"
- },
- {
- "name": "AZURE_COMPUTER_VISION_KEY",
- "value": "$COMPUTER_VISION_KEY"
- },
- {
- "name": "AZURE_COMPUTER_VISION_ENDPOINT",
- "value": "$COMPUTER_VISION_ENDPOINT"
- },
- {
- "name": "AZURE_STORAGE_ACCOUNT_NAME",
- "value": "$MY_STORAGE_ACCOUNT_NAME"
- },
- {
- "name": "AZURE_STORAGE_ACCOUNT_KEY",
- "value": "$STORAGE_ACCOUNT_KEY"
- }
- ],
- "image": "ralphr123/cn-app",
- "name": "$MY_CONTAINER_APP_NAME",
- "resources": {
- "cpu": 0.5,
- "ephemeralStorage": "2Gi",
- "memory": "1Gi"
- }
- }
- ],
- "initContainers": null,
- "revisionSuffix": "",
- "scale": {
- "maxReplicas": 10,
- "minReplicas": null,
- "rules": null
- },
- "serviceBinds": null,
- "terminationGracePeriodSeconds": null,
- "volumes": null
- },
- "workloadProfileName": null
- },
- "resourceGroup": "$MY_RESOURCE_GROUP_NAME",
- "systemData": {
- "createdAt": "2023-08-10T21:50:07.2125698",
- "createdBy": "username@domain.com",
- "createdByType": "User",
- "lastModifiedAt": "2023-08-10T21:50:07.2125698",
- "lastModifiedBy": "username@domain.com",
- "lastModifiedByType": "User"
- },
- "type": "Microsoft.App/containerApps"
-}
-```
-
-## Create a database firewall rule
-
-By default, our database is configured to allow traffic from an allowlist of IP addresses. We need to add the IP of our newly deployed Container App to this allowlist. We can get the IP from the `az containerapp show` command.
-
-```bash
-export CONTAINER_APP_IP=$(az containerapp show --name $MY_CONTAINER_APP_NAME --resource-group $MY_RESOURCE_GROUP_NAME --query "properties.outboundIpAddresses[0]" --output tsv)
-```
-
-We can now add this IP as a firewall rule with this command:
-
-```bash
-az postgres flexible-server firewall-rule create \
- --name $MY_DATABASE_SERVER_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --rule-name allow-container-app \
- --start-ip-address $CONTAINER_APP_IP \
- --end-ip-address $CONTAINER_APP_IP
-```
-
-Results:
-
-
-```json
-{
- "endIpAddress": "20.237.221.47",
- "id": "/subscriptions/ab9d8365-2f65-47a4-8df4-7e40db70c8d2/resourceGroups/$MY_RESOURCE_GROUP_NAME/providers/Microsoft.DBforPostgreSQL/flexibleServers/$MY_DATABASE_SERVER_NAME/firewallRules/allow-container-app",
- "name": "allow-container-app",
- "resourceGroup": "$MY_RESOURCE_GROUP_NAME",
- "startIpAddress": "20.237.221.47",
- "systemData": null,
- "type": "Microsoft.DBforPostgreSQL/flexibleServers/firewallRules"
-}
-```
-
-## Create a storage CORS rule
-
-Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain. CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain. We need to add a CORS rule on the URL of our web app to our storage account. First, let's get the URL with a similar `az containerapp show` command as earlier.
-
-```bash
-export CONTAINER_APP_URL=https://$(az containerapp show --name $MY_CONTAINER_APP_NAME --resource-group $MY_RESOURCE_GROUP_NAME --query "properties.configuration.ingress.fqdn" --output tsv)
-```
-
-Next, we're ready to add a CORS rule with the following command. Let's break down the different parts of this command.
-
-- We are specifying blob service as the storage type to add the rule to.
-- We are allowing all operations to be performed.
-- We are allowing only the container app URL we just saved.
-- We are allowing all HTTP headers from this URL.
-- Max age is the amount of time, in seconds, that a browser should cache the preflight response for a specific request.
-- We are passing the storage account name and key from earlier.
-
-```bash
-az storage cors add \
- --services b \
- --methods DELETE GET HEAD MERGE OPTIONS POST PUT PATCH \
- --origins $CONTAINER_APP_URL \
- --allowed-headers '*' \
- --max-age 3600 \
- --account-name $MY_STORAGE_ACCOUNT_NAME \
- --account-key $STORAGE_ACCOUNT_KEY
-```
-
-That's it! Feel free to access the newly deployed web app in your browser printing the CONTAINER_APP_URL environment variable we added earlier.
-
-```bash
-echo $CONTAINER_APP_URL
-```
-
-## Next Steps
-
-- [Azure Container Apps documentation](https://learn.microsoft.com/en-us/azure/container-apps/)
-- [Azure Database for PostgreSQL documentation](https://learn.microsoft.com/en-us/azure/postgresql/)
-- [Azure Blob Storage documentation](https://learn.microsoft.com/en-us/azure/storage/blobs/)
-- [Azure Computer (AI) Vision Documentation](https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/)
diff --git a/scenarios/ocd/CreateLinuxVMAndSSH/README.md b/scenarios/ocd/CreateLinuxVMAndSSH/README.md
deleted file mode 100644
index d483959d..00000000
--- a/scenarios/ocd/CreateLinuxVMAndSSH/README.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# Create a Linux VM and SSH On Azure
-
-## Define Environment Variables
-
-The First step in this tutorial is to define environment variables.
-
-```bash
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myVMResourceGroup$RANDOM_ID"
-export REGION=EastUS
-export MY_VM_NAME="myVM$RANDOM_ID"
-export MY_USERNAME=azureuser
-export MY_VM_IMAGE="Canonical:0001-com-ubuntu-minimal-jammy:minimal-22_04-lts-gen2:latest"
-```
-
-# Login to Azure using the CLI
-
-In order to run commands against Azure using the CLI you need to login. This is
-done, very simply, though the `az login` command:
-
-# Create a resource group
-
-A resource group is a container for related resources. All resources must be
-placed in a resource group. We will create one for this tutorial. The following
-command creates a resource group with the previously defined
-$MY_RESOURCE_GROUP_NAME and $REGION parameters.
-
-```bash
-az group create --name $MY_RESOURCE_GROUP_NAME --location $REGION
-```
-
-Results:
-
-
-
-```json
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMResourceGroup",
- "location": "eastus",
- "managedBy": null,
- "name": "myVMResourceGroup",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Create the Virtual Machine
-
-To create a VM in this resource group we need to run a simple command, here we
-have provided the `--generate-ssh-keys` flag, this will cause the CLI to look
-for an avialable ssh key in `~/.ssh`, if one is found it will be used, otherwise
-one will be generated and stored in `~/.ssh`. We also provide the
-`--public-ip-sku Standard` flag to ensure that the machine is accessible via a
-public IP. Finally, we are deploying the latest `Ubuntu 22.04` image. All other
-values are configured using environment variables.
-
-```bash
-az vm create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_VM_NAME \
- --image $MY_VM_IMAGE \
- --admin-username $MY_USERNAME \
- --assign-identity \
- --generate-ssh-keys \
- --public-ip-sku Standard
-```
-
-Results:
-
-
-
-```json
-{
- "fqdns": "",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMResourceGroup/providers/Microsoft.Compute/virtualMachines/myVM",
- "location": "eastus",
- "macAddress": "00-0D-3A-10-4F-70",
- "powerState": "VM running",
- "privateIpAddress": "10.0.0.4",
- "publicIpAddress": "52.147.208.85",
- "resourceGroup": "myVMResourceGroup",
- "zones": ""
-}
-```
-
-### Enable Azure AD login for a Linux Virtual Machine in Azure
-
-The following example has deploys a Linux VM and then installs the extension to
-enable Azure AD login for a Linux VM. VM extensions are small applications that
-provide post-deployment configuration and automation tasks on Azure virtual
-machines.
-
-```bash
-az vm extension set \
- --publisher Microsoft.Azure.ActiveDirectory \
- --name AADSSHLoginForLinux \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --vm-name $MY_VM_NAME
-```
-
-# Store IP Address of VM in order to SSH
-
-Run the following command to get the IP Address of the VM and store it as an
-environment variable
-
-
-```bash
-export IP_ADDRESS=$(az vm show --show-details --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_VM_NAME --query publicIps --output tsv)
-```
-
-# SSH Into VM
-
-
-
-
-
-You can now SSH into the VM by running the following command.
-
-```bash
-ssh -o StrictHostKeyChecking=no $MY_USERNAME@$IP_ADDRESS
-```
-
-# Next Steps
-
-- [VM Documentation](https://learn.microsoft.com/en-us/azure/virtual-machines/)
-- [Use Cloud-Init to initialize a Linux VM on first boot](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/tutorial-automate-vm-deployment)
-- [Create custom VM images](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/tutorial-custom-images)
-- [Load Balance VMs](https://learn.microsoft.com/en-us/azure/load-balancer/quickstart-load-balancer-standard-public-cli)
diff --git a/scenarios/ocd/CreateLinuxVMLAMP/README.md b/scenarios/ocd/CreateLinuxVMLAMP/README.md
deleted file mode 100644
index 956e05f5..00000000
--- a/scenarios/ocd/CreateLinuxVMLAMP/README.md
+++ /dev/null
@@ -1,819 +0,0 @@
-# Install a LEMP stack on Azure
-
-This article walks you through how to deploy an NGINX web server, Azure MySQL Flexible Server, and PHP (the LEMP stack) on an Ubuntu Linux VM in Azure. To see the LEMP server in action, you can optionally install and configure a WordPress site. In this tutorial you learn how to:
-
-> [!div class="checklist"]
-
-> * Create a Linux Ubuntu VM
-> * Open ports 80 and 443 for web traffic
-> * Install and Secure NGINX, Azure Flexible MySQL Server, and PHP
-> * Verify installation and configuration
-> * Install WordPress
-
-## Variable declaration
-
-First we will define a few variables that will help with the configuration of the LEMP workload.
-
-```bash
-export NETWORK_PREFIX="$(($RANDOM % 254 + 1))"
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myLEMPResourceGroup$RANDOM_ID"
-export REGION="eastus"
-export MY_VM_NAME="myVM$RANDOM_ID"
-export MY_VM_USERNAME="azureadmin"
-export MY_VM_SIZE='Standard_DS2_v2'
-export MY_VM_IMAGE='Canonical:0001-com-ubuntu-minimal-jammy:minimal-22_04-lts-gen2:latest'
-export MY_PUBLIC_IP_NAME="myPublicIP$RANDOM_ID"
-export MY_DNS_LABEL="mydnslabel$RANDOM_ID"
-export MY_NSG_NAME="myNSG$RANDOM_ID"
-export MY_NSG_SSH_RULE="Allow-Access$RANDOM_ID"
-export MY_VM_NIC_NAME="myVMNic$RANDOM_ID"
-export MY_VNET_NAME="myVNet$RANDOM_ID"
-export MY_VNET_PREFIX="10.$NETWORK_PREFIX.0.0/22"
-export MY_SN_NAME="mySN$RANDOM_ID"
-export MY_SN_PREFIX="10.$NETWORK_PREFIX.0.0/24"
-export MY_MYSQL_DB_NAME="mydb$RANDOM_ID"
-export MY_MYSQL_ADMIN_USERNAME="dbadmin$RANDOM_ID"
-export MY_MYSQL_ADMIN_PW="$(openssl rand -base64 32)"
-export MY_MYSQL_SN_NAME="myMySQLSN$RANDOM_ID"
-export MY_WP_ADMIN_PW="$(openssl rand -base64 32)"
-export MY_WP_ADMIN_USER="wpcliadmin"
-export MY_AZURE_USER=$(az account show --query user.name --output tsv)
-export FQDN="${MY_DNS_LABEL}.${REGION}.cloudapp.azure.com"
-```
-
-
-
-## Create RG
-
-Create a resource group with the [az group create](https://learn.microsoft.com/cli/azure/group#az-group-create) command. An Azure resource group is a logical container into which Azure resources are deployed and managed.
-The following example creates a resource group named `$MY_RESOURCE_GROUP_NAME` in the `eastus` location.
-
-```bash
-az group create \
- --name $MY_RESOURCE_GROUP_NAME \
- --location $REGION -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx",
- "location": "eastus",
- "managedBy": null,
- "name": "myLEMPResourceGroupxxxxxx",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Setup LEMP networking
-
-## Create an Azure Virtual Network
-
-A virtual network is the fundamental building block for private networks in Azure. Azure Virtual Network enables Azure resources like VMs to securely communicate with each other and the internet.
-Use [az network vnet create](https://learn.microsoft.com/cli/azure/network/vnet#az-network-vnet-create) to create a virtual network named `$MY_VNET_NAME` with a subnet named `$MY_SN_NAME` in the `$MY_RESOURCE_GROUP_NAME` resource group.
-
-```bash
-az network vnet create \
- --name $MY_VNET_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION \
- --address-prefix $MY_VNET_PREFIX \
- --subnet-name $MY_SN_NAME \
- --subnet-prefixes $MY_SN_PREFIX -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "newVNet": {
- "addressSpace": {
- "addressPrefixes": [
- "10.19.0.0/22"
- ]
- },
- "enableDdosProtection": false,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx",
- "location": "eastus",
- "name": "myVNetxxxxxx",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "subnets": [
- {
- "addressPrefix": "10.19.0.0/24",
- "delegations": [],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx/subnets/mySNxxxxxx",
- "name": "mySNxxxxxx",
- "privateEndpointNetworkPolicies": "Disabled",
- "privateLinkServiceNetworkPolicies": "Enabled",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "type": "Microsoft.Network/virtualNetworks/subnets"
- }
- ],
- "type": "Microsoft.Network/virtualNetworks",
- "virtualNetworkPeerings": []
- }
-}
-```
-
-## Create an Azure Public IP
-
-Use [az network public-ip create](https://learn.microsoft.com/cli/azure/network/public-ip#az-network-public-ip-create) to create a standard zone-redundant public IPv4 address named `MY_PUBLIC_IP_NAME` in `$MY_RESOURCE_GROUP_NAME`.
-
->[!NOTE]
->The below options for zones are only valid selections in regions with [Availability Zones](https://learn.microsoft.com/azure/reliability/availability-zones-service-support).
-
-```bash
-az network public-ip create \
- --name $MY_PUBLIC_IP_NAME \
- --location $REGION \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --dns-name $MY_DNS_LABEL \
- --sku Standard \
- --allocation-method static \
- --version IPv4 \
- --zone 1 2 3 -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "publicIp": {
- "ddosSettings": {
- "protectionMode": "VirtualNetworkInherited"
- },
- "dnsSettings": {
- "domainNameLabel": "mydnslabelxxxxxx",
- "fqdn": "mydnslabelxxxxxx.eastus.cloudapp.azure.com"
- },
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/publicIPAddresses/myPublicIPxxxxxx",
- "idleTimeoutInMinutes": 4,
- "ipTags": [],
- "location": "eastus",
- "name": "myPublicIPxxxxxx",
- "provisioningState": "Succeeded",
- "publicIPAddressVersion": "IPv4",
- "publicIPAllocationMethod": "Static",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "sku": {
- "name": "Standard",
- "tier": "Regional"
- },
- "type": "Microsoft.Network/publicIPAddresses",
- "zones": [
- "1",
- "2",
- "3"
- ]
- }
-}
-```
-
-## Create an Azure Network Security Group
-
-Security rules in network security groups enable you to filter the type of network traffic that can flow in and out of virtual network subnets and network interfaces. To learn more about network security groups, see [Network security group overview](https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview).
-
-```bash
-az network nsg create \
- --name $MY_NSG_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "NewNSG": {
- "defaultSecurityRules":
- {
- "access": "Allow",
- "description": "Allow inbound traffic from all VMs in VNET",
- "destinationAddressPrefix": "VirtualNetwork",
- "destinationAddressPrefixes": [],
- "destinationPortRange": "*",
- "destinationPortRanges": [],
- "direction": "Inbound",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroup104/providers/Microsoft.Network/networkSecurityGroups/protect-vms/defaultSecurityRules/AllowVnetInBound",
- "name": "AllowVnetInBound",
- "priority": 65000,
- "protocol": "*",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroup104",
- "sourceAddressPrefix": "VirtualNetwork",
- "sourceAddressPrefixes": [],
- "sourcePortRange": "*",
- "sourcePortRanges": [],
- "type": "Microsoft.Network/networkSecurityGroups/defaultSecurityRules"
- },
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroup104/providers/Microsoft.Network/networkSecurityGroups/protect-vms",
- "location": "eastus",
- "name": "protect-vms",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroup104",
- "securityRules": [],
- "type": "Microsoft.Network/networkSecurityGroups"
- }
-}
-```
-
-## Create Azure Network Security Group rules
-
-You'll create a rule to allow connections to the virtual machine on port 22 for SSH and ports 80, 443 for HTTP and HTTPS. An extra rule is created to allow all ports for outbound connections. Use [az network nsg rule create](https://learn.microsoft.com/cli/azure/network/nsg/rule#az-network-nsg-rule-create) to create a network security group rule.
-
-```bash
-az network nsg rule create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --nsg-name $MY_NSG_NAME \
- --name $MY_NSG_SSH_RULE \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix '*' \
- --source-port-range '*' \
- --destination-address-prefix '*' \
- --destination-port-range 22 80 443 -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "access": "Allow",
- "destinationAddressPrefix": "*",
- "destinationAddressPrefixes": [],
- "destinationPortRanges": [
- "22",
- "80",
- "443"
- ],
- "direction": "Inbound",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/networkSecurityGroups/myNSGNamexxxxxx/securityRules/Allow-Accessxxxxxx",
- "name": "Allow-Accessxxxxxx",
- "priority": 100,
- "protocol": "Tcp",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "sourceAddressPrefix": "*",
- "sourceAddressPrefixes": [],
- "sourcePortRange": "*",
- "sourcePortRanges": [],
- "type": "Microsoft.Network/networkSecurityGroups/securityRules"
-}
-```
-
-## Create an Azure Network Interface
-
-You'll use [az network nic create](https://learn.microsoft.com/cli/azure/network/nic#az-network-nic-create) to create the network interface for the virtual machine. The public IP addresses and the NSG created previously are associated with the NIC. The network interface is attached to the virtual network you created previously.
-
-```bash
-az network nic create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_VM_NIC_NAME \
- --location $REGION \
- --ip-forwarding false \
- --subnet $MY_SN_NAME \
- --vnet-name $MY_VNET_NAME \
- --network-security-group $MY_NSG_NAME \
- --public-ip-address $MY_PUBLIC_IP_NAME -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "NewNIC": {
- "auxiliaryMode": "None",
- "auxiliarySku": "None",
- "disableTcpStateTracking": false,
- "dnsSettings": {
- "appliedDnsServers": [],
- "dnsServers": []
- },
- "enableAcceleratedNetworking": false,
- "enableIPForwarding": false,
- "hostedWorkloads": [],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/networkInterfaces/myVMNicNamexxxxxx",
- "ipConfigurations": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/networkInterfaces/myVMNicNamexxxxxx/ipConfigurations/ipconfig1",
- "name": "ipconfig1",
- "primary": true,
- "privateIPAddress": "10.19.0.4",
- "privateIPAddressVersion": "IPv4",
- "privateIPAllocationMethod": "Dynamic",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "subnet": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx/subnets/mySNxxxxxx",
- "resourceGroup": "myLEMPResourceGroupxxxxxx"
- },
- "type": "Microsoft.Network/networkInterfaces/ipConfigurations"
- }
- ],
- "location": "eastus",
- "name": "myVMNicNamexxxxxx",
- "networkSecurityGroup": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/networkSecurityGroups/myNSGNamexxxxxx",
- "resourceGroup": "myLEMPResourceGroupxxxxxx"
- },
- "nicType": "Standard",
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "tapConfigurations": [],
- "type": "Microsoft.Network/networkInterfaces",
- "vnetEncryptionSupported": false
- }
-}
-```
-
-## Cloud-init overview
-
-Cloud-init is a widely used approach to customize a Linux VM as it boots for the first time. You can use cloud-init to install packages and write files, or to configure users and security. As cloud-init runs during the initial boot process, there are no additional steps or required agents to apply your configuration.
-
-Cloud-init also works across distributions. For example, you don't use apt-get install or yum install to install a package. Instead you can define a list of packages to install. Cloud-init automatically uses the native package management tool for the distro you select.
-
-We are working with our partners to get cloud-init included and working in the images that they provide to Azure. For detailed information cloud-init support for each distribution, see [Cloud-init support for VMs in Azure](https://learn.microsoft.com/azure/virtual-machines/linux/using-cloud-init).
-
-### Create cloud-init config file
-
-To see cloud-init in action, create a VM that installs a LEMP stack and runs a simple Wordpress app secured with an SSL certificate. The following cloud-init configuration installs the required packages, creates the Wordpress website, then initialize and starts the website.
-
-```bash
-cat << EOF > cloud-init.txt
-#cloud-config
-
-# Install, update, and upgrade packages
-package_upgrade: true
-package_update: true
-package_reboot_if_require: true
-
-# Install packages
-packages:
- - vim
- - certbot
- - python3-certbot-nginx
- - bash-completion
- - nginx
- - mysql-client
- - php
- - php-cli
- - php-bcmath
- - php-curl
- - php-imagick
- - php-intl
- - php-json
- - php-mbstring
- - php-mysql
- - php-gd
- - php-xml
- - php-xmlrpc
- - php-zip
- - php-fpm
-
-write_files:
- - owner: www-data:www-data
- path: /etc/nginx/sites-available/default.conf
- content: |
- server {
- listen 80 default_server;
- listen [::]:80 default_server;
- root /var/www/html;
- server_name $FQDN;
- }
-
-write_files:
- - owner: www-data:www-data
- path: /etc/nginx/sites-available/$FQDN.conf
- content: |
- upstream php {
- server unix:/run/php/php8.1-fpm.sock;
- }
- server {
- listen 443 ssl http2;
- listen [::]:443 ssl http2;
-
- server_name $FQDN;
-
- ssl_certificate /etc/letsencrypt/live/$FQDN/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/$FQDN/privkey.pem;
-
- root /var/www/$FQDN;
- index index.php;
-
- location / {
- try_files \$uri \$uri/ /index.php?\$args;
- }
- location ~ \.php$ {
- include fastcgi_params;
- fastcgi_intercept_errors on;
- fastcgi_pass php;
- fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
- }
- location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
- expires max;
- log_not_found off;
- }
- location = /favicon.ico {
- log_not_found off;
- access_log off;
- }
-
- location = /robots.txt {
- allow all;
- log_not_found off;
- access_log off;
- }
- }
- server {
- listen 80;
- listen [::]:80;
- server_name $FQDN;
- return 301 https://$FQDN\$request_uri;
- }
-
-runcmd:
- - sed -i 's/;cgi.fix_pathinfo.*/cgi.fix_pathinfo = 1/' /etc/php/8.1/fpm/php.ini
- - sed -i 's/^max_execution_time \= .*/max_execution_time \= 300/g' /etc/php/8.1/fpm/php.ini
- - sed -i 's/^upload_max_filesize \= .*/upload_max_filesize \= 64M/g' /etc/php/8.1/fpm/php.ini
- - sed -i 's/^post_max_size \= .*/post_max_size \= 64M/g' /etc/php/8.1/fpm/php.ini
- - systemctl restart php8.1-fpm
- - systemctl restart nginx
- - certbot --nginx certonly --non-interactive --agree-tos -d $FQDN -m dummy@dummy.com --redirect
- - ln -s /etc/nginx/sites-available/$FQDN.conf /etc/nginx/sites-enabled/
- - rm /etc/nginx/sites-enabled/default
- - systemctl restart nginx
- - curl --url https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar --output /tmp/wp-cli.phar
- - mv /tmp/wp-cli.phar /usr/local/bin/wp
- - chmod +x /usr/local/bin/wp
- - wp cli update
- - mkdir -m 0755 -p /var/www/$FQDN
- - chown -R azureadmin:www-data /var/www/$FQDN
- - sudo -u azureadmin -i -- wp core download --path=/var/www/$FQDN
- - sudo -u azureadmin -i -- wp config create --dbhost=$MY_MYSQL_DB_NAME.mysql.database.azure.com --dbname=wp001 --dbuser=$MY_MYSQL_ADMIN_USERNAME --dbpass="$MY_MYSQL_ADMIN_PW" --path=/var/www/$FQDN
- - sudo -u azureadmin -i -- wp core install --url=$FQDN --title="Azure hosted blog" --admin_user=$MY_WP_ADMIN_USER --admin_password="$MY_WP_ADMIN_PW" --admin_email=$MY_AZURE_USER --path=/var/www/$FQDN
- - sudo -u azureadmin -i -- wp plugin update --all --path=/var/www/$FQDN
- - chmod 600 /var/www/$FQDN/wp-config.php
- - mkdir -p -m 0775 /var/www/$FQDN/wp-content/uploads
- - chgrp www-data /var/www/$FQDN/wp-content/uploads
-EOF
-```
-
-## Create an Azure Private DNS Zone for Azure MySQL Flexible Server
-
-Azure Private DNS Zone integration allows you to resolve the private DNS within the current VNET or any in-region peered VNET where the private DNS Zone is linked. You'll use [az network private-dns zone create](https://learn.microsoft.com/cli/azure/network/private-dns/zone#az-network-private-dns-zone-create) to create the private DNS zone.
-
-```bash
-az network private-dns zone create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_DNS_LABEL.private.mysql.database.azure.com -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/privateDnsZones/mydnslabelxxxxxx.private.mysql.database.azure.com",
- "location": "global",
- "maxNumberOfRecordSets": 25000,
- "maxNumberOfVirtualNetworkLinks": 1000,
- "maxNumberOfVirtualNetworkLinksWithRegistration": 100,
- "name": "mydnslabelxxxxxx.private.mysql.database.azure.com",
- "numberOfRecordSets": 1,
- "numberOfVirtualNetworkLinks": 0,
- "numberOfVirtualNetworkLinksWithRegistration": 0,
- "provisioningState": "Succeeded",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "tags": null,
- "type": "Microsoft.Network/privateDnsZones"
-}
-```
-
-## Create an Azure Database for MySQL - Flexible Server
-
-Azure Database for MySQL - Flexible Server is a managed service that you can use to run, manage, and scale highly available MySQL servers in the cloud. Create a flexible server with the [az mysql flexible-server create](https://learn.microsoft.com/cli/azure/mysql/flexible-server#az-mysql-flexible-server-create) command. A server can contain multiple databases. The following command creates a server using service defaults and variable values from your Azure CLI's local environment:
-
-```bash
-az mysql flexible-server create \
- --admin-password $MY_MYSQL_ADMIN_PW \
- --admin-user $MY_MYSQL_ADMIN_USERNAME \
- --auto-scale-iops Disabled \
- --high-availability Disabled \
- --iops 500 \
- --location $REGION \
- --name $MY_MYSQL_DB_NAME \
- --database-name wp001 \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --sku-name Standard_B2s \
- --storage-auto-grow Disabled \
- --storage-size 20 \
- --subnet $MY_MYSQL_SN_NAME \
- --private-dns-zone $MY_DNS_LABEL.private.mysql.database.azure.com \
- --tier Burstable \
- --version 8.0.21 \
- --vnet $MY_VNET_NAME \
- --yes -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "databaseName": "wp001",
- "host": "mydbxxxxxx.mysql.database.azure.com",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.DBforMySQL/flexibleServers/mydbxxxxxx",
- "location": "East US",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "skuname": "Standard_B2s",
- "subnetId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx/subnets/myMySQLSNxxxxxx",
- "username": "dbadminxxxxxx",
- "version": "8.0.21"
-}
-```
-
-```bash
-echo "Your MySQL user $MY_MYSQL_ADMIN_USERNAME password is: $MY_WP_ADMIN_PW"
-```
-
-The server created has the below attributes:
-
-* The server name, admin username, admin password, resource group name, location are already specified in local context environment of the cloud shell, and will be created in the same location as your the resource group and the other Azure components.
-* Service defaults for remaining server configurations: compute tier (Burstable), compute size/SKU (Standard_B2s), backup retention period (7 days), and MySQL version (8.0.21)
-* The default connectivity method is Private access (VNet Integration) with a linked virtual network and a auto-generated subnet.
-
-> [!NOTE]
-> The connectivity method cannot be changed after creating the server. For example, if you selected `Private access (VNet Integration)` during create then you cannot change to `Public access (allowed IP addresses)` after create. We highly recommend creating a server with Private access to securely access your server using VNet Integration. Learn more about Private access in the [concepts article](https://learn.microsoft.com/azure/mysql/flexible-server/concepts-networking-vnet).
-
-If you'd like to change any defaults, please refer to the Azure CLI [reference documentation](https://learn.microsoft.com/cli/azure//mysql/flexible-server) for the complete list of configurable CLI parameters.
-
-## Check the Azure Database for MySQL - Flexible Server status
-
-It takes a few minutes to create the Azure Database for MySQL - Flexible Server and supporting resources.
-
-```bash
-runtime="10 minute";
-endtime=$(date -ud "$runtime" +%s);
-while [[ $(date -u +%s) -le $endtime ]]; do
- STATUS=$(az mysql flexible-server show -g $MY_RESOURCE_GROUP_NAME -n $MY_MYSQL_DB_NAME --query state -o tsv);
- echo $STATUS;
- if [ "$STATUS" == 'Ready' ]; then
- break;
- else
- sleep 10;
- fi;
-done
-```
-
-## Configure server parameters in Azure Database for MySQL - Flexible Server
-
-You can manage Azure Database for MySQL - Flexible Server configuration using server parameters. The server parameters are configured with the default and recommended value when you create the server.
-
-Show server parameter details
-To show details about a particular parameter for a server, run the [az mysql flexible-server parameter show](https://learn.microsoft.com/cli/azure/mysql/flexible-server/parameter) command.
-
-### Disable Azure Database for MySQL - Flexible Server SSL connection parameter for Wordpress integration
-
-Modify a server parameter value
-You can also modify the value of a certain server parameter, which updates the underlying configuration value for the MySQL server engine. To update the server parameter, use the [az mysql flexible-server parameter set](https://learn.microsoft.com/cli/azure/mysql/flexible-server/parameter#az-mysql-flexible-server-parameter-set) command.
-
-```bash
-az mysql flexible-server parameter set \
- -g $MY_RESOURCE_GROUP_NAME \
- -s $MY_MYSQL_DB_NAME \
- -n require_secure_transport -v "OFF" -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "allowedValues": "ON,OFF",
- "currentValue": "OFF",
- "dataType": "Enumeration",
- "defaultValue": "ON",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.DBforMySQL/flexibleServers/mydbxxxxxx/configurations/require_secure_transport",
- "isConfigPendingRestart": "False",
- "isDynamicConfig": "True",
- "isReadOnly": "False",
- "name": "require_secure_transport",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "source": "user-override",
- "systemData": null,
- "type": "Microsoft.DBforMySQL/flexibleServers/configurations",
- "value": "OFF"
-}
-```
-
-## Create an Azure Linux Virtual Machine
-
-The following example creates a VM named `$MY_VM_NAME` and creates SSH keys if they do not already exist in a default key location. The command also sets `$MY_VM_USERNAME` as an administrator user name.
-To improve the security of Linux virtual machines in Azure, you can integrate with Azure Active Directory authentication. You can now use Azure AD as a core authentication platform and a certificate authority to SSH into a Linux VM by using Azure AD and OpenSSH certificate-based authentication. This functionality allows organizations to manage access to VMs with Azure role-based access control and Conditional Access policies.
-
-Create a VM with the [az vm create](https://learn.microsoft.com/cli/azure/vm#az-vm-create) command.
-
-```bash
-az vm create \
- --name $MY_VM_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --admin-username $MY_VM_USERNAME \
- --authentication-type ssh \
- --assign-identity \
- --image $MY_VM_IMAGE \
- --location $REGION \
- --nic-delete-option Delete \
- --os-disk-caching ReadOnly \
- --os-disk-delete-option Delete \
- --os-disk-size-gb 30 \
- --size $MY_VM_SIZE \
- --generate-ssh-keys \
- --storage-sku Premium_LRS \
- --nics $MY_VM_NIC_NAME \
- --custom-data cloud-init.txt -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "fqdns": "mydnslabelxxxxxx.eastus.cloudapp.azure.com",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Compute/virtualMachines/myVMNamexxxxxx",
- "identity": {
- "principalId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
- "tenantId": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
- "type": "SystemAssigned",
- "userAssignedIdentities": null
- },
- "location": "eastus",
- "macAddress": "60-45-BD-D8-1D-84",
- "powerState": "VM running",
- "privateIpAddress": "10.19.0.4",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "zones": ""
-}
-```
-
-## Check the Azure Linux Virtual Machine status
-
-It takes a few minutes to create the VM and supporting resources. The provisioningState value of Succeeded appears when the extension is successfully installed on the VM. The VM must have a running [VM agent](https://learn.microsoft.com/azure/virtual-machines/extensions/agent-linux) to install the extension.
-
-```bash
-runtime="5 minute";
-endtime=$(date -ud "$runtime" +%s);
-while [[ $(date -u +%s) -le $endtime ]]; do
- STATUS=$(ssh -o StrictHostKeyChecking=no $MY_VM_USERNAME@$FQDN "cloud-init status --wait");
- echo $STATUS;
- if [[ "$STATUS" == *'status: done'* ]]; then
- break;
- else
- sleep 10;
- fi;
-done
-```
-
-
-
-
-
-## Enable Azure AD login for a Linux Virtual Machine in Azure
-
-The following installs the extension to enable Azure AD login for a Linux VM. VM extensions are small applications that provide post-deployment configuration and automation tasks on Azure virtual machines.
-
-```bash
-az vm extension set \
- --publisher Microsoft.Azure.ActiveDirectory \
- --name AADSSHLoginForLinux \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --vm-name $MY_VM_NAME -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "autoUpgradeMinorVersion": true,
- "enableAutomaticUpgrade": null,
- "forceUpdateTag": null,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myLEMPResourceGroupxxxxxx/providers/Microsoft.Compute/virtualMachines/myVMNamexxxxxx/extensions/AADSSHLoginForLinux",
- "instanceView": null,
- "location": "eastus",
- "name": "AADSSHLoginForLinux",
- "protectedSettings": null,
- "protectedSettingsFromKeyVault": null,
- "provisioningState": "Succeeded",
- "publisher": "Microsoft.Azure.ActiveDirectory",
- "resourceGroup": "myLEMPResourceGroupxxxxxx",
- "settings": null,
- "suppressFailures": null,
- "tags": null,
- "type": "Microsoft.Compute/virtualMachines/extensions",
- "typeHandlerVersion": "1.0",
- "typePropertiesType": "AADSSHLoginForLinux"
-}
-```
-
-## Check and browse your WordPress website
-
-[WordPress](https://www.wordpress.org) is an open source content management system (CMS) used by over 40% of the web to create websites, blogs, and other applications. WordPress can be run on a few different Azure services: [AKS](https://learn.microsoft.com/azure/mysql/flexible-server/tutorial-deploy-wordpress-on-aks), Virtual Machines, and App Service. For a full list of WordPress options on Azure, see [WordPress on Azure Marketplace](https://azuremarketplace.microsoft.com/marketplace/apps?page=1&search=wordpress).
-
-This WordPress setup is only for proof of concept. To install the latest WordPress in production with recommended security settings, see the [WordPress documentation](https://codex.wordpress.org/Main_Page).
-
-Validate that the application is running by curling the application url:
-
-```bash
-runtime="5 minute";
-endtime=$(date -ud "$runtime" +%s);
-while [[ $(date -u +%s) -le $endtime ]]; do
- if curl -I -s -f $FQDN > /dev/null ; then
- curl -L -s -f $FQDN 2> /dev/null | head -n 9
- break
- else
- sleep 10
- fi;
-done
-```
-
-Results:
-
-
-```HTML
-
-
-
-
-
-
-Azure hosted blog
-
-
-```
-
-```bash
-echo "You can now visit your web server at https://$FQDN"
-```
diff --git a/scenarios/ocd/CreateLinuxVMSSwithAppGW/README.md b/scenarios/ocd/CreateLinuxVMSSwithAppGW/README.md
deleted file mode 100644
index de17dce6..00000000
--- a/scenarios/ocd/CreateLinuxVMSSwithAppGW/README.md
+++ /dev/null
@@ -1,838 +0,0 @@
-# Create a Virtual Machine Scale Set with Application Gateway with Linux image
-
-## Define Environment Variables
-
-The First step in this tutorial is to define environment variables.
-
-```bash
-
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myVMSSResourceGroup$RANDOM_ID"
-export REGION=EastUS
-export MY_VMSS_NAME="myVMSS$RANDOM_ID"
-export MY_USERNAME=azureuser
-export MY_VM_IMAGE="Ubuntu2204"
-export MY_VNET_NAME="myVNet$RANDOM_ID"
-export NETWORK_PREFIX="$(($RANDOM % 254 + 1))"
-export MY_VNET_PREFIX="10.$NETWORK_PREFIX.0.0/16"
-export MY_VM_SN_NAME="myVMSN$RANDOM_ID"
-export MY_VM_SN_PREFIX="10.$NETWORK_PREFIX.0.0/24"
-export MY_APPGW_SN_NAME="myAPPGWSN$RANDOM_ID"
-export MY_APPGW_SN_PREFIX="10.$NETWORK_PREFIX.1.0/24"
-export MY_APPGW_NAME="myAPPGW$RANDOM_ID"
-export MY_APPGW_PUBLIC_IP_NAME="myAPPGWPublicIP$RANDOM_ID"
-
-```
-# Login to Azure using the CLI
-
-In order to run commands against Azure using the CLI you need to login. This is done, very simply, though the `az login` command:
-
-# Create a resource group
-
-A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $MY_RESOURCE_GROUP_NAME and $REGION parameters.
-
-```bash
-az group create --name $MY_RESOURCE_GROUP_NAME --location $REGION -o JSON
-```
-
-Results:
-
-
-```json
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx",
- "location": "eastus",
- "managedBy": null,
- "name": "myVMSSResourceGroupxxxxxx",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-# Create Network Resources
-
-You need to create network resources before you proceed the VMSS steps. In this step you're going to create a VNET, 2 subnets 1 for Application Gateway and 1 for VMs. You also need to have a public IP to attach your Application Gateway to be able to reach your web application from internet.
-
-
-#### Create Virtual Network (VNET) and VM Subnet
-
-```bash
-az network vnet create --name $MY_VNET_NAME --resource-group $MY_RESOURCE_GROUP_NAME --location $REGION --address-prefix $MY_VNET_PREFIX --subnet-name $MY_VM_SN_NAME --subnet-prefix $MY_VM_SN_PREFIX -o JSON
-```
-
-Results:
-
-
-```json
-{
- "newVNet": {
- "addressSpace": {
- "addressPrefixes": [
- "10.X.0.0/16"
- ]
- },
- "enableDdosProtection": false,
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx",
- "location": "eastus",
- "name": "myVNetxxxxxx",
- "provisioningState": "Succeeded",
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "resourceGuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "subnets": [
- {
- "addressPrefix": "10.X.0.0/24",
- "delegations": [],
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx/subnets/myVMSNxxxxxx",
- "name": "myVMSNxxxxxx",
- "privateEndpointNetworkPolicies": "Disabled",
- "privateLinkServiceNetworkPolicies": "Enabled",
- "provisioningState": "Succeeded",
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/virtualNetworks/subnets"
- }
- ],
- "type": "Microsoft.Network/virtualNetworks",
- "virtualNetworkPeerings": []
- }
-}
-```
-
-### Create Application Gateway Resources
-
-Azure Application Gateway requires a dedicated subnet within your virtual network. The below command creates a subnet named $MY_APPGW_SN_NAME with specified address prefix named $MY_APPGW_SN_PREFIX in your VNET $MY_VNET_NAME
-
-
-```bash
-az network vnet subnet create --name $MY_APPGW_SN_NAME --resource-group $MY_RESOURCE_GROUP_NAME --vnet-name $MY_VNET_NAME --address-prefix $MY_APPGW_SN_PREFIX -o JSON
-```
-
-Results:
-
-
-```json
-{
- "addressPrefix": "10.66.1.0/24",
- "delegations": [],
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx/subnets/myAPPGWSNxxxxxx",
- "name": "myAPPGWSNxxxxxx",
- "privateEndpointNetworkPolicies": "Disabled",
- "privateLinkServiceNetworkPolicies": "Enabled",
- "provisioningState": "Succeeded",
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/virtualNetworks/subnets"
-}
-```
-The below command creates a standard, zone redundant, static, public IPv4 in your resource group.
-
-```bash
-az network public-ip create --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_APPGW_PUBLIC_IP_NAME --sku Standard --location $REGION --allocation-method static --version IPv4 --zone 1 2 3 -o JSON
- ```
-
-Results:
-
-
-```json
-{
- "publicIp": {
- "ddosSettings": {
- "protectionMode": "VirtualNetworkInherited"
- },
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/publicIPAddresses//myAPPGWPublicIPxxxxxx",
- "idleTimeoutInMinutes": 4,
- "ipAddress": "X.X.X.X",
- "ipTags": [],
- "location": "eastus",
- "name": "/myAPPGWPublicIPxxxxxx",
- "provisioningState": "Succeeded",
- "publicIPAddressVersion": "IPv4",
- "publicIPAllocationMethod": "Static",
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "resourceGuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "sku": {
- "name": "Standard",
- "tier": "Regional"
- },
- "type": "Microsoft.Network/publicIPAddresses",
- "zones": [
- "1",
- "2",
- "3"
- ]
- }
-}
-```
-
-In this step you create an Application Gateway that you're going to integrate with your Virtual Machine Scale Set. In this example we create a zone redundant Application Gateway with Standard_v2 SKU and enable Http communication for the Application Gateway. The public IP $MY_APPGW_PUBLIC_IP_NAME that we created in previous step attached to the Application Gateway.
-
-```bash
-az network application-gateway create --name $MY_APPGW_NAME --location $REGION --resource-group $MY_RESOURCE_GROUP_NAME --vnet-name $MY_VNET_NAME --subnet $MY_APPGW_SN_NAME --capacity 2 --zones 1 2 3 --sku Standard_v2 --http-settings-cookie-based-affinity Disabled --frontend-port 80 --http-settings-port 80 --http-settings-protocol Http --public-ip-address $MY_APPGW_PUBLIC_IP_NAME --priority 1001 -o JSON
- ```
-
-
-```json
-{
- "applicationGateway": {
- "backendAddressPools": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/backendAddressPools/appGatewayBackendPool",
- "name": "appGatewayBackendPool",
- "properties": {
- "backendAddresses": [],
- "provisioningState": "Succeeded",
- "requestRoutingRules": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/requestRoutingRules/rule1",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ]
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/backendAddressPools"
- }
- ],
- "backendHttpSettingsCollection": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/backendHttpSettingsCollection/appGatewayBackendHttpSettings",
- "name": "appGatewayBackendHttpSettings",
- "properties": {
- "connectionDraining": {
- "drainTimeoutInSec": 1,
- "enabled": false
- },
- "cookieBasedAffinity": "Disabled",
- "pickHostNameFromBackendAddress": false,
- "port": 80,
- "protocol": "Http",
- "provisioningState": "Succeeded",
- "requestRoutingRules": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/requestRoutingRules/rule1",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ],
- "requestTimeout": 30
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/backendHttpSettingsCollection"
- }
- ],
- "backendSettingsCollection": [],
- "frontendIPConfigurations": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/frontendIPConfigurations/appGatewayFrontendIP",
- "name": "appGatewayFrontendIP",
- "properties": {
- "httpListeners": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/httpListeners/appGatewayHttpListener",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ],
- "privateIPAllocationMethod": "Dynamic",
- "provisioningState": "Succeeded",
- "publicIPAddress": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/publicIPAddresses/myAPPGWPublicIPxxxxxx",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/frontendIPConfigurations"
- }
- ],
- "frontendPorts": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/frontendPorts/appGatewayFrontendPort",
- "name": "appGatewayFrontendPort",
- "properties": {
- "httpListeners": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/httpListeners/appGatewayHttpListener",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ],
- "port": 80,
- "provisioningState": "Succeeded"
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/frontendPorts"
- }
- ],
- "gatewayIPConfigurations": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/gatewayIPConfigurations/appGatewayFrontendIP",
- "name": "appGatewayFrontendIP",
- "properties": {
- "provisioningState": "Succeeded",
- "subnet": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxxx/subnets/myAPPGWSNxxxxxx",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/gatewayIPConfigurations"
- }
- ],
- "httpListeners": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/httpListeners/appGatewayHttpListener",
- "name": "appGatewayHttpListener",
- "properties": {
- "frontendIPConfiguration": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/frontendIPConfigurations/appGatewayFrontendIP",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- },
- "frontendPort": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/frontendPorts/appGatewayFrontendPort",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- },
- "hostNames": [],
- "protocol": "Http",
- "provisioningState": "Succeeded",
- "requestRoutingRules": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/requestRoutingRules/rule1",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ],
- "requireServerNameIndication": false
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/httpListeners"
- }
- ],
- "listeners": [],
- "loadDistributionPolicies": [],
- "operationalState": "Running",
- "privateEndpointConnections": [],
- "privateLinkConfigurations": [],
- "probes": [],
- "provisioningState": "Succeeded",
- "redirectConfigurations": [],
- "requestRoutingRules": [
- {
- "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/requestRoutingRules/rule1",
- "name": "rule1",
- "properties": {
- "backendAddressPool": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/backendAddressPools/appGatewayBackendPool",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- },
- "backendHttpSettings": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/backendHttpSettingsCollection/appGatewayBackendHttpSettings",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- },
- "httpListener": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxxxx/httpListeners/appGatewayHttpListener",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- },
- "priority": 1001,
- "provisioningState": "Succeeded",
- "ruleType": "Basic"
- },
- "resourceGroup": "myVMSSResourceGroupxxxxxx",
- "type": "Microsoft.Network/applicationGateways/requestRoutingRules"
- }
- ],
- "resourceGuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "rewriteRuleSets": [],
- "routingRules": [],
- "sku": {
- "capacity": 2,
- "family": "Generation_1",
- "name": "Standard_v2",
- "tier": "Standard_v2"
- },
- "sslCertificates": [],
- "sslProfiles": [],
- "trustedClientCertificates": [],
- "trustedRootCertificates": [],
- "urlPathMaps": []
- }
-}
- ```
-
-
-# Create Virtual Machine Scale Set
-
-The below command creates a zone redundant Virtual Machine Scale Set (VMSS) within your resource group $MY_RESOURCE_GROUP_NAME. We integrate the Application Gateway that we created previous step. This command creates 2 Standard_DS2_v2 SKU Virtual Machines with public IP in subnet $MY_VM_SN_NAME. A ssh key will be created during the below step you may want to save the key if you need to login your VMs via ssh.
-
-```bash
-az vmss create --name $MY_VMSS_NAME --resource-group $MY_RESOURCE_GROUP_NAME --image $MY_VM_IMAGE --admin-username $MY_USERNAME --generate-ssh-keys --public-ip-per-vm --orchestration-mode Uniform --instance-count 2 --zones 1 2 3 --vnet-name $MY_VNET_NAME --subnet $MY_VM_SN_NAME --vm-sku Standard_DS2_v2 --upgrade-policy-mode Automatic --app-gateway $MY_APPGW_NAME --backend-pool-name appGatewayBackendPool -o JSON
- ```
-
-Results:
-
-
-```json
-{
- "vmss": {
- "doNotRunExtensionsOnOverprovisionedVMs": false,
- "orchestrationMode": "Uniform",
- "overprovision": true,
- "platformFaultDomainCount": 1,
- "provisioningState": "Succeeded",
- "singlePlacementGroup": false,
- "timeCreated": "20xx-xx-xxTxx:xx:xx.xxxxxx+00:00",
- "uniqueId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
- "upgradePolicy": {
- "mode": "Automatic",
- "rollingUpgradePolicy": {
- "maxBatchInstancePercent": 20,
- "maxSurge": false,
- "maxUnhealthyInstancePercent": 20,
- "maxUnhealthyUpgradedInstancePercent": 20,
- "pauseTimeBetweenBatches": "PT0S",
- "rollbackFailedInstancesOnPolicyBreach": false
- }
- },
- "virtualMachineProfile": {
- "networkProfile": {
- "networkInterfaceConfigurations": [
- {
- "name": "myvmsa53cNic",
- "properties": {
- "disableTcpStateTracking": false,
- "dnsSettings": {
- "dnsServers": []
- },
- "enableAcceleratedNetworking": false,
- "enableIPForwarding": false,
- "ipConfigurations": [
- {
- "name": "myvmsa53cIPConfig",
- "properties": {
- "applicationGatewayBackendAddressPools": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGW7xxxxx/backendAddressPools/appGatewayBackendPool",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ],
- "privateIPAddressVersion": "IPv4",
- "publicIPAddressConfiguration": {
- "name": "instancepublicip",
- "properties": {
- "idleTimeoutInMinutes": 10,
- "ipTags": [],
- "publicIPAddressVersion": "IPv4"
- }
- },
- "subnet": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxx/subnets/myVMSN7xxxxx",
- "resourceGroup": "myVMSSResourceGroupxxxxxxx"
- }
- }
- }
- ],
- "primary": true
- }
- }
- ]
- },
- "osProfile": {
- "adminUsername": "azureuser",
- "allowExtensionOperations": true,
- "computerNamePrefix": "myvmsa53c",
- "linuxConfiguration": {
- "disablePasswordAuthentication": true,
- "enableVMAgentPlatformUpdates": false,
- "provisionVMAgent": true,
- "ssh": {
- "publicKeys": [
- {
- "keyData": "ssh-rsa xxxxxxxx",
- "path": "/home/azureuser/.ssh/authorized_keys"
- }
- ]
- }
- },
- "requireGuestProvisionSignal": true,
- "secrets": []
- },
- "storageProfile": {
- "diskControllerType": "SCSI",
- "imageReference": {
- "offer": "0001-com-ubuntu-server-jammy",
- "publisher": "Canonical",
- "sku": "22_04-lts-gen2",
- "version": "latest"
- },
- "osDisk": {
- "caching": "ReadWrite",
- "createOption": "FromImage",
- "diskSizeGB": 30,
- "managedDisk": {
- "storageAccountType": "Premium_LRS"
- },
- "osType": "Linux"
- }
- },
- "timeCreated": "20xx-xx-xxTxx:xx:xx.xxxxxx+00:00"
- },
- "zoneBalance": false
- }
-}
-```
-
-### Install ngnix with VMSS extensions
-
-The below command uses VMSS extension to run custom script. For testing purposes, here we install ngnix and publish a page that shows the hostname of the Virtual Machine that your HTTP requests hits. We use this custom script for this pusposes : https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh
-
-
-```bash
-az vmss extension set --publisher Microsoft.Azure.Extensions --version 2.0 --name CustomScript --resource-group $MY_RESOURCE_GROUP_NAME --vmss-name $MY_VMSS_NAME --settings '{ "fileUris": ["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"], "commandToExecute": "./automate_nginx.sh" }' -o JSON
-```
-
-Results:
-
-
-```json
-{
- "additionalCapabilities": null,
- "automaticRepairsPolicy": null,
- "constrainedMaximumCapacity": null,
- "doNotRunExtensionsOnOverprovisionedVMs": false,
- "extendedLocation": null,
- "hostGroup": null,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxx/providers/Microsoft.Compute/virtualMachineScaleSets/myVMSSxxxxx",
- "identity": null,
- "location": "eastus",
- "name": "myVMSSxxxx",
- "orchestrationMode": "Uniform",
- "overprovision": true,
- "plan": null,
- "platformFaultDomainCount": 1,
- "priorityMixPolicy": null,
- "provisioningState": "Succeeded",
- "proximityPlacementGroup": null,
- "resourceGroup": "myVMSSResourceGroupxxxxx",
- "scaleInPolicy": null,
- "singlePlacementGroup": false,
- "sku": {
- "capacity": 2,
- "name": "Standard_DS2_v2",
- "tier": "Standard"
- },
- "spotRestorePolicy": null,
- "tags": {},
- "timeCreated": "20xx-xx-xxTxx:xx:xx.xxxxxx+00:00",
- "type": "Microsoft.Compute/virtualMachineScaleSets",
- "uniqueId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
- "upgradePolicy": {
- "automaticOsUpgradePolicy": null,
- "mode": "Automatic",
- "rollingUpgradePolicy": {
- "enableCrossZoneUpgrade": null,
- "maxBatchInstancePercent": 20,
- "maxSurge": false,
- "maxUnhealthyInstancePercent": 20,
- "maxUnhealthyUpgradedInstancePercent": 20,
- "pauseTimeBetweenBatches": "PT0S",
- "prioritizeUnhealthyInstances": null,
- "rollbackFailedInstancesOnPolicyBreach": false
- }
- },
- "virtualMachineProfile": {
- "applicationProfile": null,
- "billingProfile": null,
- "capacityReservation": null,
- "diagnosticsProfile": null,
- "evictionPolicy": null,
- "extensionProfile": {
- "extensions": [
- {
- "autoUpgradeMinorVersion": true,
- "enableAutomaticUpgrade": null,
- "forceUpdateTag": null,
- "id": null,
- "name": "CustomScript",
- "protectedSettings": null,
- "protectedSettingsFromKeyVault": null,
- "provisionAfterExtensions": null,
- "provisioningState": null,
- "publisher": "Microsoft.Azure.Extensions",
- "settings": {
- "commandToExecute": "./automate_nginx.sh",
- "fileUris": [
- "https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/automate_nginx.sh"
- ]
- },
- "suppressFailures": null,
- "type": null,
- "typeHandlerVersion": "2.0",
- "typePropertiesType": "CustomScript"
- }
- ],
- "extensionsTimeBudget": null
- },
- "hardwareProfile": null,
- "licenseType": null,
- "networkProfile": {
- "healthProbe": null,
- "networkApiVersion": null,
- "networkInterfaceConfigurations": [
- {
- "deleteOption": null,
- "disableTcpStateTracking": false,
- "dnsSettings": {
- "dnsServers": []
- },
- "enableAcceleratedNetworking": false,
- "enableFpga": null,
- "enableIpForwarding": false,
- "ipConfigurations": [
- {
- "applicationGatewayBackendAddressPools": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxx/providers/Microsoft.Network/applicationGateways/myAPPGWxxxx/backendAddressPools/appGatewayBackendPool",
- "resourceGroup": "myVMSSResourceGroupxxxxxx"
- }
- ],
- "applicationSecurityGroups": null,
- "loadBalancerBackendAddressPools": null,
- "loadBalancerInboundNatPools": null,
- "name": "myvmsdxxxIPConfig",
- "primary": null,
- "privateIpAddressVersion": "IPv4",
- "publicIpAddressConfiguration": null,
- "subnet": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxx/providers/Microsoft.Network/virtualNetworks/myVNetxxxxx/subnets/myVMSNxxxxx",
- "resourceGroup": "myVMSSResourceGroupaxxxxx"
- }
- }
- ],
- "name": "myvmsxxxxxx",
- "networkSecurityGroup": null,
- "primary": true
- }
- ]
- },
- "osProfile": {
- "adminPassword": null,
- "adminUsername": "azureuser",
- "allowExtensionOperations": true,
- "computerNamePrefix": "myvmsdxxx",
- "customData": null,
- "linuxConfiguration": {
- "disablePasswordAuthentication": true,
- "enableVmAgentPlatformUpdates": false,
- "patchSettings": null,
- "provisionVmAgent": true,
- "ssh": {
- "publicKeys": [
- {
- "keyData": "ssh-rsa xxxxxxxx",
- "path": "/home/azureuser/.ssh/authorized_keys"
- }
- ]
- }
- },
- "requireGuestProvisionSignal": true,
- "secrets": [],
- "windowsConfiguration": null
- },
- "priority": null,
- "scheduledEventsProfile": null,
- "securityPostureReference": null,
- "securityProfile": null,
- "serviceArtifactReference": null,
- "storageProfile": {
- "dataDisks": null,
- "diskControllerType": "SCSI",
- "imageReference": {
- "communityGalleryImageId": null,
- "exactVersion": null,
- "id": null,
- "offer": "0001-com-ubuntu-server-jammy",
- "publisher": "Canonical",
- "sharedGalleryImageId": null,
- "sku": "22_04-lts-gen2",
- "version": "latest"
- },
- "osDisk": {
- "caching": "ReadWrite",
- "createOption": "FromImage",
- "deleteOption": null,
- "diffDiskSettings": null,
- "diskSizeGb": 30,
- "image": null,
- "managedDisk": {
- "diskEncryptionSet": null,
- "securityProfile": null,
- "storageAccountType": "Premium_LRS"
- },
- "name": null,
- "osType": "Linux",
- "vhdContainers": null,
- "writeAcceleratorEnabled": null
- }
- },
- "userData": null
- },
- "zoneBalance": false,
- "zones": [
- "1",
- "2",
- "3"
- ]
-}
-```
-
-
-# Define an autoscale profile
-
-To enable autoscale on a scale set, you first define an autoscale profile. This profile defines the default, minimum, and maximum scale set capacity. These limits let you control cost by not continually creating VM instances, and balance acceptable performance with a minimum number of instances that remain in a scale-in event.
-The following example sets the default, and minimum, capacity of 2 VM instances, and a maximum of 10:
-
-```bash
-az monitor autoscale create --resource-group $MY_RESOURCE_GROUP_NAME --resource $MY_VMSS_NAME --resource-type Microsoft.Compute/virtualMachineScaleSets --name autoscale --min-count 2 --max-count 10 --count 2
-```
-
-
-Results:
-
-
-```json
-{
- "enabled": true,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxx/providers/microsoft.insights/autoscalesettings/autoscale",
- "location": "eastus",
- "name": "autoscale",
- "namePropertiesName": "autoscale",
- "notifications": [
- {
- "email": {
- "customEmails": [],
- "sendToSubscriptionAdministrator": false,
- "sendToSubscriptionCoAdministrators": false
- },
- "webhooks": []
- }
- ],
- "predictiveAutoscalePolicy": {
- "scaleLookAheadTime": null,
- "scaleMode": "Disabled"
- },
- "profiles": [
- {
- "capacity": {
- "default": "2",
- "maximum": "10",
- "minimum": "2"
- },
- "fixedDate": null,
- "name": "default",
- "recurrence": null,
- "rules": []
- }
- ],
- "resourceGroup": "myVMSSResourceGroupxxxxx",
- "systemData": null,
- "tags": {},
- "targetResourceLocation": null,
- "targetResourceUri": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Compute/virtualMachineScaleSets/myVMSSxxxxxx",
- "type": "Microsoft.Insights/autoscaleSettings"
-}
-```
-
-# Create a rule to autoscale out
-
-The Following command creates a rule that 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.
-
-```bash
-az monitor autoscale rule create --resource-group $MY_RESOURCE_GROUP_NAME --autoscale-name autoscale --condition "Percentage CPU > 70 avg 5m" --scale out 3
-```
-
-Results:
-
-
-```json
-{
- "metricTrigger": {
- "dimensions": [],
- "dividePerInstance": null,
- "metricName": "Percentage CPU",
- "metricNamespace": null,
- "metricResourceLocation": null,
- "metricResourceUri": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Compute/virtualMachineScaleSets/myVMSSxxxxxx",
- "operator": "GreaterThan",
- "statistic": "Average",
- "threshold": "70",
- "timeAggregation": "Average",
- "timeGrain": "PT1M",
- "timeWindow": "PT5M"
- },
- "scaleAction": {
- "cooldown": "PT5M",
- "direction": "Increase",
- "type": "ChangeCount",
- "value": "3"
- }
-}
-```
-
-# Create a rule to autoscale in
-
-Create another rule with az monitor autoscale rule create that decreases the number of VM instances in a scale set when the average CPU load then drops below 30% over a 5-minute period. The following example defines the rule to scale in the number of VM instances by one.
-
-```bash
-az monitor autoscale rule create --resource-group $MY_RESOURCE_GROUP_NAME --autoscale-name autoscale --condition "Percentage CPU < 30 avg 5m" --scale in 1
-```
-
-Results:
-
-
-```json
-{
- "metricTrigger": {
- "dimensions": [],
- "dividePerInstance": null,
- "metricName": "Percentage CPU",
- "metricNamespace": null,
- "metricResourceLocation": null,
- "metricResourceUri": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMSSResourceGroupxxxxxx/providers/Microsoft.Compute/virtualMachineScaleSets/myVMSSxxxxxx",
- "operator": "LessThan",
- "statistic": "Average",
- "threshold": "30",
- "timeAggregation": "Average",
- "timeGrain": "PT1M",
- "timeWindow": "PT5M"
- },
- "scaleAction": {
- "cooldown": "PT5M",
- "direction": "Decrease",
- "type": "ChangeCount",
- "value": "1"
- }
-}
-```
-
-
-### Test the page
-
-The below command shows you the public IP of your Application Gateway. You can paste the IP adress to a browser page for testing.
-
-```bash
-az network public-ip show --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_APPGW_PUBLIC_IP_NAME --query [ipAddress] --output tsv
-```
-
-
-
-# References
-
-* [VMSS Documentation](https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview)
-* [VMSS AutoScale](https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/tutorial-autoscale-cli?tabs=Ubuntu)
-
diff --git a/scenarios/ocd/CreateLinuxVMSecureWebServer/README.md b/scenarios/ocd/CreateLinuxVMSecureWebServer/README.md
deleted file mode 100644
index 18309e57..00000000
--- a/scenarios/ocd/CreateLinuxVMSecureWebServer/README.md
+++ /dev/null
@@ -1,826 +0,0 @@
-# Intro to Create a NGINX Webserver Secured via HTTPS
-
-To secure web servers, a Transport Layer Security (TLS), previously known as Secure Sockets Layer (SSL), certificate can be used to encrypt web traffic. These TLS/SSL certificates can be stored in Azure Key Vault, and allow secure deployments of certificates to Linux virtual machines (VMs) in Azure. In this tutorial you learn how to:
-
-> [!div class="checklist"]
-
-> * Setup and secure Azure Networking
-> * Create an Azure Key Vault
-> * Generate or upload a certificate to the Key Vault
-> * Create a VM and install the NGINX web server
-> * Inject the certificate into the VM and configure NGINX with a TLS binding
-
-If you choose to install and use the CLI locally, this tutorial requires that you're running the Azure CLI version 2.0.30 or later. Run `az --version` to find the version. If you need to install or upgrade, see [Install Azure CLI]( https://learn.microsoft.com//cli/azure/install-azure-cli ).
-
-## Variable Declaration
-
-List of all the environment variables you'll need to execute this tutorial:
-
-```bash
-export NETWORK_PREFIX="$(($RANDOM % 254 + 1))"
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myResourceGroup$RANDOM_ID"
-export MY_KEY_VAULT="mykeyvault$RANDOM_ID"
-export MY_CERT_NAME="nginxcert$RANDOM_ID"
-export REGION="eastus"
-export MY_VM_NAME="myVMName$RANDOM_ID"
-export MY_VM_ID_NAME="myVMIDName$RANDOM_ID"
-export MY_VM_IMAGE='Ubuntu2204'
-export MY_VM_USERNAME="azureuser"
-export MY_VM_SIZE='Standard_DS2_v2'
-export MY_VNET_NAME="myVNet$RANDOM_ID"
-export MY_VM_NIC_NAME="myVMNicName$RANDOM_ID"
-export MY_NSG_SSH_RULE="Allow-Access$RANDOM_ID"
-export MY_VM_NIC_NAME="myVMNicName$RANDOM_ID"
-export MY_VNET_PREFIX="10.$NETWORK_PREFIX.0.0/16"
-export MY_SN_NAME="mySN$RANDOM_ID"
-export MY_SN_PREFIX="10.$NETWORK_PREFIX.0.0/24"
-export MY_PUBLIC_IP_NAME="myPublicIP$RANDOM_ID"
-export MY_DNS_LABEL="mydnslabel$RANDOM_ID"
-export MY_NSG_NAME="myNSGName$RANDOM_ID"
-export FQDN="${MY_DNS_LABEL}.${REGION}.cloudapp.azure.com"
-```
-
-## Create a Resource Group
-
-Before you can create a secure Linux VM, create a resource group with az group create. The following example creates a resource group equal to the contents of the variable *MY_RESOURCE_GROUP_NAME* in the location specified by the variable contents *REGION*:
-
-```bash
-az group create \
- --name $MY_RESOURCE_GROUP_NAME \
- --location $REGION -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f",
- "location": "eastus",
- "managedBy": null,
- "name": "myResourceGroupb1404f",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Set up VM Network
-
-Use az network vnet create to create a virtual network named *$MY_VNET_NAME* with a subnet named *$MY_SN_NAME*in the *$MY_RESOURCE_GROUP_NAME*resource group.
-
-```bash
-az network vnet create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_VNET_NAME \
- --location $REGION \
- --address-prefix $MY_VNET_PREFIX \
- --subnet-name $MY_SN_NAME \
- --subnet-prefix $MY_SN_PREFIX -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "newVNet": {
- "addressSpace": {
- "addressPrefixes": [
- "10.168.0.0/16"
- ]
- },
- "bgpCommunities": null,
- "ddosProtectionPlan": null,
- "dhcpOptions": {
- "dnsServers": []
- },
- "enableDdosProtection": false,
- "enableVmProtection": null,
- "encryption": null,
- "extendedLocation": null,
- "flowTimeoutInMinutes": null,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/virtualNetworks/myVNetb1404f",
- "ipAllocations": null,
- "location": "eastus",
- "name": "myVNetb1404f",
- "provisioningState": "Succeeded",
- "resourceGroup": "myResourceGroupb1404f",
- "subnets": [
- {
- "addressPrefix": "10.168.0.0/24",
- "addressPrefixes": null,
- "applicationGatewayIpConfigurations": null,
- "delegations": [],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/virtualNetworks/myVNetb1404f/subnets/mySNb1404f",
- "ipAllocations": null,
- "ipConfigurationProfiles": null,
- "ipConfigurations": null,
- "name": "mySNb1404f",
- "natGateway": null,
- "networkSecurityGroup": null,
- "privateEndpointNetworkPolicies": "Disabled",
- "privateEndpoints": null,
- "privateLinkServiceNetworkPolicies": "Enabled",
- "provisioningState": "Succeeded",
- "purpose": null,
- "resourceGroup": "myResourceGroupb1404f",
- "resourceNavigationLinks": null,
- "routeTable": null,
- "serviceAssociationLinks": null,
- "serviceEndpointPolicies": null,
- "serviceEndpoints": null,
- "type": "Microsoft.Network/virtualNetworks/subnets"
- }
- ],
- "tags": {},
- "type": "Microsoft.Network/virtualNetworks",
- "virtualNetworkPeerings": []
- }
-}
-```
-
-Use az network public-ip create to create a standard zone-redundant public IPv4 address named *$MY_PUBLIC_IP_NAME* in *$MY_RESOURCE_GROUP_NAME*.
-
-```bash
-az network public-ip create \
- --name $MY_PUBLIC_IP_NAME \
- --location $REGION \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --dns-name $MY_DNS_LABEL \
- --sku Standard \
- --allocation-method static \
- --version IPv4 \
- --zone 1 2 3 -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "publicIp": {
- "ddosSettings": null,
- "deleteOption": null,
- "dnsSettings": {
- "domainNameLabel": "mydnslabelb1404f",
- "fqdn": "mydnslabelb1404f.eastus.cloudapp.azure.com",
- "reverseFqdn": null
- },
- "extendedLocation": null,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/publicIPAddresses/myPublicIPb1404f",
- "idleTimeoutInMinutes": 4,
- "ipAddress": "20.88.178.210",
- "ipConfiguration": null,
- "ipTags": [],
- "linkedPublicIpAddress": null,
- "location": "eastus",
- "migrationPhase": null,
- "name": "myPublicIPb1404f",
- "natGateway": null,
- "provisioningState": "Succeeded",
- "publicIpAddressVersion": "IPv4",
- "publicIpAllocationMethod": "Static",
- "publicIpPrefix": null,
- "resourceGroup": "myResourceGroupb1404f",
- "servicePublicIpAddress": null,
- "sku": {
- "name": "Standard",
- "tier": "Regional"
- },
- "tags": null,
- "type": "Microsoft.Network/publicIPAddresses",
- "zones": [
- "1",
- "2",
- "3"
- ]
- }
-}
-```
-
-Security rules in network security groups enable you to filter the type of network traffic that can flow in and out of virtual network subnets and network interfaces. To learn more about network security groups, see [Network security group overview](https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview).
-
-```bash
-az network nsg create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_NSG_NAME \
- --location $REGION -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "NewNSG": {
- "defaultSecurityRules": [
- {
- "access": "Allow",
- "description": "Allow inbound traffic from all VMs in VNET",
- "destinationAddressPrefix": "VirtualNetwork",
- "destinationAddressPrefixes": [],
- "destinationPortRange": "*",
- "destinationPortRanges": [],
- "direction": "Inbound",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/networkSecurityGroups/myNSGNameb1404f/defaultSecurityRules/AllowVnetInBound",
- "name": "AllowVnetInBound",
- "priority": 65000,
- "protocol": "*",
- "provisioningState": "Succeeded",
- "resourceGroup": "myResourceGroupb1404f",
- "sourceAddressPrefix": "VirtualNetwork",
- "sourceAddressPrefixes": [],
- "sourcePortRange": "*",
- "sourcePortRanges": [],
- "type": "Microsoft.Network/networkSecurityGroups/defaultSecurityRules"
- }
- ],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/networkSecurityGroups/myNSGNameb1404f",
- "location": "eastus",
- "name": "myNSGNameb1404f",
- "provisioningState": "Succeeded",
- "resourceGroup": "myResourceGroupb1404f",
- "securityRules": [],
- "type": "Microsoft.Network/networkSecurityGroups"
- }
-}
-```
-
-Open ports 22 (SSH), 80 (HTTP) and 443 (HTTPS) to allow SSH and Web traffic
-
-```bash
-az network nsg rule create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --nsg-name $MY_NSG_NAME \
- --name $MY_NSG_SSH_RULE \
- --access Allow \
- --protocol Tcp \
- --direction Inbound \
- --priority 100 \
- --source-address-prefix '*' \
- --source-port-range '*' \
- --destination-address-prefix '*' \
- --destination-port-range 22 80 443 -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "access": "Allow",
- "description": null,
- "destinationAddressPrefix": "*",
- "destinationAddressPrefixes": [],
- "destinationApplicationSecurityGroups": null,
- "destinationPortRange": null,
- "destinationPortRanges": [
- "22",
- "80",
- "443"
- ],
- "direction": "Inbound",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/networkSecurityGroups/myNSGNameb1404f/securityRules/MY_NSG_SSH_RULE",
- "name": "MY_NSG_SSH_RULE",
- "priority": 100,
- "protocol": "Tcp",
- "provisioningState": "Succeeded",
- "resourceGroup": "myResourceGroupb1404f",
- "sourceAddressPrefix": "*",
- "sourceAddressPrefixes": [],
- "sourceApplicationSecurityGroups": null,
- "sourcePortRange": "*",
- "sourcePortRanges": [],
- "type": "Microsoft.Network/networkSecurityGroups/securityRules"
-}
-```
-
-And finally create the Network Interface Card (NIC):
-
-```bash
-az network nic create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_VM_NIC_NAME \
- --location $REGION \
- --ip-forwarding false \
- --subnet $MY_SN_NAME \
- --vnet-name $MY_VNET_NAME \
- --network-security-group $MY_NSG_NAME \
- --public-ip-address $MY_PUBLIC_IP_NAME -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "NewNIC": {
- "auxiliaryMode": "None",
- "auxiliarySku": "None",
- "disableTcpStateTracking": false,
- "dnsSettings": {
- "appliedDnsServers": [],
- "dnsServers": []
- },
- "enableAcceleratedNetworking": false,
- "enableIPForwarding": false,
- "hostedWorkloads": [],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/networkInterfaces/myVMNicNameb1404f",
- "ipConfigurations": [
- {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/networkInterfaces/myVMNicNameb1404f/ipConfigurations/ipconfig1",
- "name": "ipconfig1",
- "primary": true,
- "privateIPAddress": "10.168.0.4",
- "privateIPAddressVersion": "IPv4",
- "privateIPAllocationMethod": "Dynamic",
- "provisioningState": "Succeeded",
- "resourceGroup": "myResourceGroupb1404f",
- "subnet": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/virtualNetworks/myVNetb1404f/subnets/mySNb1404f",
- "resourceGroup": "myResourceGroupb1404f"
- },
- "type": "Microsoft.Network/networkInterfaces/ipConfigurations"
- }
- ],
- "location": "eastus",
- "name": "myVMNicNameb1404f",
- "networkSecurityGroup": {
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.Network/networkSecurityGroups/myNSGNameb1404f",
- "resourceGroup": "myResourceGroupb1404f"
- },
- "nicType": "Standard",
- "provisioningState": "Succeeded",
- "resourceGroup": "myResourceGroupb1404f",
- "tapConfigurations": [],
- "type": "Microsoft.Network/networkInterfaces",
- "vnetEncryptionSupported": false
- }
-}
-```
-
-## Generate a certificate and store it in Azure Key Vault
-
-Azure Key Vault safeguards cryptographic keys and secrets, such as certificates or passwords. Key Vault helps streamline the certificate management process and enables you to maintain control of keys that access those certificates. You can create a self-signed certificate inside Key Vault, or upload an existing, trusted certificate that you already own. For this tutorial we'll create self-signed certificates inside the Key Vault and afterwards inject these certificates into a running VM. This process ensures that the most up-to-date certificates are installed on a web server during deployment.
-
-The following example creates an Azure Key Vault named *$MY_KEY_VAULT* in the chosen region *$REGION* with a retention policy of 7 days. This means once a secret, key, certificate, or key vault is deleted, it will remain recoverable for a configurable period of 7 to 90 calendar days.
-
-```bash
-az keyvault create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_KEY_VAULT \
- --location $REGION \
- --retention-days 7\
- --enabled-for-deployment true -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.KeyVault/vaults/myKeyVaultb1404f",
- "location": "eastus",
- "name": "myKeyVaultb1404f",
- "properties": {
- "accessPolicies": [
- {
- "applicationId": null,
- "permissions": {
- "certificates": [
- "all"
- ],
- "keys": [
- "all"
- ],
- "secrets": [
- "all"
- ],
- "storage": [
- "all"
- ]
- },
- "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
- }
- ],
- "createMode": null,
- "enablePurgeProtection": null,
- "enableRbacAuthorization": null,
- "enableSoftDelete": true,
- "enabledForDeployment": true,
- "enabledForDiskEncryption": null,
- "enabledForTemplateDeployment": null,
- "hsmPoolResourceId": null,
- "networkAcls": null,
- "privateEndpointConnections": null,
- "provisioningState": "Succeeded",
- "publicNetworkAccess": "Enabled",
- "sku": {
- "family": "A",
- "name": "standard"
- },
- "softDeleteRetentionInDays": 7,
- "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "vaultUri": "https://mykeyvaultb1404f.vault.azure.net/"
- },
- "resourceGroup": "myResourceGroupb1404f",
- "systemData": {
- "createdAt": "2023-09-18T12:25:55.208000+00:00",
- "createdBy": "example@microsoft.com",
- "createdByType": "User",
- "lastModifiedAt": "2023-09-18T12:25:55.208000+00:00",
- "lastModifiedBy": "example@microsoft.com",
- "lastModifiedByType": "User"
- },
- "tags": {},
- "type": "Microsoft.KeyVault/vaults"
-}
-```
-
-## Create a certificate and store in Azure key Vault
-
-Now let's generate a self-signed certificate with az keyvault certificate create that uses the default certificate policy:
-
-```bash
-az keyvault certificate create \
- --vault-name $MY_KEY_VAULT \
- --name $MY_CERT_NAME \
- --policy "$(az keyvault certificate get-default-policy)" -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "cancellationRequested": false,
- "csr": "MIICr...",
- "error": null,
- "id": "https://mykeyvault67a7ba.vault.azure.net/certificates/nginxcert67a7ba/pending",
- "issuerParameters": {
- "certificateTransparency": null,
- "certificateType": null,
- "name": "Self"
- },
- "name": "nginxcert67a7ba",
- "status": "completed",
- "statusDetails": null,
- "target": "https://mykeyvault67a7ba.vault.azure.net/certificates/nginxcert67a7ba"
-}
-```
-
-Finally, we need to prepare the certificate so it can be used during the VM create process. To do so we need to obtain the ID of the certificate with az keyvault secret list-versions, and convert the certificate with az vm secret format. The following example assigns the output of these commands to variables for ease of use in the next steps:
-
-```bash
-az identity create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_VM_ID_NAME -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroupb1404f/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myVMIDNameb1404f",
- "location": "eastus",
- "name": "myVMIDNameb1404f",
- "principalId": "e09ebfce-97f0-4aff-9abd-415ebd6f915c",
- "resourceGroup": "myResourceGroupb1404f",
- "tags": {},
- "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
-}
-```
-
-```bash
-MY_VM_PRINCIPALID=$(az identity show --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_VM_ID_NAME --query principalId -o tsv)
-
-az keyvault set-policy \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_KEY_VAULT \
- --object-id $MY_VM_PRINCIPALID \
- --secret-permissions get list \
- --certificate-permissions get list -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupb1404f/providers/Microsoft.KeyVault/vaults/myKeyVaultb1404f",
- "location": "eastus",
- "name": "myKeyVaultb1404f",
- "properties": {
- "accessPolicies": [
- {
- "applicationId": null,
- "objectId": "ceeb4e98-5831-4d9f-b8ba-2ee14b3cdf80",
- "permissions": {
- "certificates": [
- "all"
- ],
- "keys": [
- "all"
- ],
- "secrets": [
- "all"
- ],
- "storage": [
- "all"
- ]
- },
- "tenantId": "bd7153ee-d085-4a28-a928-2f0ef402f076"
- },
- {
- "applicationId": null,
- "objectId": "e09ebfce-97f0-4aff-9abd-415ebd6f915c",
- "permissions": {
- "certificates": [
- "list",
- "get"
- ],
- "keys": null,
- "secrets": [
- "list",
- "get"
- ],
- "storage": null
- },
- "tenantId": "bd7153ee-d085-4a28-a928-2f0ef402f076"
- }
- ],
- "createMode": null,
- "enablePurgeProtection": null,
- "enableRbacAuthorization": null,
- "enableSoftDelete": true,
- "enabledForDeployment": true,
- "enabledForDiskEncryption": null,
- "enabledForTemplateDeployment": null,
- "hsmPoolResourceId": null,
- "networkAcls": null,
- "privateEndpointConnections": null,
- "provisioningState": "Succeeded",
- "publicNetworkAccess": "Enabled",
- "sku": {
- "family": "A",
- "name": "standard"
- },
- "softDeleteRetentionInDays": 7,
- "tenantId": "bd7153ee-d085-4a28-a928-2f0ef402f076",
- "vaultUri": "https://mykeyvaultb1404f.vault.azure.net/"
- },
- "resourceGroup": "myResourceGroupb1404f",
- "systemData": {
- "createdAt": "2023-09-18T12:25:55.208000+00:00",
- "createdBy": "ajoian@microsoft.com",
- "createdByType": "User",
- "lastModifiedAt": "2023-09-18T12:48:08.966000+00:00",
- "lastModifiedBy": "ajoian@microsoft.com",
- "lastModifiedByType": "User"
- },
- "tags": {},
- "type": "Microsoft.KeyVault/vaults"
-}
-```
-
-## Create the VM
-
-Now create a VM with az vm create. Use the --custom-data parameter to pass in the cloud-init config file, named *cloud-init-nginx.txt*.
-Cloud-init is a widely used approach to customize a Linux VM as it boots for the first time. You can use cloud-init to install packages and write files, or to configure users and security. As cloud-init runs during the initial boot process, there are no extra steps or required agents to apply your configuration.
-When you create a VM, certificates and keys are stored in the protected /var/lib/waagent/ directory. In this example, we are installing and configuring the NGINX web server.
-
-```bash
-cat > cloud-init-nginx.txt </dev/null; echo "0 * * * * /root/convert_akv_cert.sh && service nginx reload") | crontab -
- - service nginx restart
-EOF
-```
-
-The following example creates a VM named *myVMName$UNIQUE_POSTFIX*:
-
-```bash
-MY_VM_ID=$(az identity show --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_VM_ID_NAME --query id -o tsv)
-
-az vm create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_VM_NAME \
- --image $MY_VM_IMAGE \
- --admin-username $MY_VM_USERNAME \
- --generate-ssh-keys \
- --assign-identity $MY_VM_ID \
- --size $MY_VM_SIZE \
- --custom-data cloud-init-nginx.txt \
- --nics $MY_VM_NIC_NAME
-```
-
-Results:
-
-
-```JSON
-{
- "fqdns": "mydnslabel67a7ba.eastus.cloudapp.azure.com",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup67a7ba/providers/Microsoft.Compute/virtualMachines/myVMName67a7ba",
- "identity": {
- "systemAssignedIdentity": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "userAssignedIdentities": {
- "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroup67a7ba/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myVMIDName67a7ba": {
- "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
- "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
- }
- }
- },
- "location": "eastus",
- "macAddress": "60-45-BD-D3-B5-29",
- "powerState": "VM running",
- "privateIpAddress": "10.56.0.4",
- "publicIpAddress": "20.231.118.239",
- "resourceGroup": "myResourceGroup67a7ba",
- "zones": ""
-}
-```
-
-## Deploying AKV extension for VM $vm_name to retrieve cert $cert_name from AKV $akv_name..."
-
-```bash
-MY_CERT_ID=$(az keyvault certificate show --vault-name $MY_KEY_VAULT --name $MY_CERT_NAME --query sid -o tsv)
-MY_VM_CLIENTID=$(az identity show --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_VM_ID_NAME --query clientId -o tsv)
-MY_AKV_EXT_SETTINGS="{\"secretsManagementSettings\":{\"pollingIntervalInS\":\"3600\",\"requireInitialSync\":"true",\"certificateStoreLocation\":\"/etc/nginx/ssl/\",\"observedCertificates\":[\"$MY_CERT_ID\"]},\"authenticationSettings\":{\"msiClientId\":\"${MY_VM_CLIENTID}\"}}"
-
-az vm extension set \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --vm-name $MY_VM_NAME \
- -n "KeyVaultForLinux" \
- --publisher Microsoft.Azure.KeyVault \
- --version 2.0 \
- --enable-auto-upgrade true \
- --settings $MY_AKV_EXT_SETTINGS -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "autoUpgradeMinorVersion": true,
- "enableAutomaticUpgrade": true,
- "forceUpdateTag": null,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup67a7ba/providers/Microsoft.Compute/virtualMachines/myVMName67a7ba/extensions/KeyVaultForLinux",
- "instanceView": null,
- "location": "eastus",
- "name": "KeyVaultForLinux",
- "protectedSettings": null,
- "protectedSettingsFromKeyVault": null,
- "provisioningState": "Succeeded",
- "publisher": "Microsoft.Azure.KeyVault",
- "resourceGroup": "myResourceGroup67a7ba",
- "settings": {
- "secretsManagementSettings": {
- "certificateStoreLocation": "/etc/nginx/ssl",
- "observedCertificates": [
- "https://mykeyvault67a7ba.vault.azure.net/secrets/nginxcert67a7ba/aac9b30a90c04fc58bc230ae15b1148f"
- ],
- "pollingIntervalInS": "3600"
- }
- },
- "suppressFailures": null,
- "tags": null,
- "type": "Microsoft.Compute/virtualMachines/extensions",
- "typeHandlerVersion": "2.0",
- "typePropertiesType": "KeyVaultForLinux"
-}
-```
-
-## Enable Azure AD login for a Linux Virtual Machine in Azure
-
-The following example deploys a VM and then installs the extension to enable Azure AD login for a Linux VM. VM extensions are small applications that provide post-deployment configuration and automation tasks on Azure virtual machines.
-
-```bash
-az vm extension set \
- --publisher Microsoft.Azure.ActiveDirectory \
- --name AADSSHLoginForLinux \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --vm-name $MY_VM_NAME -o JSON
-```
-
-Results:
-
-
-```JSON
-{
- "autoUpgradeMinorVersion": true,
- "enableAutomaticUpgrade": null,
- "forceUpdateTag": null,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupfa636b/providers/Microsoft.Compute/virtualMachines/myVMNamefa636b/extensions/AADSSHLoginForLinux",
- "instanceView": null,
- "location": "eastus",
- "name": "AADSSHLoginForLinux",
- "protectedSettings": null,
- "protectedSettingsFromKeyVault": null,
- "provisioningState": "Succeeded",
- "publisher": "Microsoft.Azure.ActiveDirectory",
- "resourceGroup": "myResourceGroupfa636b",
- "settings": null,
- "suppressFailures": null,
- "tags": null,
- "type": "Microsoft.Compute/virtualMachines/extensions",
- "typeHandlerVersion": "1.0",
- "typePropertiesType": "AADSSHLoginForLinux"
-}
-```
-
-## Browse your secure website
-
-Validate that the application is running by visiting the application url:
-
-```bash
-curl --max-time 120 -k "https://$FQDN"
-```
-
-Results:
-
-
-```html
-
-
-
-Welcome to nginx!
-
-
-
-
Welcome to nginx!
-
If you see this page, the nginx web server is successfully installed and
-working. Further configuration is required.
-
-
For online documentation and support please refer to
-nginx.org.
-Commercial support is available at
-nginx.com.
-
-
Thank you for using nginx.
-
-
-```
diff --git a/scenarios/ocd/CreateStaticWebApp/README.md b/scenarios/ocd/CreateStaticWebApp/README.md
deleted file mode 100644
index 6030270b..00000000
--- a/scenarios/ocd/CreateStaticWebApp/README.md
+++ /dev/null
@@ -1,134 +0,0 @@
-# Azure Static Web Apps Quickstart: Building Your First Static Site Using the Azure CLI
-
-Azure Static Web Apps publishes websites to production by building apps from a code repository. In this quickstart, you deploy a web application to Azure Static Web Apps using the Azure CLI.
-
-## Define Environment Variables
-
-The First step in this tutorial is to define environment variables.
-
-```bash
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myStaticWebAppResourceGroup$RANDOM_ID"
-export REGION=EastUS2
-export MY_STATIC_WEB_APP_NAME="myStaticWebApp$RANDOM_ID"
-```
-
-## Create a Repository (optional)
-
-(Optional) This article uses a GitHub template repository as another way to make it easy for you to get started. The template features a starter app to deploy to Azure Static Web Apps.
-
-- Navigate to the following location to create a new repository: https://github.com/staticwebdev/vanilla-basic/generate
-- Name your repository `my-first-static-web-app`
-
-> **Note:** Azure Static Web Apps requires at least one HTML file to create a web app. The repository you create in this step includes a single `index.html` file.
-
-Select `Create repository`.
-
-## Deploy a Static Web App
-
-You can deploy the app as a static web app from the Azure CLI.
-
-1. Create a resource group.
-
-```bash
-az group create \
- --name $MY_RESOURCE_GROUP_NAME \
- --location $REGION
-```
-
-Results:
-
-
-```json
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/my-swa-group",
- "location": "eastus2",
- "managedBy": null,
- "name": "my-swa-group",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-2. Deploy a new static web app from your repository.
-
-```bash
-az staticwebapp create \
- --name $MY_STATIC_WEB_APP_NAME \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION
-```
-
-There are two aspects to deploying a static app. The first operation creates the underlying Azure resources that make up your app. The second is a workflow that builds and publishes your application.
-
-Before you can go to your new static site, the deployment build must first finish running.
-
-3. Return to your console window and run the following command to list the website's URL.
-
-```bash
-export MY_STATIC_WEB_APP_URL=$(az staticwebapp show --name $MY_STATIC_WEB_APP_NAME --resource-group $MY_RESOURCE_GROUP_NAME --query "defaultHostname" -o tsv)
-```
-
-```bash
-runtime="1 minute";
-endtime=$(date -ud "$runtime" +%s);
-while [[ $(date -u +%s) -le $endtime ]]; do
- if curl -I -s $MY_STATIC_WEB_APP_URL > /dev/null ; then
- curl -L -s $MY_STATIC_WEB_APP_URL 2> /dev/null | head -n 9
- break
- else
- sleep 10
- fi;
-done
-```
-
-Results:
-
-
-```HTML
-
-
-
-
-
-
-Azure Static Web Apps - Welcome
-
-
-```
-
-```bash
-echo "You can now visit your web server at https://$MY_STATIC_WEB_APP_URL"
-```
-
-## Next Steps
-
-Congratulations! You have successfully deployed a static web app to Azure Static Web Apps using the Azure CLI. Now that you have a basic understanding of how to deploy a static web app, you can explore more advanced features and functionality of Azure Static Web Apps.
-
-In case you want to use the GitHub template repository, follow the additional steps below.
-
-Go to https://github.com/login/device and enter the user code 329B-3945 to activate and retrieve your GitHub personal access token.
-
-1. Go to https://github.com/login/device.
-2. Enter the user code as displayed your console's message.
-3. Select `Continue`.
-4. Select `Authorize AzureAppServiceCLI`.
-
-### View the Website via Git
-
-1. As you get the repository URL while running the script, copy the repository URL and paste it into your browser.
-2. Select the `Actions` tab.
-
- At this point, Azure is creating the resources to support your static web app. Wait until the icon next to the running workflow turns into a check mark with green background ( ). This operation may take a few minutes to complete.
-
-3. Once the success icon appears, the workflow is complete and you can return back to your console window.
-4. Run the following command to query for your website's URL.
-
- az staticwebapp show \
- --name $MY_STATIC_WEB_APP_NAME \
- --query "defaultHostname"
-
-5. Copy the URL into your browser to go to your website.
\ No newline at end of file
diff --git a/scenarios/ocd/CreateWordPressDeployment/README.md b/scenarios/ocd/CreateWordPressDeployment/README.md
deleted file mode 100644
index 75d862de..00000000
--- a/scenarios/ocd/CreateWordPressDeployment/README.md
+++ /dev/null
@@ -1,510 +0,0 @@
-# Quickstart: Deploy a Scalable & Secure WordPress instance on AKS
-
-Welcome to this tutorial where we will take you step by step in creating an Azure Kubernetes Web Application that is secured via https. This tutorial assumes you are logged into Azure CLI already and have selected a subscription to use with the CLI. It also assumes that you have Helm installed ([Instructions can be found here](https://helm.sh/docs/intro/install/)).
-
-## Define Environment Variables
-
-The first step in this tutorial is to define environment variables.
-
-```bash
-export SSL_EMAIL_ADDRESS="$(az account show --query user.name --output tsv)"
-export NETWORK_PREFIX="$(($RANDOM % 253 + 1))"
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myWordPressAKSResourceGroup$RANDOM_ID"
-export REGION="eastus"
-export MY_AKS_CLUSTER_NAME="myAKSCluster$RANDOM_ID"
-export MY_PUBLIC_IP_NAME="myPublicIP$RANDOM_ID"
-export MY_DNS_LABEL="mydnslabel$RANDOM_ID"
-export MY_VNET_NAME="myVNet$RANDOM_ID"
-export MY_VNET_PREFIX="10.$NETWORK_PREFIX.0.0/16"
-export MY_SN_NAME="mySN$RANDOM_ID"
-export MY_SN_PREFIX="10.$NETWORK_PREFIX.0.0/22"
-export MY_MYSQL_DB_NAME="mydb$RANDOM_ID"
-export MY_MYSQL_ADMIN_USERNAME="dbadmin$RANDOM_ID"
-export MY_MYSQL_ADMIN_PW="$(openssl rand -base64 32)"
-export MY_MYSQL_SN_NAME="myMySQLSN$RANDOM_ID"
-export MY_MYSQL_HOSTNAME="$MY_MYSQL_DB_NAME.mysql.database.azure.com"
-export MY_WP_ADMIN_PW="$(openssl rand -base64 32)"
-export MY_WP_ADMIN_USER="wpcliadmin"
-export FQDN="${MY_DNS_LABEL}.${REGION}.cloudapp.azure.com"
-```
-
-## Create a resource group
-
-A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $MY_RESOURCE_GROUP_NAME and $REGION parameters.
-
-```bash
-az group create \
- --name $MY_RESOURCE_GROUP_NAME \
- --location $REGION
-```
-
-Results:
-
-
-```json
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX",
- "location": "eastus",
- "managedBy": null,
- "name": "testResourceGroup",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Create a virtual network and subnet
-
-A virtual network is the fundamental building block for private networks in Azure. Azure Virtual Network enables Azure resources like VMs to securely communicate with each other and the internet.
-
-```bash
-az network vnet create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --location $REGION \
- --name $MY_VNET_NAME \
- --address-prefix $MY_VNET_PREFIX \
- --subnet-name $MY_SN_NAME \
- --subnet-prefixes $MY_SN_PREFIX
-```
-
-Results:
-
-
-```json
-{
- "newVNet": {
- "addressSpace": {
- "addressPrefixes": [
- "10.210.0.0/16"
- ]
- },
- "enableDdosProtection": false,
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/myWordPressAKSResourceGroupXXX/providers/Microsoft.Network/virtualNetworks/myVNetXXX",
- "location": "eastus",
- "name": "myVNet210",
- "provisioningState": "Succeeded",
- "resourceGroup": "myWordPressAKSResourceGroupXXX",
- "subnets": [
- {
- "addressPrefix": "10.210.0.0/22",
- "delegations": [],
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/myWordPressAKSResourceGroupXXX/providers/Microsoft.Network/virtualNetworks/myVNetXXX/subnets/mySNXXX",
- "name": "mySN210",
- "privateEndpointNetworkPolicies": "Disabled",
- "privateLinkServiceNetworkPolicies": "Enabled",
- "provisioningState": "Succeeded",
- "resourceGroup": "myWordPressAKSResourceGroupXXX",
- "type": "Microsoft.Network/virtualNetworks/subnets"
- }
- ],
- "type": "Microsoft.Network/virtualNetworks",
- "virtualNetworkPeerings": []
- }
-}
-```
-
-## Create an Azure Database for MySQL - Flexible Server
-
-Azure Database for MySQL - Flexible Server is a managed service that you can use to run, manage, and scale highly available MySQL servers in the cloud. Create a flexible server with the [az mysql flexible-server create](https://learn.microsoft.com/cli/azure/mysql/flexible-server#az-mysql-flexible-server-create) command. A server can contain multiple databases. The following command creates a server using service defaults and variable values from your Azure CLI's local environment:
-
-```bash
-echo "Your MySQL user $MY_MYSQL_ADMIN_USERNAME password is: $MY_WP_ADMIN_PW"
-```
-
-```bash
-az mysql flexible-server create \
- --admin-password $MY_MYSQL_ADMIN_PW \
- --admin-user $MY_MYSQL_ADMIN_USERNAME \
- --auto-scale-iops Disabled \
- --high-availability Disabled \
- --iops 500 \
- --location $REGION \
- --name $MY_MYSQL_DB_NAME \
- --database-name wordpress \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --sku-name Standard_B2s \
- --storage-auto-grow Disabled \
- --storage-size 20 \
- --subnet $MY_MYSQL_SN_NAME \
- --private-dns-zone $MY_DNS_LABEL.private.mysql.database.azure.com \
- --tier Burstable \
- --version 8.0.21 \
- --vnet $MY_VNET_NAME \
- --yes -o JSON
-```
-
-Results:
-
-
-```json
-{
- "databaseName": "wordpress",
- "host": "mydbxxx.mysql.database.azure.com",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX/providers/Microsoft.DBforMySQL/flexibleServers/mydbXXX",
- "location": "East US",
- "resourceGroup": "myWordPressAKSResourceGroupXXX",
- "skuname": "Standard_B2s",
- "subnetId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX/providers/Microsoft.Network/virtualNetworks/myVNetXXX/subnets/myMySQLSNXXX",
- "username": "dbadminxxx",
- "version": "8.0.21"
-}
-```
-
-The server created has the below attributes:
-
-- The server name, admin username, admin password, resource group name, location are already specified in local context environment of the cloud shell, and will be created in the same location as your the resource group and the other Azure components.
-- Service defaults for remaining server configurations: compute tier (Burstable), compute size/SKU (Standard_B2s), backup retention period (7 days), and MySQL version (8.0.21)
-- The default connectivity method is Private access (VNet Integration) with a linked virtual network and a auto-generated subnet.
-
-> [!NOTE]
-> The connectivity method cannot be changed after creating the server. For example, if you selected `Private access (VNet Integration)` during create then you cannot change to `Public access (allowed IP addresses)` after create. We highly recommend creating a server with Private access to securely access your server using VNet Integration. Learn more about Private access in the [concepts article](https://learn.microsoft.com/azure/mysql/flexible-server/concepts-networking-vnet).
-
-If you'd like to change any defaults, please refer to the Azure CLI [reference documentation](https://learn.microsoft.com/cli/azure//mysql/flexible-server) for the complete list of configurable CLI parameters.
-
-## Check the Azure Database for MySQL - Flexible Server status
-
-It takes a few minutes to create the Azure Database for MySQL - Flexible Server and supporting resources.
-
-```bash
-runtime="10 minute"; endtime=$(date -ud "$runtime" +%s); while [[ $(date -u +%s) -le $endtime ]]; do STATUS=$(az mysql flexible-server show -g $MY_RESOURCE_GROUP_NAME -n $MY_MYSQL_DB_NAME --query state -o tsv); echo $STATUS; if [ "$STATUS" = 'Ready' ]; then break; else sleep 10; fi; done
-```
-
-## Configure server parameters in Azure Database for MySQL - Flexible Server
-
-You can manage Azure Database for MySQL - Flexible Server configuration using server parameters. The server parameters are configured with the default and recommended value when you create the server.
-
-Show server parameter details
-To show details about a particular parameter for a server, run the [az mysql flexible-server parameter show](https://learn.microsoft.com/cli/azure/mysql/flexible-server/parameter) command.
-
-### Disable Azure Database for MySQL - Flexible Server SSL connection parameter for WordPress integration
-
-You can also modify the value of certain server parameters, which updates the underlying configuration values for the MySQL server engine. To update the server parameter, use the [az mysql flexible-server parameter set](https://learn.microsoft.com/cli/azure/mysql/flexible-server/parameter#az-mysql-flexible-server-parameter-set) command.
-
-```bash
-az mysql flexible-server parameter set \
- -g $MY_RESOURCE_GROUP_NAME \
- -s $MY_MYSQL_DB_NAME \
- -n require_secure_transport -v "OFF" -o JSON
-```
-
-Results:
-
-
-```json
-{
- "allowedValues": "ON,OFF",
- "currentValue": "OFF",
- "dataType": "Enumeration",
- "defaultValue": "ON",
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX/providers/Microsoft.DBforMySQL/flexibleServers/mydbXXX/configurations/require_secure_transport",
- "isConfigPendingRestart": "False",
- "isDynamicConfig": "True",
- "isReadOnly": "False",
- "name": "require_secure_transport",
- "resourceGroup": "myWordPressAKSResourceGroupXXX",
- "source": "user-override",
- "systemData": null,
- "type": "Microsoft.DBforMySQL/flexibleServers/configurations",
- "value": "OFF"
-}
-```
-
-## Create AKS Cluster
-
-Create an AKS cluster using the az aks create command with the --enable-addons monitoring parameter to enable Container insights. The following example creates an autoscaling, availability zone enabled cluster named myAKSCluster:
-
-This will take a few minutes
-
-```bash
-export MY_SN_ID=$(az network vnet subnet list --resource-group $MY_RESOURCE_GROUP_NAME --vnet-name $MY_VNET_NAME --query "[0].id" --output tsv)
-
-az aks create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_AKS_CLUSTER_NAME \
- --auto-upgrade-channel stable \
- --enable-cluster-autoscaler \
- --enable-addons monitoring \
- --location $REGION \
- --node-count 1 \
- --min-count 1 \
- --max-count 3 \
- --network-plugin azure \
- --network-policy azure \
- --vnet-subnet-id $MY_SN_ID \
- --no-ssh-key \
- --node-vm-size Standard_DS2_v2 \
- --service-cidr 10.255.0.0/24 \
- --dns-service-ip 10.255.0.10 \
- --zones 1 2 3
-```
-
-## Connect to the cluster
-
-To manage a Kubernetes cluster, use the Kubernetes command-line client, kubectl. kubectl is already installed if you use Azure Cloud Shell.
-
-1. Install az aks CLI locally using the az aks install-cli command
-
- ```bash
- if ! [ -x "$(command -v kubectl)" ]; then az aks install-cli; fi
- ```
-
-2. Configure kubectl to connect to your Kubernetes cluster using the az aks get-credentials command. The following command:
-
- - Downloads credentials and configures the Kubernetes CLI to use them.
- - Uses ~/.kube/config, the default location for the Kubernetes configuration file. Specify a different location for your Kubernetes configuration file using --file argument.
-
- > [!WARNING]
- > This will overwrite any existing credentials with the same entry
-
- ```bash
- az aks get-credentials --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_AKS_CLUSTER_NAME --overwrite-existing
- ```
-
-3. Verify the connection to your cluster using the kubectl get command. This command returns a list of the cluster nodes.
-
- ```bash
- kubectl get nodes
- ```
-
-## Install NGINX Ingress Controller
-
-You can configure your ingress controller with a static public IP address. The static public IP address remains if you delete your ingress controller. The IP address doesn't remain if you delete your AKS cluster.
-When you upgrade your ingress controller, you must pass a parameter to the Helm release to ensure the ingress controller service is made aware of the load balancer that will be allocated to it. For the HTTPS certificates to work correctly, you use a DNS label to configure an FQDN for the ingress controller IP address.
-Your FQDN should follow this form: $MY_DNS_LABEL.AZURE_REGION_NAME.cloudapp.azure.com.
-
-```bash
-export MY_STATIC_IP=$(az network public-ip create --resource-group MC_${MY_RESOURCE_GROUP_NAME}_${MY_AKS_CLUSTER_NAME}_${REGION} --location ${REGION} --name ${MY_PUBLIC_IP_NAME} --dns-name ${MY_DNS_LABEL} --sku Standard --allocation-method static --version IPv4 --zone 1 2 3 --query publicIp.ipAddress -o tsv)
-```
-
-Add the --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="" parameter. The DNS label can be set either when the ingress controller is first deployed, or it can be configured later. Add the --set controller.service.loadBalancerIP="" parameter. Specify your own public IP address that was created in the previous step.
-
-1. Add the ingress-nginx Helm repository
-
- ```bash
- helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
- ```
-
-2. Update local Helm Chart repository cache
-
- ```bash
- helm repo update
- ```
-
-3. Install ingress-nginx addon via Helm by running the following:
-
- ```bash
- helm upgrade --install --cleanup-on-fail --atomic ingress-nginx ingress-nginx/ingress-nginx \
- --namespace ingress-nginx \
- --create-namespace \
- --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$MY_DNS_LABEL \
- --set controller.service.loadBalancerIP=$MY_STATIC_IP \
- --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
- --wait --timeout 10m0s
- ```
-
-## Add HTTPS termination to custom domain
-
-At this point in the tutorial you have an AKS web app with NGINX as the Ingress controller and a custom domain you can use to access your application. The next step is to add an SSL certificate to the domain so that users can reach your application securely via https.
-
-## Set Up Cert Manager
-
-In order to add HTTPS we are going to use Cert Manager. Cert Manager is an open source tool used to obtain and manage SSL certificate for Kubernetes deployments. Cert Manager will obtain certificates from a variety of Issuers, both popular public Issuers as well as private Issuers, and ensure the certificates are valid and up-to-date, and will attempt to renew certificates at a configured time before expiry.
-
-1. In order to install cert-manager, we must first create a namespace to run it in. This tutorial will install cert-manager into the cert-manager namespace. It is possible to run cert-manager in a different namespace, although you will need to make modifications to the deployment manifests.
-
- ```bash
- kubectl create namespace cert-manager
- ```
-
-2. We can now install cert-manager. All resources are included in a single YAML manifest file. This can be installed by running the following:
-
- ```bash
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.0/cert-manager.crds.yaml
- ```
-
-3. Add the certmanager.k8s.io/disable-validation: "true" label to the cert-manager namespace by running the following. This will allow the system resources that cert-manager requires to bootstrap TLS to be created in its own namespace.
-
- ```bash
- kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
- ```
-
-## Obtain certificate via Helm Charts
-
-Helm is a Kubernetes deployment tool for automating creation, packaging, configuration, and deployment of applications and services to Kubernetes clusters.
-
-Cert-manager provides Helm charts as a first-class method of installation on Kubernetes.
-
-1. Add the Jetstack Helm repository
-
- This repository is the only supported source of cert-manager charts. There are some other mirrors and copies across the internet, but those are entirely unofficial and could present a security risk.
-
- ```bash
- helm repo add jetstack https://charts.jetstack.io
- ```
-
-2. Update local Helm Chart repository cache
-
- ```bash
- helm repo update
- ```
-
-3. Install Cert-Manager addon via Helm by running the following:
-
- ```bash
- helm upgrade --install --cleanup-on-fail --atomic \
- --namespace cert-manager \
- --version v1.7.0 \
- --wait --timeout 10m0s \
- cert-manager jetstack/cert-manager
- ```
-
-4. Apply Certificate Issuer YAML File
-
- ClusterIssuers are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request.
- The issuer we are using can be found in the `cluster-issuer-prod.yml file`
-
- ```bash
- cluster_issuer_variables=$(
-```text
-Release "wordpress" does not exist. Installing it now.
-NAME: wordpress
-LAST DEPLOYED: Tue Oct 24 16:19:35 2023
-NAMESPACE: wordpress
-STATUS: deployed
-REVISION: 1
-TEST SUITE: None
-NOTES:
-CHART NAME: wordpress
-CHART VERSION: 18.0.8
-APP VERSION: 6.3.2
-
-** Please be patient while the chart is being deployed **
-
-Your WordPress site can be accessed through the following DNS name from within your cluster:
-
- wordpress.wordpress.svc.cluster.local (port 80)
-
-To access your WordPress site from outside the cluster follow the steps below:
-
-1. Get the WordPress URL and associate WordPress hostname to your cluster external IP:
-
- export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters
- echo "WordPress URL: https://mydnslabelxxx.eastus.cloudapp.azure.com/"
- echo "$CLUSTER_IP mydnslabelxxx.eastus.cloudapp.azure.com" | sudo tee -a /etc/hosts
- export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters
- echo "WordPress URL: https://mydnslabelxxx.eastus.cloudapp.azure.com/"
- echo "$CLUSTER_IP mydnslabelxxx.eastus.cloudapp.azure.com" | sudo tee -a /etc/hosts
-
-2. Open a browser and access WordPress using the obtained URL.
-
-3. Login with the following credentials below to see your blog:
-
- echo Username: wpcliadmin
- echo Password: $(kubectl get secret --namespace wordpress wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d)
-```
-
-## Browse your AKS Deployment Secured via HTTPS
-
-Run the following command to get the HTTPS endpoint for your application:
-
-> [!NOTE]
-> It often takes 2-3 minutes for the SSL certificate to propogate and about 5 minutes to have all WordPress POD replicas ready and the site to be fully reachable via https.
-
-```bash
-runtime="5 minute"
-endtime=$(date -ud "$runtime" +%s)
-while [[ $(date -u +%s) -le $endtime ]]; do
- export DEPLOYMENT_REPLICAS=$(kubectl -n wordpress get deployment wordpress -o=jsonpath='{.status.availableReplicas}');
- echo Current number of replicas "$DEPLOYMENT_REPLICAS/3";
- if [ "$DEPLOYMENT_REPLICAS" = "3" ]; then
- break;
- else
- sleep 10;
- fi;
-done
-```
-
-Checking that WordPress content is being delivered correctly.
-
-```bash
-if curl -I -s -f https://$FQDN > /dev/null ; then
- curl -L -s -f https://$FQDN 2> /dev/null | head -n 9
-else
- exit 1
-fi;
-```
-
-Results:
-
-
-```HTML
-{
-
-
-
-
-
-
-WordPress on AKS
-
-
-}
-```
-
-The website can be visited by following the URL below:
-
-```bash
-echo "You can now visit your web server at https://$FQDN"
-```
diff --git a/scenarios/ocd/CreateWordPressDeployment/cluster-issuer-prod.yaml b/scenarios/ocd/CreateWordPressDeployment/cluster-issuer-prod.yaml
deleted file mode 100644
index e4a37bab..00000000
--- a/scenarios/ocd/CreateWordPressDeployment/cluster-issuer-prod.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#kubectl apply -f - <> /bitnami/wordpress/wp-config.php
- wp total-cache option set pgcache.engine memcached --type=string
- wp total-cache flush all
- wp total-cache option set pgcache.memcached.servers wordpress-memcached.wordpress.svc.cluster.local:11211 --type=string
- wp total-cache option set pgcache.enabled true --type=boolean
- wp total-cache flush all
- chmod a-w /bitnami/wordpress/wp-config.php
-service:
- type: ClusterIP
-ingress:
- enabled: true
- tls: true
- certManager: true
-# hostname: 'FQDN'
- annotations:
- kubernetes.io/ingress.class: nginx
- cert-manager.io/cluster-issuer: letsencrypt-prod
-resources:
- requests:
- cpu: 500m
- memory: 32Mi
- limits:
- memory: 128Mi
-wordpressConfigureCache: true
-memcached:
- enabled: true
- replicaCount: 1
- resources:
- requests:
- cpu: 500m
- memory: 128Mi
- limits:
- cpu: 500m
- memory: 128Mi
-# https://github.com/bitnami/charts/issues/16332
-# https://github.com/nextcloud/helm/issues/399
-livenessProbe:
- initialDelaySeconds: 60
- failureThreshold: 60
-readinessProbe:
- initialDelaySeconds: 60
- failureThreshold: 60
-startupProbe:
- initialDelaySeconds: 60
- failureThreshold: 60
diff --git a/scenarios/ocd/CreateWordPressDeployment/wp-azurefiles-sc.yaml b/scenarios/ocd/CreateWordPressDeployment/wp-azurefiles-sc.yaml
deleted file mode 100644
index 6dc69326..00000000
--- a/scenarios/ocd/CreateWordPressDeployment/wp-azurefiles-sc.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-apiVersion: storage.k8s.io/v1
-kind: StorageClass
-metadata:
- name: wp-azurefile-sc
-provisioner: file.csi.azure.com
-parameters:
- skuName: Premium_LRS
- enableMultichannel: "true"
- useDataPlaneAPI: "true"
-reclaimPolicy: Delete
-mountOptions:
- - dir_mode=0755
- - file_mode=0755
- - forceuid
- - forcegid
- - uid=1001
- - gid=1001
- - mfsymlinks
- - cache=strict
- - nosharesock
- - actimeo=30
- - vers=3.1.1
- - nobrl
- - noatime
- - multichannel
- - max_channels=4
-allowVolumeExpansion: true
-volumeBindingMode: WaitForFirstConsumer
diff --git a/scenarios/ocd/DeployIGonAKS/README.md b/scenarios/ocd/DeployIGonAKS/README.md
deleted file mode 100644
index c4aa7e1b..00000000
--- a/scenarios/ocd/DeployIGonAKS/README.md
+++ /dev/null
@@ -1,168 +0,0 @@
-# Quickstart: Deploy Inspektor Gadget in an Azure Kubernetes Service cluster
-
-Welcome to this tutorial where we will take you step by step in deploying [Inspektor Gadget](https://www.inspektor-gadget.io/) in an Azure Kubernetes Service (AKS) cluster with the kubectl plugin: `gadget`. This tutorial assumes you are logged into Azure CLI already and have selected a subscription to use with the CLI.
-
-## Define Environment Variables
-
-The First step in this tutorial is to define environment variables:
-
-```bash
-export RANDOM_ID="$(openssl rand -hex 3)"
-export MY_RESOURCE_GROUP_NAME="myResourceGroup$RANDOM_ID"
-export REGION="eastus"
-export MY_AKS_CLUSTER_NAME="myAKSCluster$RANDOM_ID"
-```
-
-## Create a resource group
-
-A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $MY_RESOURCE_GROUP_NAME and $REGION parameters.
-
-```bash
-az group create --name $MY_RESOURCE_GROUP_NAME --location $REGION
-```
-
-Results:
-
-
-```JSON
-{
- "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup210",
- "location": "eastus",
- "managedBy": null,
- "name": "testResourceGroup",
- "properties": {
- "provisioningState": "Succeeded"
- },
- "tags": null,
- "type": "Microsoft.Resources/resourceGroups"
-}
-```
-
-## Create AKS Cluster
-
-Create an AKS cluster using the az aks create command.
-
-This will take a few minutes.
-
-```bash
-az aks create \
- --resource-group $MY_RESOURCE_GROUP_NAME \
- --name $MY_AKS_CLUSTER_NAME \
- --location $REGION \
- --no-ssh-key
-```
-
-## Connect to the cluster
-
-To manage a Kubernetes cluster, use the Kubernetes command-line client, kubectl. kubectl is already installed if you use Azure Cloud Shell.
-
-1. Install az aks CLI locally using the az aks install-cli command
-
- ```bash
- if ! [ -x "$(command -v kubectl)" ]; then az aks install-cli; fi
- ```
-
-2. Configure kubectl to connect to your Kubernetes cluster using the az aks get-credentials command. The following command:
- - Downloads credentials and configures the Kubernetes CLI to use them.
- - Uses ~/.kube/config, the default location for the Kubernetes configuration file. Specify a different location for your Kubernetes configuration file using --file argument.
-
- > [!WARNING]
- > This will overwrite any existing credentials with the same entry
-
- ```bash
- az aks get-credentials --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_AKS_CLUSTER_NAME --overwrite-existing
- ```
-
-3. Verify the connection to your cluster using the kubectl get command. This command returns a list of the cluster nodes.
-
- ```bash
- kubectl get nodes
- ```
-
-## Install Inspektor Gadget
-
-The Inspektor Gadget installation is composed of two steps:
-
-1. Installing the kubectl plugin in the user's system.
-2. Installing Inspektor Gadget in the cluster.
-
- > [!NOTE]
- > There are additional mechanisms for deploying and utilizing Inspektor Gadget, each tailored to specific use cases and requirements. Using the `kubectl gadget` plugin covers many of them, but not all. For instance, deploying Inspektor Gadget with the `kubectl gadget` plugin depends on the Kubernetes API server's availability. So, if you can’t depend on such a component because its availability could be sometimes compromised, then it is recommended to not use the `kubectl gadget`deployment mechanism. Please check [ig documentation](https://github.com/inspektor-gadget/inspektor-gadget/blob/main/docs/ig.md) to know what to do in that, and other use cases.
-
-### Installing the kubectl plugin: `gadget`
-
-Install the latest version of the kubectl plugin from the releases page, uncompress and move the `kubectl-gadget` executable to `$HOME/.local/bin`:
-
-> [!NOTE]
-> If you want to install it using [`krew`](https://sigs.k8s.io/krew) or compile it from the source, please follow the official documentation: [installing kubectl gadget](https://github.com/inspektor-gadget/inspektor-gadget/blob/main/docs/install.md#installing-kubectl-gadget).
-
-```bash
-IG_VERSION=$(curl -s https://api.github.com/repos/inspektor-gadget/inspektor-gadget/releases/latest | jq -r .tag_name)
-IG_ARCH=amd64
-mkdir -p $HOME/.local/bin
-export PATH=$PATH:$HOME/.local/bin
-curl -sL https://github.com/inspektor-gadget/inspektor-gadget/releases/download/${IG_VERSION}/kubectl-gadget-linux-${IG_ARCH}-${IG_VERSION}.tar.gz | tar -C $HOME/.local/bin -xzf - kubectl-gadget
-```
-
-Now, let’s verify the installation by running the `version` command:
-
-```bash
-kubectl gadget version
-```
-
-The `version` command will display the version of the client (kubectl gadget plugin) and show that it is not yet installed in the server (the cluster):
-
-
-```text
-Client version: vX.Y.Z
-Server version: not installed
-```
-
-### Installing Inspektor Gadget in the cluster
-
-The following command will deploy the DaemonSet:
-
-> [!NOTE]
-> Several options are available to customize the deployment: use a specific container image, deploy to specific nodes, and many others. To know all of them, please check the official documentation: [installing in the cluster](https://github.com/inspektor-gadget/inspektor-gadget/blob/main/docs/install.md#installing-in-the-cluster).
-
-```bash
-kubectl gadget deploy
-```
-
-Now, let’s verify the installation by running the `version` command again:
-
-```bash
-kubectl gadget version
-```
-
-This time, the client and server will be correctly installed:
-
-
-```text
-Client version: vX.Y.Z
-Server version: vX.Y.Z
-```
-
-You can now start running the gadgets:
-
-```bash
-kubectl gadget help
-```
-
-
\ No newline at end of file