From 976e3fa5605e6407f5f23e84479535f20f6be8d0 Mon Sep 17 00:00:00 2001 From: Vaishnavi Sahu Date: Wed, 31 Dec 2025 12:13:55 +0000 Subject: [PATCH 1/3] added devcontainer file --- .devcontainer/devcontainer.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..59f8d3fb --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,8 @@ +{ + "name": "Azure Codespace", + "features": { + "ghcr.io/devcontainers/features/azure-cli:1": {}, + "ghcr.io/devcontainers/features/azure-cli:1": {}, + "ghcr.io/devcontainers/features/terraform:1": {} + } +} \ No newline at end of file From 2ddfc043fde660d5ade1c39772cf747b41990a88 Mon Sep 17 00:00:00 2001 From: Vaishnavi Sahu Date: Wed, 31 Dec 2025 19:16:02 +0000 Subject: [PATCH 2/3] added some changes in the project --- .devcontainer/devcontainer.json | 1 - azure/README.md | 70 ++++++++++++++++++ .../file-upload-processing-functions-blob.md | 45 ++++++----- .../function-code/function.json | 11 +++ .../function-code/index.js | 23 ++++++ .../function-deploy.zip | Bin 0 -> 852 bytes .../test-file.txt | 1 + .../test-image.jpg | 1 + 8 files changed, 132 insertions(+), 20 deletions(-) create mode 100644 azure/README.md create mode 100644 azure/file-upload-processing-functions-blob/function-code/function.json create mode 100644 azure/file-upload-processing-functions-blob/function-code/index.js create mode 100644 azure/file-upload-processing-functions-blob/function-deploy.zip create mode 100644 azure/file-upload-processing-functions-blob/test-file.txt create mode 100644 azure/file-upload-processing-functions-blob/test-image.jpg diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 59f8d3fb..31187e2e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,7 +1,6 @@ { "name": "Azure Codespace", "features": { - "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/terraform:1": {} } diff --git a/azure/README.md b/azure/README.md new file mode 100644 index 00000000..4e38c10f --- /dev/null +++ b/azure/README.md @@ -0,0 +1,70 @@ +## Preparation + +### Set up azure cli and terraform in Github Codespaces +Step 1: Create .devcontainer/devcontainer.json +Step 2: add the below content in the json file +```bash +{ + "name": "Azure Codespace", + "features": { + "ghcr.io/devcontainers/features/azure-cli:1": {}, + "ghcr.io/devcontainers/features/terraform:1": {}, +} +} +``` +Step 3: After editing devcontainer.json +- Push changes to GitHub +- In Codespace click Ctrl + Shift + P and type Codespaces: Rebuild Container and press enter + +### Set up azure login in Github Codespaces +Step 1: Run the below command in the Codespace terminal +```bash +az login --use-device-code +``` +Step 2: After login, set up the correct subscription, run below command in terminal to see all the avilable subscription +```bash +az account list --output table +``` +Step 3: Set the correct subscription explicitly +```bash +az account set --subscription +``` +- Verify the subscription has been set up correctly +```bash +az account show --query "{name:name, id:id, user:user.name}" + +``` +Step 4: Register resource provider if it is not registered. +- ✅ Check provider status +```bash +az account show --query "{name:name, id:id, user:user.name}" +``` +- ❌ If it says: NotRegistered +-🔧 Fix (this is safe) +```bash +az provider show --namespace Microsoft.Storage --query "registrationState" + +``` +- Wait 1–2 minutes, then confirm +```bash +az provider show --namespace Microsoft.Storage --query "registrationState" +``` +- It must say: Registered + +### Enable App Service for azure subscription + +Step 1: Register Microsoft.Web +- Run this once per subscription: +```bash +az provider register --namespace Microsoft.Web +``` +Step 2: Wait for registration to complete +- Check status: + +```bash +az provider show \ + --namespace Microsoft.Web \ + --query "registrationState" \ + --output tsv +``` +- You should see: Registered \ No newline at end of file diff --git a/azure/file-upload-processing-functions-blob/file-upload-processing-functions-blob.md b/azure/file-upload-processing-functions-blob/file-upload-processing-functions-blob.md index e2cf985e..d6420687 100644 --- a/azure/file-upload-processing-functions-blob/file-upload-processing-functions-blob.md +++ b/azure/file-upload-processing-functions-blob/file-upload-processing-functions-blob.md @@ -70,16 +70,19 @@ graph TB > **Note**: The Consumption plan includes a monthly free grant of 1 million executions and 400,000 GB-seconds, making this recipe extremely cost-effective for learning and testing scenarios. -## Preparation + +### Set environment variables for Azure resources ```bash -# Set environment variables for Azure resources +# Generate unique suffix for resource names +RANDOM_SUFFIX=$(openssl rand -hex 3) + +# Set environment variables export RESOURCE_GROUP="rg-file-processing-${RANDOM_SUFFIX}" export LOCATION="eastus" export SUBSCRIPTION_ID=$(az account show --query id --output tsv) -# Generate unique suffix for resource names -RANDOM_SUFFIX=$(openssl rand -hex 3) + # Set resource names with unique suffix export STORAGE_ACCOUNT="stfileproc${RANDOM_SUFFIX}" @@ -157,7 +160,7 @@ echo "✅ Resource group created: ${RESOURCE_GROUP}" --storage-account ${STORAGE_ACCOUNT} \ --consumption-plan-location ${LOCATION} \ --runtime node \ - --runtime-version 18 \ + --runtime-version 24 \ --functions-version 4 \ --tags purpose=file-processing environment=demo @@ -196,23 +199,27 @@ echo "✅ Resource group created: ${RESOURCE_GROUP}" # Create directory for function code mkdir -p function-code cd function-code - - # Create function.json configuration for blob trigger + ``` + +6. **Create function.json configuration for blob trigger** + ```bash cat > function.json << 'EOF' { - "bindings": [ +"bindings": [ { - "name": "myBlob", - "type": "blobTrigger", - "direction": "in", - "path": "uploads/{name}", - "connection": "STORAGE_CONNECTION_STRING" + "name": "myBlob", + "type": "blobTrigger", + "direction": "in", + "path": "uploads/{name}", + "connection": "STORAGE_CONNECTION_STRING" } - ] +] } EOF - - # Create JavaScript function code for file processing + ``` + +7. **Create JavaScript function code for file processing** + ```bash cat > index.js << 'EOF' module.exports = async function (context, myBlob) { const fileName = context.bindingData.name; @@ -238,12 +245,12 @@ module.exports = async function (context, myBlob) { context.log(`🎉 File processing workflow completed for: ${fileName}`); }; EOF - + ``` echo "✅ Function code created successfully" cd .. - ``` + -6. **Deploy Function to Azure**: +8. **Deploy Function to Azure**: Function deployment transfers the trigger configuration and processing logic to Azure's serverless infrastructure. Once deployed, the function automatically monitors the specified blob container and executes the processing workflow whenever new files are uploaded. diff --git a/azure/file-upload-processing-functions-blob/function-code/function.json b/azure/file-upload-processing-functions-blob/function-code/function.json new file mode 100644 index 00000000..68d2e504 --- /dev/null +++ b/azure/file-upload-processing-functions-blob/function-code/function.json @@ -0,0 +1,11 @@ +{ + "bindings": [ + { + "name": "myBlob", + "type": "blobTrigger", + "direction": "in", + "path": "uploads/{name}", + "connection": "STORAGE_CONNECTION_STRING" + } + ] +} diff --git a/azure/file-upload-processing-functions-blob/function-code/index.js b/azure/file-upload-processing-functions-blob/function-code/index.js new file mode 100644 index 00000000..01c0884d --- /dev/null +++ b/azure/file-upload-processing-functions-blob/function-code/index.js @@ -0,0 +1,23 @@ +module.exports = async function (context, myBlob) { + const fileName = context.bindingData.name; + const fileSize = myBlob.length; + const timestamp = new Date().toISOString(); + + context.log(`🔥 Processing file: ${fileName}`); + context.log(`📊 File size: ${fileSize} bytes`); + context.log(`⏰ Processing time: ${timestamp}`); + + // Simulate file processing logic + if (fileName.toLowerCase().includes('.jpg') || fileName.toLowerCase().includes('.png')) { + context.log(`🖼️ Image file detected: ${fileName}`); + context.log(`✅ Image processing completed successfully`); + } else if (fileName.toLowerCase().includes('.pdf')) { + context.log(`📄 PDF document detected: ${fileName}`); + context.log(`✅ PDF processing completed successfully`); + } else { + context.log(`📁 Generic file detected: ${fileName}`); + context.log(`✅ File processing completed successfully`); + } + + context.log(`🎉 File processing workflow completed for: ${fileName}`); +}; diff --git a/azure/file-upload-processing-functions-blob/function-deploy.zip b/azure/file-upload-processing-functions-blob/function-deploy.zip new file mode 100644 index 0000000000000000000000000000000000000000..21cea7b6a40478a46b1b7f65efc229e68ec87330 GIT binary patch literal 852 zcmWIWW@Zs#U|`^2sA`@c%@CXYq?eI_L4*Y)BEyiGmy%kcmsK1Z!pXqQ;UAg_!lf15 z42&!C$r#N5fYeuo_dT7S<;;#zV;sHjRws-sCsvEvE%k;wkDhyF#}+d5~$5{D)x zt{|2`#lVZfK?PEJ4DJbUj~qP3-?*b-W8M3+-;bG1uRC<%V4O^on_C7e8g`!9cu63jOq*&1m9uI$gFUXXo;DeZE^#{lB(q%AZcjDBU+tK5l`mcaxW7 zqFp|J85`@f70K7bcdC_NFcAu9TYDjWj`E9drmLo|>;ITt8PYa4^7)U?kw4dlF;D;0 zGSkRX)Wtqb*xhs8BE|^T)tNOq!9D!8Q@<{6+Hk}@HFWN0jWxFnWDcces`PBBNY(DL z-&en{moe%NcY2InmWtHhsoBwShc2Hz6Z6VhrGG}}M@Ll^YaXFvzg&-TOwjz3eDwr> z-P8Fo&bu$N#7}Bjd?ETm`nUg^)*s*5q%0y4yy>mcZ0`HV*ye5hfAH_ypb)Lc-3=$V zOp!cM!I>MfzJ@sf9-Wa*^P?xNcJXQlM(!aX<^@J)T4`Q#NoIZ?Fh=w9z;XJ@Co~g; z(c;v#XCv2P1rgWs{Z4bZ@9s8LY|&v8+8)%@nbi73^BAAwpYN*zV)X75zpG|U^am<;`+$>!4d(b0l6GZO&X^tNDAzr(UIBi~-(^OmfV)lBWdF zR}2im)XK1}5yV0yR#r%2Me`K0X_%pdY}$FCp=e Date: Sun, 18 Jan 2026 12:25:37 +0000 Subject: [PATCH 3/3] recent chnages --- .devcontainer/devcontainer.json | 3 +- .gitignore | 5 + azure/README.md | 61 ++++++- .../basic-database-web-app-sql-app-service/_ | 0 .../basic-database-web-app-sql-app-service.md | 4 +- .../code/README.md | 2 +- .../code/README.md | 8 +- .../code/terraform/.terraform.lock.hcl | 42 +++++ .../code/terraform/config.json | 1 + .../code/terraform/main.tf | 2 +- .../code/terraform/sample-document.txt | 1 + .../code/terraform/variables.tf | 2 +- .../code/terraform/versions.tf | 6 +- .../code/terraform/.terraform.lock.hcl | 42 +++++ .../code/terraform/main.tf | 169 +++++++++--------- .../code/terraform/outputs.tf | 22 +-- .../terraform/sample-content/404.html.tpl | 17 ++ .../code/terraform/sample-content/app.js | 9 + .../terraform/sample-content/index.html.tpl | 31 ++++ .../code/terraform/sample-content/styles.css | 7 + .../code/terraform/templates/404.html | 17 ++ .../code/terraform/templates/app.js | 9 + .../code/terraform/templates/index.html | 31 ++++ .../code/terraform/templates/styles.css | 7 + .../code/terraform/variables.tf | 4 +- .../code/terraform/versions.tf | 8 +- ...static-website-acceleration-cdn-storage.md | 2 + 27 files changed, 398 insertions(+), 114 deletions(-) create mode 100644 azure/basic-database-web-app-sql-app-service/_ create mode 100644 azure/basic-file-storage-blob-portal/code/terraform/.terraform.lock.hcl create mode 100644 azure/basic-file-storage-blob-portal/code/terraform/config.json create mode 100644 azure/basic-file-storage-blob-portal/code/terraform/sample-document.txt create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/.terraform.lock.hcl create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/404.html.tpl create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/app.js create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/index.html.tpl create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/styles.css create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/404.html create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/app.js create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/index.html create mode 100644 azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/styles.css diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 31187e2e..42590da8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,6 +2,7 @@ "name": "Azure Codespace", "features": { "ghcr.io/devcontainers/features/azure-cli:1": {}, - "ghcr.io/devcontainers/features/terraform:1": {} + "ghcr.io/devcontainers/features/terraform:1": {}, + "ghcr.io/devcontainers/features/aws-cli:1": {} } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4899c8d7..8de73276 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ __pycache__/ # SEO planning document SEO.md + +# Add this line to your .gitignore +.terraform/ +*.tfstate +*.tfstate.backup \ No newline at end of file diff --git a/azure/README.md b/azure/README.md index 4e38c10f..9759f659 100644 --- a/azure/README.md +++ b/azure/README.md @@ -9,7 +9,8 @@ Step 2: add the below content in the json file "features": { "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers/features/terraform:1": {}, -} + "ghcr.io/devcontainers/features/aws-cli:1": {} + } } ``` Step 3: After editing devcontainer.json @@ -21,7 +22,7 @@ Step 1: Run the below command in the Codespace terminal ```bash az login --use-device-code ``` -Step 2: After login, set up the correct subscription, run below command in terminal to see all the avilable subscription +Step 2: After login, set up the correct subscription, run below command in terminal to see all the available subscription ```bash az account list --output table ``` @@ -33,11 +34,16 @@ az account set --subscription ```bash az account show --query "{name:name, id:id, user:user.name}" +or +echo "SUBSCRIPTION_ID=$SUBSCRIPTION_ID" ``` Step 4: Register resource provider if it is not registered. - ✅ Check provider status ```bash -az account show --query "{name:name, id:id, user:user.name}" +az provider show \ + --namespace Microsoft.Storage \ + --query "registrationState" + ``` - ❌ If it says: NotRegistered -🔧 Fix (this is safe) @@ -67,4 +73,51 @@ az provider show \ --query "registrationState" \ --output tsv ``` -- You should see: Registered \ No newline at end of file +- You should see: Registered + +### Codespaces: Rebuild Container +```bash +az login +az account list -o table +az account set --subscription +``` + +### Generate unique suffix for resource naming +```bash +RANDOM_SUFFIX=$(openssl rand -hex 3) +``` +### Set environment variables for Azure resources +```bash +export SUBSCRIPTION_ID=$(az account show --query id --output tsv) +export RESOURCE_GROUP="rg-storage-demo-$(openssl rand -hex 3)" +export LOCATION="eastus" +``` + +### Create storage account if necessary for the project +```bash +export STORAGE_ACCOUNT="sa$(openssl rand -hex 6)" +``` + +### Create resource group for storage resources +```bash +az group create \ + --name ${RESOURCE_GROUP} \ + --location ${LOCATION} \ + --tags purpose=demo environment=learning + +echo "✅ Resource group created: ${RESOURCE_GROUP}" +echo "✅ Storage account name: ${STORAGE_ACCOUNT}" +``` + + +### Project studied but yet to run + +#### Container +- simple-web-container-aci-registry +- simple-container-deployment-container-apps +- secure-serverless-microservices +- serverless-containers-event-grid-aci --check event grid knowledge + + +#### Event-Grid +- simple-event-notifications-event-grid-functions diff --git a/azure/basic-database-web-app-sql-app-service/_ b/azure/basic-database-web-app-sql-app-service/_ new file mode 100644 index 00000000..e69de29b diff --git a/azure/basic-database-web-app-sql-app-service/basic-database-web-app-sql-app-service.md b/azure/basic-database-web-app-sql-app-service/basic-database-web-app-sql-app-service.md index 2f1d627f..6a7fd600 100644 --- a/azure/basic-database-web-app-sql-app-service/basic-database-web-app-sql-app-service.md +++ b/azure/basic-database-web-app-sql-app-service/basic-database-web-app-sql-app-service.md @@ -148,7 +148,7 @@ echo "✅ Resource group created: ${RESOURCE_GROUP}" ```bash # Create a simple table structure for demonstration - az sql query \ + az sql db query \ --server ${SQL_SERVER_NAME} \ --database ${SQL_DATABASE_NAME} \ --auth-type SqlPassword \ @@ -183,7 +183,7 @@ echo "✅ Resource group created: ${RESOURCE_GROUP}" --name ${APP_SERVICE_PLAN} \ --resource-group ${RESOURCE_GROUP} \ --location ${LOCATION} \ - --sku B1 \ + --sku B1\ --is-linux false echo "✅ App Service Plan created: ${APP_SERVICE_PLAN}" diff --git a/azure/basic-database-web-app-sql-app-service/code/README.md b/azure/basic-database-web-app-sql-app-service/code/README.md index 19eb0123..e2ae41d9 100644 --- a/azure/basic-database-web-app-sql-app-service/code/README.md +++ b/azure/basic-database-web-app-sql-app-service/code/README.md @@ -192,7 +192,7 @@ cd terraform/ # Destroy all resources terraform destroy -var="sql_admin_password=SecurePass123!" \ - -var="location=eastus" + -var="location=westus" ``` ### Using Bash Scripts diff --git a/azure/basic-file-storage-blob-portal/code/README.md b/azure/basic-file-storage-blob-portal/code/README.md index 1fe1633a..a75f9d82 100644 --- a/azure/basic-file-storage-blob-portal/code/README.md +++ b/azure/basic-file-storage-blob-portal/code/README.md @@ -62,13 +62,13 @@ terraform init terraform plan \ -var="resource_group_name=rg-storage-demo" \ -var="location=eastus" \ - -var="storage_account_prefix=mystorageacct" + -var="storage_account_name=mystorageacct" # Apply the configuration terraform apply \ -var="resource_group_name=rg-storage-demo" \ -var="location=eastus" \ - -var="storage_account_prefix=mystorageacct" + -var="storage_account_name=mystorageacct" # View outputs terraform output @@ -111,7 +111,7 @@ Customize your deployment by modifying variables in `terraform/variables.tf` or terraform apply \ -var="resource_group_name=my-rg" \ -var="location=westus2" \ - -var="storage_account_prefix=mycompany" \ + -var="storage_account_name=mycompany" \ -var="sku_name=Standard_GRS" \ -var="access_tier=Cool" ``` @@ -206,7 +206,7 @@ cd terraform/ terraform destroy \ -var="resource_group_name=rg-storage-demo" \ -var="location=eastus" \ - -var="storage_account_prefix=mystorageacct" + -var="storage_account_account=mystorageacct" ``` ### Using Bash Scripts diff --git a/azure/basic-file-storage-blob-portal/code/terraform/.terraform.lock.hcl b/azure/basic-file-storage-blob-portal/code/terraform/.terraform.lock.hcl new file mode 100644 index 00000000..9cd81b88 --- /dev/null +++ b/azure/basic-file-storage-blob-portal/code/terraform/.terraform.lock.hcl @@ -0,0 +1,42 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "4.37.0" + constraints = "~> 4.37.0" + hashes = [ + "h1:TnYunwlF59toWHSHaQ80cGc46VVJ9+wC3Go5TFTAN0o=", + "zh:10acb818823a0319215beb796af1a7a97820be5d40ec1779deb8c2bdb1cac6d0", + "zh:31cac8c98e4b8e1f44e33394e6ed375552aea204ef9ce2e8612719c5ebb8ffae", + "zh:32048bf10eec89819f73de86a478aced0101be9d480badad8dec31f65b65590a", + "zh:38236dfd5e28c4ceaf27b3a719deb40802159ceed810c667be3a42ee8bc384d8", + "zh:438cff6ac72117016975d47fadfdbccb33218274c6c74fd4ff4f1eea2ec18b6a", + "zh:7763f4d97b3f67e65e730023755db6b567644c0fab9a65e966c9a34fb4690a97", + "zh:799eca3363eda85a6f6678d47bf01cb48dcb9296ecd6165814eb696a9d9e2c7d", + "zh:8508771cedbaa651156a3726cda04e1f28443a46e3a7c72b4a9a7abbf671aed9", + "zh:96b016af4ebe0db58ba51e40dd419465b5152f98842d366a5b5b8835f2c7be58", + "zh:eb7d0efaaaef225b6e867e5cbd0514f39f0bc4e12e6c3cdfdb666776c5948995", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:ffa8d70d432894b7b023f50831490bd5db762c8f48d5f7607888aaa5d0da39e8", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.4.3" + constraints = "~> 3.4.0" + hashes = [ + "h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=", + "zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752", + "zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b", + "zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3", + "zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5", + "zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda", + "zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6", + "zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1", + "zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d", + "zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8", + "zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93", + ] +} diff --git a/azure/basic-file-storage-blob-portal/code/terraform/config.json b/azure/basic-file-storage-blob-portal/code/terraform/config.json new file mode 100644 index 00000000..93c41093 --- /dev/null +++ b/azure/basic-file-storage-blob-portal/code/terraform/config.json @@ -0,0 +1 @@ +{"app": "demo", "environment": "test", "version": "1.0"} diff --git a/azure/basic-file-storage-blob-portal/code/terraform/main.tf b/azure/basic-file-storage-blob-portal/code/terraform/main.tf index 17d07b7e..fc1a0306 100644 --- a/azure/basic-file-storage-blob-portal/code/terraform/main.tf +++ b/azure/basic-file-storage-blob-portal/code/terraform/main.tf @@ -202,7 +202,7 @@ resource "azurerm_role_assignment" "current_user_blob_contributor" { principal_id = data.azurerm_client_config.current.object_id # Specify principal type for ABAC compatibility - principal_type = "ServicePrincipal" + principal_type = "User" # Add descriptive information for audit purposes description = "Storage Blob Data Contributor access for Terraform deployment user" diff --git a/azure/basic-file-storage-blob-portal/code/terraform/sample-document.txt b/azure/basic-file-storage-blob-portal/code/terraform/sample-document.txt new file mode 100644 index 00000000..ed0949a6 --- /dev/null +++ b/azure/basic-file-storage-blob-portal/code/terraform/sample-document.txt @@ -0,0 +1 @@ +This is a sample document for testing blob storage capabilities. diff --git a/azure/basic-file-storage-blob-portal/code/terraform/variables.tf b/azure/basic-file-storage-blob-portal/code/terraform/variables.tf index fede3e1d..c332f8ef 100644 --- a/azure/basic-file-storage-blob-portal/code/terraform/variables.tf +++ b/azure/basic-file-storage-blob-portal/code/terraform/variables.tf @@ -28,7 +28,7 @@ variable "location" { validation { condition = contains([ - "East US", "East US 2", "West US", "West US 2", "West US 3", + "East US", "East US 2", "West US", "West US 2", "West US 3", "eastus", "Central US", "North Central US", "South Central US", "West Central US", "Canada Central", "Canada East", "Brazil South", diff --git a/azure/basic-file-storage-blob-portal/code/terraform/versions.tf b/azure/basic-file-storage-blob-portal/code/terraform/versions.tf index 26b36a2e..8b6482c3 100644 --- a/azure/basic-file-storage-blob-portal/code/terraform/versions.tf +++ b/azure/basic-file-storage-blob-portal/code/terraform/versions.tf @@ -30,8 +30,8 @@ provider "azurerm" { # Storage provider features for enhanced blob storage management storage { # Prevent accidental deletion of storage containers and blobs - purge_soft_delete_on_destroy = false - recover_soft_deleted_key_vaults = false + # purge_soft_delete_on_destroy = false + # recover_soft_deleted_key_vaults = false } # Resource group provider features @@ -40,7 +40,7 @@ provider "azurerm" { prevent_deletion_if_contains_resources = false } } - + subscription_id = "333e3c5a-b7cf-41ff-9a88-f367c6754474" # Use Azure CLI authentication by default # Alternatively, service principal authentication can be configured # using environment variables or configuration blocks diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/.terraform.lock.hcl b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/.terraform.lock.hcl new file mode 100644 index 00000000..76340b39 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/.terraform.lock.hcl @@ -0,0 +1,42 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "3.117.1" + constraints = "~> 3.70" + hashes = [ + "h1:3c9iOEtBMnHrpJLlhbQ0sCZPWhE/2dvEPcL8KkXAh7w=", + "zh:0c513676836e3c50d004ece7d2624a8aff6faac14b833b96feeac2e4bc2c1c12", + "zh:50ea01ada95bae2f187db9e926e463f45d860767a85ebc59160414e00e76c35d", + "zh:52c2a9edacc06b3f72153f5ef6daca0761c6292158815961fe37f60bc576a3d7", + "zh:618eed2a06b19b1a025b45b05891846d570a6a1cca4d23f4942f5a99e1f747ae", + "zh:61cde5d3165d7e5ec311d5d89486819cd605c1b2d54611b5c97bd4e97dba2762", + "zh:6a873358d5031fc222f5e05f029d1237f3dce8345c767665f393283dfa2627f6", + "zh:afdd80064b2a04da311856feb4ed45f77ff4df6c356e8c2b10afb51fe7e61c70", + "zh:b09113df7e0e8c8959539bd22bae6c39faeb269ba3c4cd948e742f5cf58c35fb", + "zh:d340db7973109761cfc27d52aa02560363337c908b2c99b3628adc5a70a99d5b", + "zh:d5a577226ebc8c65e8f19384878a86acc4b51ede4b4a82d37c3b331b0efcd4a7", + "zh:e2962b147f9e71732df8dbc74940c10d20906f3c003cbfaa1eb9fabbf601a9f0", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = "~> 3.5" + hashes = [ + "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/main.tf b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/main.tf index f96c8d21..efdf9cc4 100644 --- a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/main.tf +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/main.tf @@ -43,13 +43,13 @@ resource "azurerm_storage_account" "main" { shared_access_key_enabled = true # Cross-Origin Resource Sharing (CORS) rules for web applications - cors_rule { - allowed_headers = ["*"] - allowed_methods = ["GET", "HEAD", "OPTIONS"] - allowed_origins = ["*"] - exposed_headers = ["*"] - max_age_in_seconds = 3600 - } + # cors_rule { + # allowed_headers = ["*"] + # allowed_methods = ["GET", "HEAD", "OPTIONS"] + # allowed_origins = ["*"] + # exposed_headers = ["*"] + # max_age_in_seconds = 3600 + # } tags = var.tags } @@ -113,18 +113,17 @@ resource "azurerm_storage_blob" "error_404_html" { } # Create CDN Profile for global content delivery -resource "azurerm_cdn_profile" "main" { +resource "azurerm_cdn_frontdoor_profile" "main" { name = "${var.cdn_profile_name_prefix}-${random_string.suffix.result}" - location = azurerm_resource_group.main.location resource_group_name = azurerm_resource_group.main.name - sku = var.cdn_sku + sku_name = var.cdn_sku tags = var.tags } # Create CDN Endpoint pointing to the static website resource "azurerm_cdn_endpoint" "main" { name = "${var.cdn_endpoint_name_prefix}-${random_string.suffix.result}" - profile_name = azurerm_cdn_profile.main.name + profile_name = azurerm_cdn_frontdoor_profile.main.name location = azurerm_resource_group.main.location resource_group_name = azurerm_resource_group.main.name @@ -150,7 +149,15 @@ resource "azurerm_cdn_endpoint" "main" { ] # Configure caching behavior - query_string_caching_behaviour = var.query_string_caching_behavior + # query_string_caching_behaviour = var.query_string_caching_behavior + # delivery_rule { + # name = "query_string_caching_behaviour" + # order = 1 + + # cache_key_query_string_action { + # behavior = var.query_string_caching_behavior + # } + # } optimization_type = var.optimization_type # Configure origin host header to match storage account @@ -162,21 +169,21 @@ resource "azurerm_cdn_endpoint" "main" { order = 1 # Match CSS, JS, and image files - conditions { - url_file_extension_condition { - operator = "Equal" - match_values = ["css", "js", "png", "jpg", "jpeg", "gif", "svg", "ico", "woff", "woff2", "ttf", "eot"] - transforms = ["Lowercase"] - } - } + # conditions { + # url_file_extension_condition { + # operator = "Equal" + # match_values = ["css", "js", "png", "jpg", "jpeg", "gif", "svg", "ico", "woff", "woff2", "ttf", "eot"] + # transforms = ["Lowercase"] + # } + # } # Cache for 30 days - actions { - cache_expiration_action { - behavior = "Override" - duration = "30.00:00:00" - } - } + # actions { + # cache_expiration_action { + # behavior = "Override" + # duration = "30.00:00:00" + # } + # } } delivery_rule { @@ -184,69 +191,29 @@ resource "azurerm_cdn_endpoint" "main" { order = 2 # Match HTML files - conditions { - url_file_extension_condition { - operator = "Equal" - match_values = ["html", "htm"] - transforms = ["Lowercase"] - } + # conditions { + # url_file_extension_condition { + # operator = "Equal" + # match_values = ["html", "htm"] + # transforms = ["Lowercase"] + # } } # Cache for 1 hour - actions { - cache_expiration_action { - behavior = "Override" - duration = "01:00:00" - } - } - } + # actions { + # cache_expiration_action { + # behavior = "Override" + # duration = "01:00:00" + # } + # } + # } tags = var.tags depends_on = [azurerm_storage_account.main] } -# Create template files for sample content -resource "local_file" "index_html_template" { - count = var.create_sample_content ? 1 : 0 - filename = "${path.module}/templates/index.html" - content = templatefile("${path.module}/sample-content/index.html.tpl", {}) - - provisioner "local-exec" { - command = "mkdir -p ${path.module}/templates" - } -} - -resource "local_file" "styles_css_template" { - count = var.create_sample_content ? 1 : 0 - filename = "${path.module}/templates/styles.css" - content = file("${path.module}/sample-content/styles.css") - - provisioner "local-exec" { - command = "mkdir -p ${path.module}/templates" - } -} - -resource "local_file" "app_js_template" { - count = var.create_sample_content ? 1 : 0 - filename = "${path.module}/templates/app.js" - content = file("${path.module}/sample-content/app.js") - - provisioner "local-exec" { - command = "mkdir -p ${path.module}/templates" - } -} - -resource "local_file" "error_404_html_template" { - count = var.create_sample_content ? 1 : 0 - filename = "${path.module}/templates/404.html" - content = templatefile("${path.module}/sample-content/404.html.tpl", {}) - - provisioner "local-exec" { - command = "mkdir -p ${path.module}/templates" - } -} - +/* # Create sample content directory and files resource "local_file" "sample_index_html" { count = var.create_sample_content ? 1 : 0 @@ -354,4 +321,46 @@ EOT provisioner "local-exec" { command = "mkdir -p ${path.module}/sample-content" } -} \ No newline at end of file +} + +# Create template files for sample content +resource "local_file" "index_html_template" { + count = var.create_sample_content ? 1 : 0 + filename = "${path.module}/templates/index.html" + content = templatefile("${path.module}/sample-content/index.html.tpl", {}) + + provisioner "local-exec" { + command = "mkdir -p ${path.module}/templates" + } +} + +resource "local_file" "styles_css_template" { + count = var.create_sample_content ? 1 : 0 + filename = "${path.module}/templates/styles.css" + content = file("${path.module}/sample-content/styles.css") + + provisioner "local-exec" { + command = "mkdir -p ${path.module}/templates" + } +} + +resource "local_file" "app_js_template" { + count = var.create_sample_content ? 1 : 0 + filename = "${path.module}/templates/app.js" + content = file("${path.module}/sample-content/app.js") + + provisioner "local-exec" { + command = "mkdir -p ${path.module}/templates" + } +} + +resource "local_file" "error_404_html_template" { + count = var.create_sample_content ? 1 : 0 + filename = "${path.module}/templates/404.html" + content = templatefile("${path.module}/sample-content/404.html.tpl", {}) + + provisioner "local-exec" { + command = "mkdir -p ${path.module}/templates" + } +} +*/ \ No newline at end of file diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/outputs.tf b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/outputs.tf index b1028afe..f137bf44 100644 --- a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/outputs.tf +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/outputs.tf @@ -54,17 +54,17 @@ output "static_website_host" { # CDN Information output "cdn_profile_name" { description = "Name of the CDN profile" - value = azurerm_cdn_profile.main.name + value = azurerm_cdn_frontdoor_profile.main.name } output "cdn_profile_id" { description = "Full resource ID of the CDN profile" - value = azurerm_cdn_profile.main.id + value = azurerm_cdn_frontdoor_profile.main.id } output "cdn_profile_sku" { description = "SKU/pricing tier of the CDN profile" - value = azurerm_cdn_profile.main.sku + value = azurerm_cdn_frontdoor_profile.main.sku_name } # CDN Endpoint Information @@ -80,12 +80,12 @@ output "cdn_endpoint_id" { output "cdn_endpoint_url" { description = "Primary URL for accessing content via CDN" - value = "https://${azurerm_cdn_endpoint.main.host_name}" + value = "https://${azurerm_cdn_endpoint.main.fqdn}" } output "cdn_endpoint_hostname" { description = "Hostname of the CDN endpoint" - value = azurerm_cdn_endpoint.main.host_name + value = azurerm_cdn_endpoint.main.fqdn } output "cdn_endpoint_origin_host_header" { @@ -106,7 +106,7 @@ output "optimization_type" { output "query_string_caching_behavior" { description = "Query string caching behavior for the CDN endpoint" - value = azurerm_cdn_endpoint.main.query_string_caching_behaviour + value = var.query_string_caching_behavior } # Website Configuration @@ -131,8 +131,8 @@ output "testing_commands" { description = "Commands to test the deployed infrastructure" value = { test_storage_direct = "curl -I ${azurerm_storage_account.main.primary_web_endpoint}" - test_cdn_endpoint = "curl -I https://${azurerm_cdn_endpoint.main.host_name}" - test_compression = "curl -H 'Accept-Encoding: gzip' -I https://${azurerm_cdn_endpoint.main.host_name}" + test_cdn_endpoint = "curl -I https://${azurerm_cdn_endpoint.main.fqdn}" + test_compression = "curl -H 'Accept-Encoding: gzip' -I https://${azurerm_cdn_endpoint.main.fqdn}" } } @@ -154,8 +154,8 @@ output "deployment_summary" { estimated_monthly_cost = "~$1-3 USD (depending on storage and bandwidth usage)" } cdn_profile = { - name = azurerm_cdn_profile.main.name - sku = azurerm_cdn_profile.main.sku + name = azurerm_cdn_frontdoor_profile.main.name + sku = azurerm_cdn_frontdoor_profile.main.sku_name estimated_monthly_cost = "~$1-2 USD (depending on data transfer and requests)" } total_estimated_monthly_cost = "~$2-5 USD" @@ -178,7 +178,7 @@ output "next_steps" { description = "Recommended next steps after deployment" value = [ "Test the static website: ${azurerm_storage_account.main.primary_web_endpoint}", - "Test the CDN endpoint: https://${azurerm_cdn_endpoint.main.host_name}", + "Test the CDN endpoint: https://${azurerm_cdn_endpoint.main.fqdn}", "Upload your own content to the '$web' container in the storage account", "Configure a custom domain for production use", "Set up monitoring and alerts for performance tracking", diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/404.html.tpl b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/404.html.tpl new file mode 100644 index 00000000..3f9f0857 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/404.html.tpl @@ -0,0 +1,17 @@ + + + + + + Page Not Found - Global Store + + + +

Page Not Found

+
+

404 - Content Not Available

+

The requested page could not be found.

+ Return to Home +
+ + diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/app.js b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/app.js new file mode 100644 index 00000000..445df99b --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/app.js @@ -0,0 +1,9 @@ +document.addEventListener('DOMContentLoaded', function() { + console.log('Static website loaded via Azure CDN'); + + // Add performance timing + window.addEventListener('load', function() { + const loadTime = performance.timing.loadEventEnd - performance.timing.navigationStart; + console.log('Page load time: ' + loadTime + 'ms'); + }); +}); diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/index.html.tpl b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/index.html.tpl new file mode 100644 index 00000000..53f6d098 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/index.html.tpl @@ -0,0 +1,31 @@ + + + + + + Global Product Catalog - Accelerated by Azure CDN + + + +
+

Welcome to Our Global Store

+

Lightning-fast delivery worldwide via Azure CDN

+
+
+
+

Experience Global Performance

+

This website is delivered from Azure's global edge network, + ensuring fast loading times regardless of your location.

+
+
+

Featured Products

+
+
Premium Headphones - $299
+
Smart Watch - $399
+
Wireless Speaker - $199
+
+
+
+ + + diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/styles.css b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/styles.css new file mode 100644 index 00000000..fdea4556 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/sample-content/styles.css @@ -0,0 +1,7 @@ +* { margin: 0; padding: 0; box-sizing: border-box; } +body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; } +header { background: #0078D4; color: white; padding: 2rem; text-align: center; } +.hero { padding: 3rem 2rem; background: #f4f4f4; text-align: center; } +.products { padding: 2rem; } +.product-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; } +.product { background: white; padding: 1rem; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/404.html b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/404.html new file mode 100644 index 00000000..3f9f0857 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/404.html @@ -0,0 +1,17 @@ + + + + + + Page Not Found - Global Store + + + +

Page Not Found

+
+

404 - Content Not Available

+

The requested page could not be found.

+ Return to Home +
+ + diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/app.js b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/app.js new file mode 100644 index 00000000..445df99b --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/app.js @@ -0,0 +1,9 @@ +document.addEventListener('DOMContentLoaded', function() { + console.log('Static website loaded via Azure CDN'); + + // Add performance timing + window.addEventListener('load', function() { + const loadTime = performance.timing.loadEventEnd - performance.timing.navigationStart; + console.log('Page load time: ' + loadTime + 'ms'); + }); +}); diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/index.html b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/index.html new file mode 100644 index 00000000..53f6d098 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/index.html @@ -0,0 +1,31 @@ + + + + + + Global Product Catalog - Accelerated by Azure CDN + + + +
+

Welcome to Our Global Store

+

Lightning-fast delivery worldwide via Azure CDN

+
+
+
+

Experience Global Performance

+

This website is delivered from Azure's global edge network, + ensuring fast loading times regardless of your location.

+
+
+

Featured Products

+
+
Premium Headphones - $299
+
Smart Watch - $399
+
Wireless Speaker - $199
+
+
+
+ + + diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/styles.css b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/styles.css new file mode 100644 index 00000000..fdea4556 --- /dev/null +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/templates/styles.css @@ -0,0 +1,7 @@ +* { margin: 0; padding: 0; box-sizing: border-box; } +body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; } +header { background: #0078D4; color: white; padding: 2rem; text-align: center; } +.hero { padding: 3rem 2rem; background: #f4f4f4; text-align: center; } +.products { padding: 2rem; } +.product-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; } +.product { background: white; padding: 1rem; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/variables.tf b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/variables.tf index aeb93fc7..156c68d1 100644 --- a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/variables.tf +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/variables.tf @@ -101,12 +101,12 @@ variable "storage_account_access_tier" { variable "cdn_sku" { description = "CDN profile SKU/pricing tier" type = string - default = "Standard_Microsoft" + default = "Standard_AzureFrontDoor" validation { condition = contains([ "Standard_Akamai", "Standard_Microsoft", "Standard_Verizon", - "Premium_Verizon", "Standard_ChinaCdn", "Standard_955BandWidth_ChinaCdn" + "Premium_Verizon", "Standard_ChinaCdn", "Standard_955BandWidth_ChinaCdn","Standard_AzureFrontDoor" ], var.cdn_sku) error_message = "CDN SKU must be a valid Azure CDN pricing tier." } diff --git a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/versions.tf b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/versions.tf index d1b406d3..62a6bccb 100644 --- a/azure/simple-static-website-acceleration-cdn-storage/code/terraform/versions.tf +++ b/azure/simple-static-website-acceleration-cdn-storage/code/terraform/versions.tf @@ -19,10 +19,10 @@ terraform { # Configure the Azure Provider provider "azurerm" { features { - # Enable enhanced storage account features - storage { - purge_soft_deleted_blobs_on_destroy = true - } + # # Enable enhanced storage account features + # # storage { + # # purge_soft_deleted_blobs_on_destroy = true + # # } # Enable resource group cleanup features resource_group { diff --git a/azure/simple-static-website-acceleration-cdn-storage/simple-static-website-acceleration-cdn-storage.md b/azure/simple-static-website-acceleration-cdn-storage/simple-static-website-acceleration-cdn-storage.md index d0f644e7..dc5d6139 100644 --- a/azure/simple-static-website-acceleration-cdn-storage/simple-static-website-acceleration-cdn-storage.md +++ b/azure/simple-static-website-acceleration-cdn-storage/simple-static-website-acceleration-cdn-storage.md @@ -282,7 +282,9 @@ EOF # Extract origin hostname from website URL for CDN configuration ORIGIN_HOSTNAME=$(echo ${WEBSITE_URL} | sed 's|https://||' | sed 's|/||') + ``` + ```bash # Create CDN endpoint pointing to static website az cdn endpoint create \ --name ${CDN_ENDPOINT} \