From 9418a5aaed265ec6b8d8de03961515d158a0e39b Mon Sep 17 00:00:00 2001 From: Aaron Wislang Date: Wed, 28 Aug 2024 19:10:26 -0400 Subject: [PATCH] Deprecate Cloud Native / AKS scenarios to be updated to use Azure Verified Modules (AVM) (#57) * Deprecate: - cloud-native/aks-arm64/ Signed-off-by: Aaron Wislang * Deprecate: - cloud-native/aks-bicep/ - cloud-native/aks-bicep-keda/ - cloud-native/webapp-routing/ Remove: - cloud-native/aks-open-service-mesh/ Signed-off-by: Aaron Wislang * Remove: - cloud-native/aks-bicep-k8s/ Signed-off-by: Aaron Wislang --------- Signed-off-by: Aaron Wislang --- .github/workflows/publish_bicep_module.yml | 43 - bicep/modules/azure-cli-script/README.md | 22 - bicep/modules/azure-cli-script/main.bicep | 62 -- bicep/modules/azure-cli-script/metadata.json | 6 - .../azure-container-registry/README.MD | 23 - .../azure-container-registry/main.bicep | 48 - .../azure-container-registry/metadata.json | 6 - bicep/modules/azure-cosmos-db/README.md | 21 - bicep/modules/azure-cosmos-db/main.bicep | 50 - bicep/modules/azure-cosmos-db/metadata.json | 6 - bicep/modules/azure-dns/README.md | 18 - bicep/modules/azure-dns/main.bicep | 20 - bicep/modules/azure-dns/metadata.json | 6 - bicep/modules/azure-key-vault/README.md | 20 - bicep/modules/azure-key-vault/main.bicep | 57 -- bicep/modules/azure-key-vault/metadata.json | 6 - .../azure-kubernetes-service-addons/README.md | 18 - .../main.bicep | 18 - .../metadata.json | 6 - .../README.md | 20 - .../main.bicep | 23 - .../metadata.json | 6 - .../README.md | 19 - .../main.bicep | 21 - .../metadata.json | 6 - .../README.md | 19 - .../main.bicep | 25 - .../metadata.json | 6 - .../azure-kubernetes-service/README.md | 39 - .../azure-kubernetes-service/main.bicep | 211 ---- .../azure-kubernetes-service/metadata.json | 6 - .../azure-log-analytics-workspace/README.md | 17 - .../azure-log-analytics-workspace/main.bicep | 17 - .../metadata.json | 6 - .../README.md | 17 - .../main.bicep | 370 ------- .../metadata.json | 6 - .../azure-network-security-group/README.md | 17 - .../azure-network-security-group/main.bicep | 14 - .../metadata.json | 6 - bicep/modules/azure-virtual-network/README.md | 24 - .../modules/azure-virtual-network/main.bicep | 41 - .../azure-virtual-network/metadata.json | 6 - cloud-native/README.md | 7 +- cloud-native/aks-arm64/README.md | 368 ------- .../aks-arm64/azure-voting-app-deploy.yaml | 94 -- cloud-native/aks-arm64/bicepconfig.json | 10 - cloud-native/aks-arm64/kustomization.yaml | 8 - cloud-native/aks-arm64/main.bicep | 128 --- cloud-native/aks-arm64/main.json | 914 ------------------ cloud-native/aks-bicep-k8s/README.md | 61 -- .../aks-bicep-k8s/aks-deploy-app.bicep | 16 - cloud-native/aks-bicep-k8s/aks.bicep | 93 -- cloud-native/aks-bicep-k8s/azure-vote.bicep | 150 --- cloud-native/aks-bicep-k8s/azure-vote.yaml | 85 -- .../aks-bicep-k8s/azure-voting-app-rust.bicep | 165 ---- .../aks-bicep-k8s/azure-voting-app-rust.yaml | 93 -- cloud-native/aks-bicep-k8s/bicepconfig.json | 16 - .../aks-bicep-k8s/dotnet-vue-starter.bicep | 75 -- .../aks-bicep-k8s/dotnet-vue-starter.yaml | 39 - cloud-native/aks-bicep-k8s/go.mod | 5 - cloud-native/aks-bicep-k8s/go.sum | 2 - cloud-native/aks-bicep-k8s/magefile.go | 277 ------ cloud-native/aks-bicep-k8s/main.bicep | 29 - cloud-native/aks-bicep-k8s/main.json | 424 -------- cloud-native/aks-bicep-keda/01-aks/README.md | 21 - .../aks-bicep-keda/01-aks/RESOURCES.md | 5 - cloud-native/aks-bicep-keda/01-aks/aks.bicep | 139 --- .../aks-bicep-keda/01-aks/deploy-aks.sh | 6 - .../01-aks/deploy-deploy-script.sh | 9 - .../aks-bicep-keda/01-aks/deploy-empty.sh | 6 - .../aks-bicep-keda/01-aks/deploy-keyvault.sh | 6 - .../aks-bicep-keda/01-aks/deploy-main.sh | 11 - .../01-aks/deploy-script-aks.sh | 8 - .../01-aks/deploy-script-keda.sh | 8 - .../aks-bicep-keda/01-aks/deploy-script.bicep | 65 -- .../aks-bicep-keda/01-aks/empty.bicep | 1 - .../aks-bicep-keda/01-aks/keyvault.bicep | 34 - cloud-native/aks-bicep-keda/01-aks/main.bicep | 31 - cloud-native/aks-bicep-keda/01-aks/main.json | 365 ------- cloud-native/aks-bicep-keda/02-keda/README.md | 3 - .../02-keda/deploy/deployment.yaml | 34 - .../aks-bicep-keda/02-keda/deploy/keda.yaml | 45 - .../02-keda/deploy/kustomization.yaml | 10 - .../02-keda/deploy/namespace.yaml | 5 - .../02-keda/deploy/serviceaccount.yaml | 7 - .../aks-bicep-keda/03-keda-http/README.md | 67 -- cloud-native/aks-bicep-keda/README.md | 94 -- cloud-native/aks-bicep/01-aks/README.md | 21 - cloud-native/aks-bicep/01-aks/RESOURCES.md | 5 - cloud-native/aks-bicep/01-aks/aks.bicep | 139 --- cloud-native/aks-bicep/01-aks/deploy-aks.sh | 6 - .../aks-bicep/01-aks/deploy-deploy-script.sh | 9 - cloud-native/aks-bicep/01-aks/deploy-empty.sh | 6 - .../aks-bicep/01-aks/deploy-keyvault.sh | 6 - cloud-native/aks-bicep/01-aks/deploy-main.sh | 11 - .../aks-bicep/01-aks/deploy-script-aks.sh | 8 - .../aks-bicep/01-aks/deploy-script-keda.sh | 8 - .../aks-bicep/01-aks/deploy-script.bicep | 65 -- cloud-native/aks-bicep/01-aks/empty.bicep | 1 - cloud-native/aks-bicep/01-aks/keyvault.bicep | 34 - cloud-native/aks-bicep/01-aks/main.bicep | 31 - cloud-native/aks-bicep/01-aks/main.json | 365 ------- cloud-native/aks-bicep/README.md | 45 - .../02-deploying-bookstore-app/README.md | 225 ----- .../bookbuyer-ui-ingressbackend.yaml | 15 - .../bookbuyer-ui.yaml | 35 - .../02-deploying-bookstore-app/bookbuyer.png | Bin 57396 -> 0 bytes .../bookstore-ui-ingressbackend.yaml | 15 - .../bookstore-ui.yaml | 35 - .../bookstore-v1.png | Bin 42483 -> 0 bytes .../bookstore_app.png | Bin 24869 -> 0 bytes .../bookthief-ui-ingressbackend.yaml | 15 - .../bookthief-ui.yaml | 34 - .../02-deploying-bookstore-app/bookthief.png | Bin 54135 -> 0 bytes .../03-applying-zero-trust/README.md | 226 ----- .../bookbuyer-ui-secure-ingress.yaml | 45 - .../03-applying-zero-trust/bookbuyer.png | Bin 59642 -> 0 bytes .../bookstore-ui-secure-ingress.yaml | 45 - .../bookthief-ui-secure-ingress.yaml | 45 - .../smi-traffic-to-bookstore.yaml | 39 - .../smi-traffic-to-bookwarehouse.yaml | 31 - .../smi-traffic-to-mysql.yaml | 27 - .../04-osm-traffic-splitting/README.md | 134 --- .../bookstore-split.png | Bin 57825 -> 0 bytes .../bookstore-ui-v2.yaml | 51 - .../04-osm-traffic-splitting/bookstore-v2.png | Bin 42379 -> 0 bytes cloud-native/aks-open-service-mesh/README.md | 275 ------ .../aks-open-service-mesh/bicepconfig.json | 10 - cloud-native/aks-open-service-mesh/main.bicep | 142 --- cloud-native/aks-open-service-mesh/main.json | 874 ----------------- cloud-native/aks-webapp-routing/README.md | 404 -------- .../azure-vote-deployment-validation.png | Bin 40669 -> 0 bytes .../azure-vote-deployment.png | Bin 175872 -> 0 bytes .../aks-webapp-routing/bicepconfig.json | 10 - .../aks-webapp-routing/deployment.yaml | 117 --- .../hello-deployment-2.yaml | 65 -- .../hello-deployment-validation.png | Bin 41039 -> 0 bytes .../aks-webapp-routing/hello-deployment.png | Bin 198400 -> 0 bytes cloud-native/aks-webapp-routing/main.bicep | 141 --- cloud-native/aks-webapp-routing/main.json | 785 --------------- 141 files changed, 3 insertions(+), 10034 deletions(-) delete mode 100644 .github/workflows/publish_bicep_module.yml delete mode 100644 bicep/modules/azure-cli-script/README.md delete mode 100644 bicep/modules/azure-cli-script/main.bicep delete mode 100644 bicep/modules/azure-cli-script/metadata.json delete mode 100644 bicep/modules/azure-container-registry/README.MD delete mode 100644 bicep/modules/azure-container-registry/main.bicep delete mode 100644 bicep/modules/azure-container-registry/metadata.json delete mode 100644 bicep/modules/azure-cosmos-db/README.md delete mode 100644 bicep/modules/azure-cosmos-db/main.bicep delete mode 100644 bicep/modules/azure-cosmos-db/metadata.json delete mode 100644 bicep/modules/azure-dns/README.md delete mode 100644 bicep/modules/azure-dns/main.bicep delete mode 100644 bicep/modules/azure-dns/metadata.json delete mode 100644 bicep/modules/azure-key-vault/README.md delete mode 100644 bicep/modules/azure-key-vault/main.bicep delete mode 100644 bicep/modules/azure-key-vault/metadata.json delete mode 100644 bicep/modules/azure-kubernetes-service-addons/README.md delete mode 100644 bicep/modules/azure-kubernetes-service-addons/main.bicep delete mode 100644 bicep/modules/azure-kubernetes-service-addons/metadata.json delete mode 100644 bicep/modules/azure-kubernetes-service-ingress-dns/README.md delete mode 100644 bicep/modules/azure-kubernetes-service-ingress-dns/main.bicep delete mode 100644 bicep/modules/azure-kubernetes-service-ingress-dns/metadata.json delete mode 100644 bicep/modules/azure-kubernetes-service-ingress/README.md delete mode 100644 bicep/modules/azure-kubernetes-service-ingress/main.bicep delete mode 100644 bicep/modules/azure-kubernetes-service-ingress/metadata.json delete mode 100644 bicep/modules/azure-kubernetes-service-nodepools/README.md delete mode 100644 bicep/modules/azure-kubernetes-service-nodepools/main.bicep delete mode 100644 bicep/modules/azure-kubernetes-service-nodepools/metadata.json delete mode 100644 bicep/modules/azure-kubernetes-service/README.md delete mode 100644 bicep/modules/azure-kubernetes-service/main.bicep delete mode 100644 bicep/modules/azure-kubernetes-service/metadata.json delete mode 100644 bicep/modules/azure-log-analytics-workspace/README.md delete mode 100644 bicep/modules/azure-log-analytics-workspace/main.bicep delete mode 100644 bicep/modules/azure-log-analytics-workspace/metadata.json delete mode 100644 bicep/modules/azure-managed-prometheus-grafana-for-aks/README.md delete mode 100644 bicep/modules/azure-managed-prometheus-grafana-for-aks/main.bicep delete mode 100644 bicep/modules/azure-managed-prometheus-grafana-for-aks/metadata.json delete mode 100644 bicep/modules/azure-network-security-group/README.md delete mode 100644 bicep/modules/azure-network-security-group/main.bicep delete mode 100644 bicep/modules/azure-network-security-group/metadata.json delete mode 100644 bicep/modules/azure-virtual-network/README.md delete mode 100644 bicep/modules/azure-virtual-network/main.bicep delete mode 100644 bicep/modules/azure-virtual-network/metadata.json delete mode 100644 cloud-native/aks-arm64/README.md delete mode 100644 cloud-native/aks-arm64/azure-voting-app-deploy.yaml delete mode 100644 cloud-native/aks-arm64/bicepconfig.json delete mode 100644 cloud-native/aks-arm64/kustomization.yaml delete mode 100644 cloud-native/aks-arm64/main.bicep delete mode 100644 cloud-native/aks-arm64/main.json delete mode 100644 cloud-native/aks-bicep-k8s/README.md delete mode 100644 cloud-native/aks-bicep-k8s/aks-deploy-app.bicep delete mode 100644 cloud-native/aks-bicep-k8s/aks.bicep delete mode 100644 cloud-native/aks-bicep-k8s/azure-vote.bicep delete mode 100644 cloud-native/aks-bicep-k8s/azure-vote.yaml delete mode 100644 cloud-native/aks-bicep-k8s/azure-voting-app-rust.bicep delete mode 100644 cloud-native/aks-bicep-k8s/azure-voting-app-rust.yaml delete mode 100644 cloud-native/aks-bicep-k8s/bicepconfig.json delete mode 100644 cloud-native/aks-bicep-k8s/dotnet-vue-starter.bicep delete mode 100644 cloud-native/aks-bicep-k8s/dotnet-vue-starter.yaml delete mode 100644 cloud-native/aks-bicep-k8s/go.mod delete mode 100644 cloud-native/aks-bicep-k8s/go.sum delete mode 100644 cloud-native/aks-bicep-k8s/magefile.go delete mode 100644 cloud-native/aks-bicep-k8s/main.bicep delete mode 100644 cloud-native/aks-bicep-k8s/main.json delete mode 100644 cloud-native/aks-bicep-keda/01-aks/README.md delete mode 100644 cloud-native/aks-bicep-keda/01-aks/RESOURCES.md delete mode 100644 cloud-native/aks-bicep-keda/01-aks/aks.bicep delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-aks.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-deploy-script.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-empty.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-keyvault.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-main.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-script-aks.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh delete mode 100644 cloud-native/aks-bicep-keda/01-aks/deploy-script.bicep delete mode 100644 cloud-native/aks-bicep-keda/01-aks/empty.bicep delete mode 100644 cloud-native/aks-bicep-keda/01-aks/keyvault.bicep delete mode 100644 cloud-native/aks-bicep-keda/01-aks/main.bicep delete mode 100644 cloud-native/aks-bicep-keda/01-aks/main.json delete mode 100644 cloud-native/aks-bicep-keda/02-keda/README.md delete mode 100644 cloud-native/aks-bicep-keda/02-keda/deploy/deployment.yaml delete mode 100644 cloud-native/aks-bicep-keda/02-keda/deploy/keda.yaml delete mode 100644 cloud-native/aks-bicep-keda/02-keda/deploy/kustomization.yaml delete mode 100644 cloud-native/aks-bicep-keda/02-keda/deploy/namespace.yaml delete mode 100644 cloud-native/aks-bicep-keda/02-keda/deploy/serviceaccount.yaml delete mode 100644 cloud-native/aks-bicep-keda/03-keda-http/README.md delete mode 100644 cloud-native/aks-bicep-keda/README.md delete mode 100644 cloud-native/aks-bicep/01-aks/README.md delete mode 100644 cloud-native/aks-bicep/01-aks/RESOURCES.md delete mode 100644 cloud-native/aks-bicep/01-aks/aks.bicep delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-aks.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-deploy-script.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-empty.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-keyvault.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-main.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-script-aks.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-script-keda.sh delete mode 100644 cloud-native/aks-bicep/01-aks/deploy-script.bicep delete mode 100644 cloud-native/aks-bicep/01-aks/empty.bicep delete mode 100644 cloud-native/aks-bicep/01-aks/keyvault.bicep delete mode 100644 cloud-native/aks-bicep/01-aks/main.bicep delete mode 100644 cloud-native/aks-bicep/01-aks/main.json delete mode 100644 cloud-native/aks-bicep/README.md delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/README.md delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui-ingressbackend.yaml delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui.yaml delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer.png delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookstore-ui-ingressbackend.yaml delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookstore-ui.yaml delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookstore-v1.png delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookstore_app.png delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui-ingressbackend.yaml delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui.yaml delete mode 100644 cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief.png delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/README.md delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer-ui-secure-ingress.yaml delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer.png delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookstore-ui-secure-ingress.yaml delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookthief-ui-secure-ingress.yaml delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookstore.yaml delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookwarehouse.yaml delete mode 100644 cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-mysql.yaml delete mode 100644 cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/README.md delete mode 100644 cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/bookstore-split.png delete mode 100644 cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/bookstore-ui-v2.yaml delete mode 100644 cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/bookstore-v2.png delete mode 100644 cloud-native/aks-open-service-mesh/README.md delete mode 100644 cloud-native/aks-open-service-mesh/bicepconfig.json delete mode 100644 cloud-native/aks-open-service-mesh/main.bicep delete mode 100644 cloud-native/aks-open-service-mesh/main.json delete mode 100644 cloud-native/aks-webapp-routing/README.md delete mode 100644 cloud-native/aks-webapp-routing/azure-vote-deployment-validation.png delete mode 100644 cloud-native/aks-webapp-routing/azure-vote-deployment.png delete mode 100644 cloud-native/aks-webapp-routing/bicepconfig.json delete mode 100644 cloud-native/aks-webapp-routing/deployment.yaml delete mode 100644 cloud-native/aks-webapp-routing/hello-deployment-2.yaml delete mode 100644 cloud-native/aks-webapp-routing/hello-deployment-validation.png delete mode 100644 cloud-native/aks-webapp-routing/hello-deployment.png delete mode 100644 cloud-native/aks-webapp-routing/main.bicep delete mode 100644 cloud-native/aks-webapp-routing/main.json diff --git a/.github/workflows/publish_bicep_module.yml b/.github/workflows/publish_bicep_module.yml deleted file mode 100644 index e3b0740..0000000 --- a/.github/workflows/publish_bicep_module.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Publish Bicep modules - -on: - workflow_dispatch: - -permissions: - id-token: write - contents: read - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: 'Az CLI login' - uses: azure/login@v1 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - - name: Install Bicep - run: | - az version - az bicep install - - - name: Publish Bicep modules to Azure Container Registry - run: | - for d in */ - do - cd $d - version="v$(cat metadata.json | jq -r '.version.major').$(cat metadata.json | jq -r '.version.minor')" - if [ -z "$(az acr repository show -n ${{ secrets.ACR_SERVER }} --image bicep/modules/${d::-1}:$version 2>/dev/null)" ]; - then - echo "Publishing br:${{ secrets.ACR_SERVER }}/bicep/modules/${d::-1}:$version"; - az bicep publish --file main.bicep --target "br:${{ secrets.ACR_SERVER }}/bicep/modules/${d::-1}:$version"; - else - echo "Skipping br:${{ secrets.ACR_SERVER }}/bicep/modules/${d::-1}:$version as it already exists"; - fi - cd - > /dev/null - done - working-directory: bicep/modules diff --git a/bicep/modules/azure-cli-script/README.md b/bicep/modules/azure-cli-script/README.md deleted file mode 100644 index f9f475f..0000000 --- a/bicep/modules/azure-cli-script/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# azure-cli-script - -This module deploys a [Microsoft.Resources/deploymentScripts](https://learn.microsoft.com/azure/templates/microsoft.resources/deploymentscripts?pivots=deployment-language-bicep) resource to run Azure CLI commands as part of your deployment. The deployment will create a User-Assigned Managed Identity and it will be granted Contributor permissions to perform actions within your subscription. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `azCliVersion` | Azure CLI version | Usually supports latest-1 | -| `cleanupPreference` | Indicates when to cleanup Azure Container Instance | Defaults to `OnSuccess` | -| `scriptContent` | Inline Azure CLI script | | - -## Outputs - -| Name | Description | -|------|-------------| -| N/A | | - -https://learn.microsoft.com/en-us/azure/templates/microsoft.resources/deploymentscripts?pivots=deployment-language-bicep#azurecliscriptproperties \ No newline at end of file diff --git a/bicep/modules/azure-cli-script/main.bicep b/bicep/modules/azure-cli-script/main.bicep deleted file mode 100644 index f059a0d..0000000 --- a/bicep/modules/azure-cli-script/main.bicep +++ /dev/null @@ -1,62 +0,0 @@ -param name string -param location string -param tags object - -@description('https://learn.microsoft.com/en-us/cli/azure/release-notes-azure-cli') -param azCliVersion string = '2.40.0' - -@allowed([ - 'Always' - 'OnExpiration' - 'OnSuccess' -]) -param cleanupPreference string = 'OnSuccess' -param scriptContent string - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: 'uid-${name}' - location: location -} - -// Get the role definition resource by name, to find the name for the role Contributor, you can look -// it up at the following url: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#contributor -resource contributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - scope: subscription() -} - -resource roleAssignmentDeploymentContributor 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(managedIdentity.id, 'Contributor') - properties: { - roleDefinitionId: contributorRoleDefinition.id - principalId: managedIdentity.properties.principalId - principalType: 'ServicePrincipal' - } -} - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: name - location: location - tags: tags - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - kind: 'AzureCLI' - properties: { - azCliVersion: azCliVersion - cleanupPreference: cleanupPreference - containerSettings: { - containerGroupName: 'deploymentScript' - } - retentionInterval: 'PT1H' - scriptContent: scriptContent - timeout: 'PT1H' - } - - dependsOn: [ - roleAssignmentDeploymentContributor - ] -} diff --git a/bicep/modules/azure-cli-script/metadata.json b/bicep/modules/azure-cli-script/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-cli-script/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-container-registry/README.MD b/bicep/modules/azure-container-registry/README.MD deleted file mode 100644 index c179df1..0000000 --- a/bicep/modules/azure-container-registry/README.MD +++ /dev/null @@ -1,23 +0,0 @@ -# azure-container-registry - -This module deploys a [Microsoft.ContainerRegistry/registries](https://learn.microsoft.com/azure/templates/microsoft.containerregistry/registries?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `sku` | SKU to deploy | `'Basic'`
`'Standard'`
`'Premium'` -| `managedIdentityType` | Managed identity type to assign on the resource | `'SystemAssigned'`
`'UserAssigned'` | -| `userAssignedIdentities` | List of user assigned identity resource IDs to assign to the resource when the managed identity type is set to `UserAssigned` | Array of resource IDs | -| `adminUserEnabled` | Enables the admin account | `true` or `false` | -| `anonymousPullEnabled` | Enables anonymous pull access | `true` or `false` | -| `publicNetworkAccess` | Enables public network access | `true` or `false` | - -## Outputs - -| Name | Description | -|------|-------------| -| `name` | This is the name of the resource | diff --git a/bicep/modules/azure-container-registry/main.bicep b/bicep/modules/azure-container-registry/main.bicep deleted file mode 100644 index 4942591..0000000 --- a/bicep/modules/azure-container-registry/main.bicep +++ /dev/null @@ -1,48 +0,0 @@ -param name string -param location string -param tags object - -@allowed([ - 'Basic' - 'Standard' - 'Premium' -]) -@description('Defaults to Standard') -param sku string = 'Standard' - -@allowed([ - 'SystemAssigned' - 'UserAssigned' -]) -@description('Two options are available: SystemAssigned or UserAssigned') -param managedIdentityType string = 'SystemAssigned' - -@description('Required when managed identity type is set to UserAssigned') -param userAssignedIdentities object = {} - -param adminUserEnabled bool = false - -param anonymousPullEnabled bool = false - -@description('Disableing public network access is not supported for Basic and Standard SKUs') -param publicNetworkAccess bool = (sku == 'Premium' ? false : true) - -resource registry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' = { - name: name - location: location - tags: tags - sku: { - name: sku - } - identity: { - type: managedIdentityType - userAssignedIdentities: managedIdentityType != 'SystemAssigned' ? userAssignedIdentities : null - } - properties: { - adminUserEnabled: adminUserEnabled - anonymousPullEnabled: anonymousPullEnabled - publicNetworkAccess: publicNetworkAccess ? 'Enabled' : 'Disabled' - } -} - -output name string = registry.name diff --git a/bicep/modules/azure-container-registry/metadata.json b/bicep/modules/azure-container-registry/metadata.json deleted file mode 100644 index 28e74a8..0000000 --- a/bicep/modules/azure-container-registry/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 2 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-cosmos-db/README.md b/bicep/modules/azure-cosmos-db/README.md deleted file mode 100644 index 541f032..0000000 --- a/bicep/modules/azure-cosmos-db/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# azure-cosmos-db - -This module deploys a [Microsoft.DocumentDB/databaseAccounts](https://learn.microsoft.com/en-us/azure/templates/microsoft.documentdb/databaseaccounts?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `kind` | Type of database account | `'GlobalDocumentDB'`
`'MongoDB'` (default)
`'Parse'` | -| `mongoApiVersion` | MongoApi version | `'3.2'`
`'3.6'`
`'4.0'`
`'4.2'` (default) | -| `managedIdentityType` | Managed identity type to assign on the resource | `'SystemAssigned'`
`'UserAssigned'` | -| `locations` | Array of geo-replication location objects | See: [locations](https://learn.microsoft.com/azure/templates/microsoft.documentdb/databaseaccounts?pivots=deployment-language-bicep#location) | -| `userAssignedIdentities` | List of user assigned identity resource IDs to assign to the resource when the managed identity type is set to `UserAssigned` | Array of resource IDs | - -## Outputs - -| Name | Description | -|------|-------------| diff --git a/bicep/modules/azure-cosmos-db/main.bicep b/bicep/modules/azure-cosmos-db/main.bicep deleted file mode 100644 index 1bd0be6..0000000 --- a/bicep/modules/azure-cosmos-db/main.bicep +++ /dev/null @@ -1,50 +0,0 @@ -param name string -param location string -param tags object - -@allowed([ - 'GlobalDocumentDB' - 'MongoDB' - 'Parse' -]) -param kind string = 'MongoDB' - -@allowed([ - '3.2' - '3.6' - '4.0' - '4.2' -]) -param mongoApiVersion string = '4.2' - -@allowed([ - 'None' - 'SystemAssigned' - 'UserAssigned' - 'SystemAssigned,UserAssigned' -]) -param managedIdentityType string = 'SystemAssigned' - -@description('Used when managedIdentityType is UserAssigned') -param userAssignedIdentities object = {} - -@description('Array of location objects with the following properties: failoverPriority, isZoneRedundant, locationName') -param locations array - -resource databaseAccount 'Microsoft.DocumentDB/databaseAccounts@2022-05-15' = { - name: name - location: location - tags: tags - kind: kind - identity: { - type: managedIdentityType - userAssignedIdentities: empty(userAssignedIdentities) ? null : userAssignedIdentities - } - properties: { - databaseAccountOfferType: 'Standard' - locations: locations - apiProperties: kind == 'MongoDB' ? { - serverVersion: mongoApiVersion - } : null - } -} diff --git a/bicep/modules/azure-cosmos-db/metadata.json b/bicep/modules/azure-cosmos-db/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-cosmos-db/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-dns/README.md b/bicep/modules/azure-dns/README.md deleted file mode 100644 index 9322d5c..0000000 --- a/bicep/modules/azure-dns/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# azure-dns-zone - -This module deploys a [Microsoft.Network/dnsZones](https://learn.microsoft.com/azure/templates/microsoft.network/dnszones?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `zoneType` | Zone type | `'Public'`
`'Private'` | - -## Outputs - -| Name | Description | -|------|-------------| -| `id` | Resource identifier | diff --git a/bicep/modules/azure-dns/main.bicep b/bicep/modules/azure-dns/main.bicep deleted file mode 100644 index ec62a30..0000000 --- a/bicep/modules/azure-dns/main.bicep +++ /dev/null @@ -1,20 +0,0 @@ -param name string -param location string -param tags object - -@allowed([ - 'Public' - 'Private' -]) -param zoneType string - -resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = { - name: name - location: location - tags: tags - properties: { - zoneType: zoneType - } -} - -output id string = dnsZone.id diff --git a/bicep/modules/azure-dns/metadata.json b/bicep/modules/azure-dns/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-dns/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-key-vault/README.md b/bicep/modules/azure-key-vault/README.md deleted file mode 100644 index 97b20a0..0000000 --- a/bicep/modules/azure-key-vault/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# azure-key-vault - -This module deploys a [Microsoft.KeyVault/vaults](https://learn.microsoft.com/azure/templates/microsoft.keyvault/vaults?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. The deployment will set initial access policy for the user that runs the Bicep template and also accepts an array of `resourceAccessPolicies` for additional policy assignments. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `sku` | Resource SKU | `premium` or `standard` (default) | -| `userObjectId` | The user object Id to give full-access to | This is typically the identity that runs the template | -| `tenantId` | The tenant which the objectIds belong to for access policy assignments | | -| `accessPolicies` | Array of `accessPolicy` objects | See: [AccessPolicyEntry](https://learn.microsoft.com/azure/templates/microsoft.keyvault/vaults?pivots=deployment-language-bicep#accesspolicyentry) | - -## Outputs - -| Name | Description | -|------|-------------| diff --git a/bicep/modules/azure-key-vault/main.bicep b/bicep/modules/azure-key-vault/main.bicep deleted file mode 100644 index 4b0d568..0000000 --- a/bicep/modules/azure-key-vault/main.bicep +++ /dev/null @@ -1,57 +0,0 @@ -param name string -param location string -param tags object - -@allowed([ - 'premium' - 'standard' -]) -param sku string = 'standard' - -@description('The object ID of a user, service principal or security group in AAD tenant.') -param userObjectId string -param tenantId string - -@description('List of AccessPolicyEntry which is used when granting additional permissions for other users or managed identities') -param accessPolicies array = [] - -resource vault 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: name - location: location - tags: tags - properties: { - accessPolicies: [ - { - objectId: userObjectId - permissions: { - certificates: [ - 'all' - ] - keys: [ - 'all' - ] - secrets: [ - 'all' - ] - storage: [ - 'all' - ] - } - tenantId: tenantId - } - ] - sku: { - family: 'A' - name: sku - } - tenantId: tenantId - } -} - -resource resourceAccessPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = if (!empty(accessPolicies)) { - name: 'add' - parent: vault - properties: { - accessPolicies: accessPolicies - } -} diff --git a/bicep/modules/azure-key-vault/metadata.json b/bicep/modules/azure-key-vault/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-key-vault/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-kubernetes-service-addons/README.md b/bicep/modules/azure-kubernetes-service-addons/README.md deleted file mode 100644 index b98c121..0000000 --- a/bicep/modules/azure-kubernetes-service-addons/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# azure-kubernetes-service-addons - -This module updates an AKS cluster to append add-ons. [`addonProfiles`](https://learn.microsoft.com/azure/templates/microsoft.containerservice/managedclusters?pivots=deployment-language-bicep#managedclusterproperties) are not very well documented. - -> This Bicep template will emit warnings due to the `mode: 'Incremental'` setting. This module still works and the warning messaging is being tracked here: https://github.com/Azure/bicep/issues/784 - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `clusterId` | Existing cluster resource Id | | -| `addonProfiles` | Add-ons to enable | No concrete definition so your best bet is to deploy using Azure CLI or Portal and see what the JSON metadata looks like | - -## Outputs - -| Name | Description | -|------|-------------| diff --git a/bicep/modules/azure-kubernetes-service-addons/main.bicep b/bicep/modules/azure-kubernetes-service-addons/main.bicep deleted file mode 100644 index 8d3ccf2..0000000 --- a/bicep/modules/azure-kubernetes-service-addons/main.bicep +++ /dev/null @@ -1,18 +0,0 @@ -param location string -param clusterId string - -@description('AKS addons to enable') -param addonProfiles object - -@description('Pull out the cluster name from the resource ID') -var clusterName = split(clusterId, '/')[8] - -resource managedCluster 'Microsoft.ContainerService/managedClusters@2022-08-03-preview' = { - name: clusterName - location: location - properties: { - mode: 'Incremental' - id: clusterId - addonProfiles: addonProfiles - } -} diff --git a/bicep/modules/azure-kubernetes-service-addons/metadata.json b/bicep/modules/azure-kubernetes-service-addons/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-kubernetes-service-addons/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-kubernetes-service-ingress-dns/README.md b/bicep/modules/azure-kubernetes-service-ingress-dns/README.md deleted file mode 100644 index ab03dc1..0000000 --- a/bicep/modules/azure-kubernetes-service-ingress-dns/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# azure-kubernetes-service-ingress-dns - -**Work in Progress** - -This module will take the `principalId` of the `webapprouting` managed identity resource and assign the "DNS Zone Contributor" to it at the Azure DNS resource scope. - -> This Bicep template will emit warnings due to the `mode: 'Incremental'` setting. This module still works and the warning messaging is being tracked here: https://github.com/Azure/bicep/issues/784 - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `dnsZoneName` | The DNS zone name used to pull the existing resource for RBAC assignment | -| `principalId` | The principal id of the user-assigned managed identity that is provisioned in the AKS managed cluster resource group (starts with `MC_*`) | | - -## Outputs - -| Name | Description | -|------|-------------| -| N/A | | diff --git a/bicep/modules/azure-kubernetes-service-ingress-dns/main.bicep b/bicep/modules/azure-kubernetes-service-ingress-dns/main.bicep deleted file mode 100644 index 5da4140..0000000 --- a/bicep/modules/azure-kubernetes-service-ingress-dns/main.bicep +++ /dev/null @@ -1,23 +0,0 @@ -param dnsZoneName string -param principalId string - -resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' existing = { - name: dnsZoneName -} - -// Get the role definition resource by name, to find the name for the role DNS Zone Contributor, you can look -// it up at the following url: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#dns-zone-contributor -resource dnsZoneContributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - scope: subscription() - name: 'befefa01-2a29-4197-83a8-272ff33ce314' -} - -resource dnsZoneContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(dnsZone.id, 'DNS Zone Contributor') - scope: dnsZone - properties: { - roleDefinitionId: dnsZoneContributorRoleDefinition.id - principalId: principalId - principalType: 'User' - } -} diff --git a/bicep/modules/azure-kubernetes-service-ingress-dns/metadata.json b/bicep/modules/azure-kubernetes-service-ingress-dns/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-kubernetes-service-ingress-dns/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-kubernetes-service-ingress/README.md b/bicep/modules/azure-kubernetes-service-ingress/README.md deleted file mode 100644 index 4344e58..0000000 --- a/bicep/modules/azure-kubernetes-service-ingress/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# azure-kubernetes-service-ingress - -This module updates an AKS cluster to install the `webAppRouting` add-on via `ingressProfile`. [`ingressProfiles`](https://learn.microsoft.com/azure/templates/microsoft.containerservice/managedclusters?pivots=deployment-language-bicep#managedclusteringressprofile) requires a [`webAppRouting`](https://learn.microsoft.com/azure/templates/microsoft.containerservice/managedclusters?pivots=deployment-language-bicep#managedclusteringressprofilewebapprouting) object to enable the managed NGINX ingress controller in the cluster. This object accepts an optional `dnsZoneResourceId` to enable the `external-dns` controller. - -> This Bicep template will emit warnings due to the `mode: 'Incremental'` setting. This module still works and the warning messaging is being tracked here: https://github.com/Azure/bicep/issues/784 - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `clusterId` | Existing cluster resource Id | | -| `dnsZoneResourceId` | Azure DNS zone resource identifier | This is optional and not required for `webAppRouting` | - -## Outputs - -| Name | Description | -|------|-------------| -| N/A | | diff --git a/bicep/modules/azure-kubernetes-service-ingress/main.bicep b/bicep/modules/azure-kubernetes-service-ingress/main.bicep deleted file mode 100644 index 1dd47ca..0000000 --- a/bicep/modules/azure-kubernetes-service-ingress/main.bicep +++ /dev/null @@ -1,21 +0,0 @@ -param location string -param clusterId string -param dnsZoneResourceId string = '' - -var clusterName = split(clusterId, '/')[8] -var attachDnsZone = dnsZoneResourceId != '' - -resource updateManagedCluster 'Microsoft.ContainerService/managedClusters@2022-08-03-preview' = { - name: clusterName - location: location - properties: { - mode: 'Incremental' - id: clusterId - ingressProfile: { - webAppRouting: { - dnsZoneResourceId: attachDnsZone ? dnsZoneResourceId : null - enabled: true - } - } - } -} diff --git a/bicep/modules/azure-kubernetes-service-ingress/metadata.json b/bicep/modules/azure-kubernetes-service-ingress/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-kubernetes-service-ingress/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-kubernetes-service-nodepools/README.md b/bicep/modules/azure-kubernetes-service-nodepools/README.md deleted file mode 100644 index 6a7bc44..0000000 --- a/bicep/modules/azure-kubernetes-service-nodepools/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# azure-kubernetes-service-nodepools - -This module deploys a [Microsoft.ContainerService/managedClusters/agentPools](https://learn.microsoft.com/azure/templates/microsoft.containerservice/managedclusters/agentpools?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `managedClusterName` | Name of the AKS resource | Resource name | -| `userNodes` | Array of userNode objects. This is a dynamic object so parameter names will not always match up with template specifications. The Bicep code will iterate through each userNode object and deploy into your AKS resource. | Array of objects | - -## Outputs - -| Name | Description | -|------|-------------| -| N/A | | diff --git a/bicep/modules/azure-kubernetes-service-nodepools/main.bicep b/bicep/modules/azure-kubernetes-service-nodepools/main.bicep deleted file mode 100644 index 5f47c18..0000000 --- a/bicep/modules/azure-kubernetes-service-nodepools/main.bicep +++ /dev/null @@ -1,25 +0,0 @@ -param managedClusterName string -param userNodes array - -// Get the managed cluster by name -resource managedCluster 'Microsoft.ContainerService/managedClusters@2022-08-03-preview' existing = { - name: managedClusterName -} - -resource userNodePools 'Microsoft.ContainerService/managedClusters/agentPools@2024-02-01' = [for i in range(0, length(userNodes)): { - name: userNodes[i].name - parent: managedCluster - properties: { - vmSize: userNodes[i].vmSize - mode: userNodes[i].mode - enableAutoScaling: userNodes[i].enableAutoScaling - count: contains(userNodes[i], 'maxCount') ? userNodes[i].maxCount : 1 - minCount: userNodes[i].enableAutoScaling && contains(userNodes[i], 'minCount') ? userNodes[i].minCount : null - maxCount: userNodes[i].enableAutoScaling && contains(userNodes[i], 'maxCount') ? userNodes[i].maxCount : null - scaleDownMode: userNodes[i].enableAutoScaling && contains(userNodes[i], 'scaleDownMode') ? userNodes[i].scaleDownMode : null - nodeTaints: empty(userNodes[i].nodeTaints) ? null : userNodes[i].nodeTaints - type: userNodes[i].type - osDiskType: userNodes[i].osDiskType - vnetSubnetID: empty(userNodes[i].vnetSubnetID) ? null : userNodes[i].vnetSubnetID - } -}] diff --git a/bicep/modules/azure-kubernetes-service-nodepools/metadata.json b/bicep/modules/azure-kubernetes-service-nodepools/metadata.json deleted file mode 100644 index 28e74a8..0000000 --- a/bicep/modules/azure-kubernetes-service-nodepools/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 2 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-kubernetes-service/README.md b/bicep/modules/azure-kubernetes-service/README.md deleted file mode 100644 index 0de4942..0000000 --- a/bicep/modules/azure-kubernetes-service/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# azure-kubernetes-service - -This module deploys a [Microsoft.ContainerService/managedClusters](https://learn.microsoft.com/azure/templates/microsoft.containerservice/managedclusters?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `slaTier` | Defaults to Free tier | `'Free'`
'Paid' | -| `managedIdentityType` | Two options are available: SystemAssigned or UserAssigned | `'SystemAssigned'`
`'UserAssigned'` | -| `userAssignedIdentities` | Required when managed identity type is set to UserAssigned | | -| `kubernetesVersion` | Default is `1.29` | `'1.29'` | -| `defenderEnabled` | Enables Defender on AKS cluster | `true` or `false` | -| `imageCleanerEnabled` | Enables ImageCleaner on AKS cluster. | `true` or `false` | -| `imageCleanerIntervalHours` | ImageCleaner scanning interval in hours | Number | -| `systemNodeCount` | Number of nodes to deploy in the system node pool | Number | -| `systemNodeVmSize` | Default system node pool size is `Standard_D2s_v5` | A valid SKU available in your chosen Azure region | -| `registryName` | Optional parameter to attach AKS cluster to an existing ACR | Name of your registry (you can omit the `azurecr.io` suffix) | -| `networkPlugin` | Network plugin used for building the Kubernetes network. | `'kubenet'`
`'azure'`
`'none'` | -| `networkPolicy` | Network policy used for building the Kubernetes network. | `'calico'`
`'azure'` | -| `loadBalancerSku` | The default is standard | `'Standard'`
`'Basic'` | -| `dnsServiceIP` | An IP address assigned to the Kubernetes DNS service. It must be within the Kubernetes service address range specified in serviceCidr. | `'10.0.0.10'` | -| `dockerBridgeCidr` | A CIDR notation IP range assigned to the Docker bridge network. It must not overlap with any Subnet IP ranges or the Kubernetes service address range. | `'172.17.0.1/16'` | -| `outboundType` | This can only be set at cluster creation time and cannot be changed later. | `'loadBalancer'`
`'managedNATGateway'`
`'userAssignedNATGateway'`
`'userDefinedRouting'` | -| `podCidrs` | One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking. | `'10.244.0.0/16'` | -| `serviceCidrs` | One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking. They must not overlap with any Subnet IP ranges. | `'10.0.0.0/16'` | -| `ipFamilies` | | `'IPv4'`
`'IPv6'` | -| `vnetSubnetID` | Id of the Vnet to deploy cluster into | | -| `nodeTaints` | Enable nodeTaints on the system node pool (e.g., [\'CriticalAddonsOnly=true:NoSchedule\']) | | -| `addonProfiles` | Add-ons to enable | No concrete definition so your best bet is to deploy using Azure CLI or Portal and see what the JSON metadata looks like | - -## Outputs - -| Name | Description | -|------|-------------| -| `name` | This is the name of the AKS resource | diff --git a/bicep/modules/azure-kubernetes-service/main.bicep b/bicep/modules/azure-kubernetes-service/main.bicep deleted file mode 100644 index 5f5a1c3..0000000 --- a/bicep/modules/azure-kubernetes-service/main.bicep +++ /dev/null @@ -1,211 +0,0 @@ -param name string -param location string -param tags object - -@allowed([ - 'Free' - 'Paid' -]) -@description('Defaults to Free tier') -param slaTier string = 'Free' - -@allowed([ - 'SystemAssigned' - 'UserAssigned' -]) -@description('Two options are available: SystemAssigned or UserAssigned') -param managedIdentityType string = 'SystemAssigned' - -@description('Required when managed identity type is set to UserAssigned') -param userAssignedIdentities object = {} - -@description('Default is 1.29') -param kubernetesVersion string = '1.29' - -param defenderEnabled bool = false - -param imageCleanerEnabled bool = false -param imageCleanerIntervalHours int = 12 - -param systemNodeCount int = 3 - -@description('Default system node pool size is Standard_D2s_v5') -param systemNodeVmSize string = 'Standard_D2s_v5' - -@description('Optional parameter to attach AKS cluster to an existing ACR') -param registryName string = '' - -@allowed([ - 'kubenet' - 'azure' - 'none' -]) -@description('Network plugin used for building the Kubernetes network.') -param networkPlugin string = 'kubenet' - -@allowed([ - 'calico' - 'azure' -]) -@description('Network policy used for building the Kubernetes network.') -param networkPolicy string = 'calico' - -@allowed([ - 'Standard' - 'Basic' -]) -@description('The default is standard.') -param loadBalancerSku string = 'Standard' - -@description('An IP address assigned to the Kubernetes DNS service. It must be within the Kubernetes service address range specified in serviceCidr.') -param dnsServiceIP string = '10.0.0.10' - -@description('A CIDR notation IP range assigned to the Docker bridge network. It must not overlap with any Subnet IP ranges or the Kubernetes service address range.') -param dockerBridgeCidr string = '172.17.0.1/16' - -@description('Resource ID of log analytics workspace for auditing') -param logAnalyticsWorkspaceResourceId string = '' - -@allowed([ - 'loadBalancer' - 'managedNATGateway' - 'userAssignedNATGateway' - 'userDefinedRouting' -]) -@description('This can only be set at cluster creation time and cannot be changed later.') -param outboundType string = 'loadBalancer' - -@description('One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking.') -param podCidrs array = [ - '10.244.0.0/16' -] - -@description('One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking. They must not overlap with any Subnet IP ranges.') -param serviceCidrs array = [ - '10.0.0.0/16' -] - -@allowed([ - 'IPv4' - 'IPv6' -]) -param ipFamilies array = [ - 'IPv4' -] - -@description('If the cluster is using azure network plugin, then you can pass in the subnet resource ID like this `vnet.outputs.subnetId`; otherwise, leave it empty') -param vnetSubnetID string = '' - -@description('Enable nodeTaints on the system node pool (e.g., [\'CriticalAddonsOnly=true:NoSchedule\'])') -param nodeTaints array = [] - -@description('AKS addons to enable') -param addonProfiles object = {} - -param enablePrometheusMetrics bool = false -param prometheusMetricLabelsAllowlist string = '' -param prometheusMetricAnnotationsAllowList string = '' - -resource managedCluster 'Microsoft.ContainerService/managedClusters@2022-08-03-preview' = { - name: name - location: location - tags: tags - sku: { - name: 'Basic' - tier: slaTier - } - identity: { - type: managedIdentityType - userAssignedIdentities: managedIdentityType == 'UserAssigned' ? userAssignedIdentities : null - } - properties: { - kubernetesVersion: kubernetesVersion - dnsPrefix: name - azureMonitorProfile: enablePrometheusMetrics ? { - metrics: { - enabled: true // Requires Microsoft.ContainerService/AKS-PrometheusAddonPreview - kubeStateMetrics: { - metricLabelsAllowlist: prometheusMetricLabelsAllowlist - metricAnnotationsAllowList: prometheusMetricAnnotationsAllowList - } - } - } : null - networkProfile: { - networkPlugin: networkPlugin - networkPolicy: networkPolicy - loadBalancerSku: loadBalancerSku - dnsServiceIP: dnsServiceIP - dockerBridgeCidr: dockerBridgeCidr - outboundType: outboundType - podCidrs: podCidrs - serviceCidrs: serviceCidrs - ipFamilies: ipFamilies - } - agentPoolProfiles: [ - { - name: 'system' - count: systemNodeCount - vmSize: systemNodeVmSize - mode: 'System' - vnetSubnetID: empty(vnetSubnetID) ? null : vnetSubnetID - nodeTaints: empty(nodeTaints) ? null : nodeTaints - } - ] - securityProfile: { - defender: { - securityMonitoring: { - enabled: defenderEnabled - } - } - imageCleaner: { - enabled: imageCleanerEnabled - intervalHours: imageCleanerIntervalHours - } - } - addonProfiles: addonProfiles - } -} - -// Get the registry by name -resource registry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' existing = if (registryName != '') { - name: registryName -} - -// Get the role definition resource by name, to find the name for the role AcrPull, you can look -// it up at the following url: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#acrpull -resource acrPullRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = if (registryName != '') { - scope: subscription() - name: '7f951dda-4ed3-4680-a7ca-43fe172d538d' -} - -// Give the kubelet user assigned managed identity the AcrPull permissions to pull containers from ACR -resource acrPullRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (registryName != '') { - name: guid(managedCluster.id, registryName) - scope: registry - properties: { - principalId: managedCluster.properties.identityProfile.kubeletidentity.objectId - roleDefinitionId: acrPullRoleDefinition.id - } -} - -// Get the role definition resource by name, to find the name for the role Contributor, you can look -// it up at the following url: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#contributor -resource contributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - scope: subscription() - name: 'b24988ac-6180-42a0-ab88-20f7382dd24c' -} - -// Give the managedCluster identity the Contributor permissions -resource contribtorRoleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(managedCluster.id, resourceGroup().id) - scope: resourceGroup() - properties: { - principalId: managedCluster.identity.principalId - roleDefinitionId: contributorRoleDefinition.id - } -} - -output name string = managedCluster.name -output id string = managedCluster.id -output kubeletIdentityObjectId string = managedCluster.properties.identityProfile.kubeletidentity.objectId -output nodeResourceGroupName string = managedCluster.properties.nodeResourceGroup diff --git a/bicep/modules/azure-kubernetes-service/metadata.json b/bicep/modules/azure-kubernetes-service/metadata.json deleted file mode 100644 index 28e74a8..0000000 --- a/bicep/modules/azure-kubernetes-service/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 2 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-log-analytics-workspace/README.md b/bicep/modules/azure-log-analytics-workspace/README.md deleted file mode 100644 index 8630572..0000000 --- a/bicep/modules/azure-log-analytics-workspace/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# azure-log-analytics-workspace - -This module deploys a [Microsoft.OperationalInsights/workspaces](https://learn.microsoft.com/azure/templates/microsoft.operationalinsights/workspaces?pivots=deployment-language-bicep) resource. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | - -## Outputs - -| Name | Description | -|------|-------------| -| `id` | This is the id of the virtual network resource | diff --git a/bicep/modules/azure-log-analytics-workspace/main.bicep b/bicep/modules/azure-log-analytics-workspace/main.bicep deleted file mode 100644 index c7297b0..0000000 --- a/bicep/modules/azure-log-analytics-workspace/main.bicep +++ /dev/null @@ -1,17 +0,0 @@ -param name string -param location string -param tags object - -resource workspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { - name: name - location: location - tags: tags - properties: { - retentionInDays: 30 - sku: { - name: 'PerGB2018' - } - } -} - -output id string = workspace.id diff --git a/bicep/modules/azure-log-analytics-workspace/metadata.json b/bicep/modules/azure-log-analytics-workspace/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-log-analytics-workspace/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-managed-prometheus-grafana-for-aks/README.md b/bicep/modules/azure-managed-prometheus-grafana-for-aks/README.md deleted file mode 100644 index 94fd15e..0000000 --- a/bicep/modules/azure-managed-prometheus-grafana-for-aks/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# azure-managed-prometheus-grafana-for-aks - -This module deploys a [Microsoft.Dashboard/grafana](https://learn.microsoft.com/en-us/azure/templates/microsoft.dashboard/grafana?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | - -## Outputs - -| Name | Description | -|------|-------------| - diff --git a/bicep/modules/azure-managed-prometheus-grafana-for-aks/main.bicep b/bicep/modules/azure-managed-prometheus-grafana-for-aks/main.bicep deleted file mode 100644 index 515521a..0000000 --- a/bicep/modules/azure-managed-prometheus-grafana-for-aks/main.bicep +++ /dev/null @@ -1,370 +0,0 @@ -param name string - -@allowed([ - 'eastus2euap' - 'centraluseuap' - 'centralus' - 'eastus' - 'eastus2' - 'northeurope' - 'southcentralus' - 'southeastasia' - 'uksouth' - 'westeurope' - 'westus' - 'westus2' -]) -param location string - -param tags object - -@allowed([ - 'SystemAssigned' - 'UserAssigned' -]) -@description('Two options are available: SystemAssigned or UserAssigned') -param managedIdentityType string = 'SystemAssigned' - -@description('Required when managed identity type is set to UserAssigned') -param userAssignedIdentities object = {} - -param publicNetworkAccess bool = true - -param zoneRedundancy bool = false - -param clusterName string - -param metricLabelsAllowlist string = '' -param metricAnnotationsAllowList string = '' - -param userObjectId string - -resource monitor 'microsoft.monitor/accounts@2021-06-03-preview' = { - name: name - location: location -} - -resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-09-01-preview' = { - name: 'MSPROM-${clusterName}-${location}' - location: location - kind: 'Linux' - properties: { - } -} - -resource dataCollectionRule 'Microsoft.Insights/dataCollectionRules@2021-09-01-preview' = { - name: 'MSPROM-${clusterName}-${location}' - location: location - kind: 'Linux' - properties: { - dataCollectionEndpointId: dataCollectionEndpoint.id - dataFlows: [ - { - destinations: [ - 'MonitoringAccount1' - ] - streams: [ - 'Microsoft-PrometheusMetrics' - ] - } - ] - dataSources: { - prometheusForwarder: [ - { - name: 'PrometheusDataSource' - streams: [ - 'Microsoft-PrometheusMetrics' - ] - labelIncludeFilter: { - } - } - ] - } - description: 'Data collection rule for Azure Monitor Metrics Profile (Managed Prometheus)' - destinations: { - monitoringAccounts: [ - { - accountResourceId: monitor.id - name: 'MonitoringAccount1' - } - ] - } - } -} - -resource dataCollectionRuleAssociation 'Microsoft.ContainerService/managedClusters/providers/dataCollectionRuleAssociations@2021-09-01-preview' = { - name: '${clusterName}/microsoft.insights/MSPROM-${clusterName}--${location}' - location: location - properties: { - description: 'Association of data collection rule. Deleting this association will break the data collection for this AKS Cluster.' - dataCollectionRuleId: dataCollectionRule.id - } - - dependsOn: [ - dataCollectionEndpoint - ] -} - -resource cluster 'Microsoft.ContainerService/managedClusters@2022-07-02-preview' existing = { - name: clusterName -} - -resource azureMonitorProfile 'Microsoft.ContainerService/managedClusters@2022-07-02-preview' = { - name: clusterName - location: location - properties: { - mode: 'Incremental' - id: cluster.id - azureMonitorProfile: { - metrics: { - enabled: true - kubeStateMetrics: { - metricLabelsAllowlist: metricLabelsAllowlist - metricAnnotationsAllowList: metricAnnotationsAllowList - } - } - } - } - - dependsOn: [ - cluster - dataCollectionRuleAssociation - ] -} - -resource nodeRecordingRuleGroup 'Microsoft.AlertsManagement/prometheusRuleGroups@2021-07-22-preview' = { - name: 'NodeRecordingRulesRuleGroup-${clusterName}' - location: location - properties: { - description: 'Node Recording Rules RuleGroup - 0.1' - scopes: [ - monitor.id - ] - clusterName: clusterName - interval: 'PT1M' - rules: [ - { - record: 'instance:node_num_cpu:sum' - expression: 'count without (cpu, mode) ( node_cpu_seconds_total{job="node",mode="idle"})' - } - { - record: 'instance:node_cpu_utilisation:rate5m' - expression: '1 - avg without (cpu) ( sum without (mode) (rate(node_cpu_seconds_total{job="node", mode=~"idle|iowait|steal"}[5m])))' - } - { - record: 'instance:node_load1_per_cpu:ratio' - expression: '( node_load1{job="node"}/ instance:node_num_cpu:sum{job="node"})' - } - { - record: 'instance:node_memory_utilisation:ratio' - expression: '1 - ( ( node_memory_MemAvailable_bytes{job="node"} or ( node_memory_Buffers_bytes{job="node"} + node_memory_Cached_bytes{job="node"} + node_memory_MemFree_bytes{job="node"} + node_memory_Slab_bytes{job="node"} ) )/ node_memory_MemTotal_bytes{job="node"})' - } - { - record: 'instance:node_vmstat_pgmajfault:rate5m' - expression: 'rate(node_vmstat_pgmajfault{job="node"}[5m])' - } - { - record: 'instance_device:node_disk_io_time_seconds:rate5m' - expression: 'rate(node_disk_io_time_seconds_total{job="node", device!=""}[5m])' - } - { - record: 'instance_device:node_disk_io_time_weighted_seconds:rate5m' - expression: 'rate(node_disk_io_time_weighted_seconds_total{job="node", device!=""}[5m])' - } - { - record: 'instance:node_network_receive_bytes_excluding_lo:rate5m' - expression: 'sum without (device) ( rate(node_network_receive_bytes_total{job="node", device!="lo"}[5m]))' - } - { - record: 'instance:node_network_transmit_bytes_excluding_lo:rate5m' - expression: 'sum without (device) ( rate(node_network_transmit_bytes_total{job="node", device!="lo"}[5m]))' - } - { - record: 'instance:node_network_receive_drop_excluding_lo:rate5m' - expression: 'sum without (device) ( rate(node_network_receive_drop_total{job="node", device!="lo"}[5m]))' - } - { - record: 'instance:node_network_transmit_drop_excluding_lo:rate5m' - expression: 'sum without (device) ( rate(node_network_transmit_drop_total{job="node", device!="lo"}[5m]))' - } - ] - } -} - -resource kubernetesRecordingRuleGroup 'Microsoft.AlertsManagement/prometheusRuleGroups@2021-07-22-preview' = { - name: 'KubernetesReccordingRulesRuleGroup-${clusterName}' - location: location - properties: { - description: 'Kubernetes Recording Rules RuleGroup - 0.1' - scopes: [ - monitor.id - ] - clusterName: clusterName - interval: 'PT1M' - rules: [ - { - record: 'node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate' - expression: 'sum by (cluster, namespace, pod, container) ( irate(container_cpu_usage_seconds_total{job="cadvisor", image!=""}[5m])) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) ( 1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=""}))' - } - { - record: 'node_namespace_pod_container:container_memory_working_set_bytes' - expression: 'container_memory_working_set_bytes{job="cadvisor", image!=""}* on (namespace, pod) group_left(node) topk by(namespace, pod) (1, max by(namespace, pod, node) (kube_pod_info{node!=""}))' - } - { - record: 'node_namespace_pod_container:container_memory_rss' - expression: 'container_memory_rss{job="cadvisor", image!=""}* on (namespace, pod) group_left(node) topk by(namespace, pod) (1, max by(namespace, pod, node) (kube_pod_info{node!=""}))' - } - { - record: 'node_namespace_pod_container:container_memory_cache' - expression: 'container_memory_cache{job="cadvisor", image!=""}* on (namespace, pod) group_left(node) topk by(namespace, pod) (1, max by(namespace, pod, node) (kube_pod_info{node!=""}))' - } - { - record: 'node_namespace_pod_container:container_memory_swap' - expression: 'container_memory_swap{job="cadvisor", image!=""}* on (namespace, pod) group_left(node) topk by(namespace, pod) (1, max by(namespace, pod, node) (kube_pod_info{node!=""}))' - } - { - record: 'cluster:namespace:pod_memory:active:kube_pod_container_resource_requests' - expression: 'kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster)group_left() max by (namespace, pod, cluster) ( (kube_pod_status_phase{phase=~"Pending|Running"} == 1))' - } - { - record: 'namespace_memory:kube_pod_container_resource_requests:sum' - expression: 'sum by (namespace, cluster) ( sum by (namespace, pod, cluster) ( max by (namespace, pod, container, cluster) ( kube_pod_container_resource_requests{resource="memory",job="kube-state-metrics"} ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( kube_pod_status_phase{phase=~"Pending|Running"} == 1 ) ))' - } - { - record: 'cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests' - expression: 'kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster)group_left() max by (namespace, pod, cluster) ( (kube_pod_status_phase{phase=~"Pending|Running"} == 1))' - } - { - record: 'namespace_cpu:kube_pod_container_resource_requests:sum' - expression: 'sum by (namespace, cluster) ( sum by (namespace, pod, cluster) ( max by (namespace, pod, container, cluster) ( kube_pod_container_resource_requests{resource="cpu",job="kube-state-metrics"} ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( kube_pod_status_phase{phase=~"Pending|Running"} == 1 ) ))' - } - { - record: 'cluster:namespace:pod_memory:active:kube_pod_container_resource_limits' - expression: 'kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} * on (namespace, pod, cluster)group_left() max by (namespace, pod, cluster) ( (kube_pod_status_phase{phase=~"Pending|Running"} == 1))' - } - { - record: 'namespace_memory:kube_pod_container_resource_limits:sum' - expression: 'sum by (namespace, cluster) ( sum by (namespace, pod, cluster) ( max by (namespace, pod, container, cluster) ( kube_pod_container_resource_limits{resource="memory",job="kube-state-metrics"} ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( kube_pod_status_phase{phase=~"Pending|Running"} == 1 ) ))' - } - { - record: 'cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits' - expression: 'kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} * on (namespace, pod, cluster)group_left() max by (namespace, pod, cluster) ( (kube_pod_status_phase{phase=~"Pending|Running"} == 1) )' - } - { - record: 'namespace_cpu:kube_pod_container_resource_limits:sum' - expression: 'sum by (namespace, cluster) ( sum by (namespace, pod, cluster) ( max by (namespace, pod, container, cluster) ( kube_pod_container_resource_limits{resource="cpu",job="kube-state-metrics"} ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) ( kube_pod_status_phase{phase=~"Pending|Running"} == 1 ) ))' - } - { - record: 'namespace_workload_pod:kube_pod_owner:relabel' - expression: 'max by (cluster, namespace, workload, pod) ( label_replace( label_replace( kube_pod_owner{job="kube-state-metrics", owner_kind="ReplicaSet"}, "replicaset", "$1", "owner_name", "(.*)" ) * on(replicaset, namespace) group_left(owner_name) topk by(replicaset, namespace) ( 1, max by (replicaset, namespace, owner_name) ( kube_replicaset_owner{job="kube-state-metrics"} ) ), "workload", "$1", "owner_name", "(.*)" ))' - labels: { - workload_type: 'deployment' - } - } - { - record: 'namespace_workload_pod:kube_pod_owner:relabel' - expression: 'max by (cluster, namespace, workload, pod) ( label_replace( kube_pod_owner{job="kube-state-metrics", owner_kind="DaemonSet"}, "workload", "$1", "owner_name", "(.*)" ))' - labels: { - workload_type: 'daemonset' - } - } - { - record: 'namespace_workload_pod:kube_pod_owner:relabel' - expression: 'max by (cluster, namespace, workload, pod) ( label_replace( kube_pod_owner{job="kube-state-metrics", owner_kind="StatefulSet"}, "workload", "$1", "owner_name", "(.*)" ))' - labels: { - workload_type: 'statefulset' - } - } - { - record: 'namespace_workload_pod:kube_pod_owner:relabel' - expression: 'max by (cluster, namespace, workload, pod) ( label_replace( kube_pod_owner{job="kube-state-metrics", owner_kind="Job"}, "workload", "$1", "owner_name", "(.*)" ))' - labels: { - workload_type: 'job' - } - } - { - record: ':node_memory_MemAvailable_bytes:sum' - expression: 'sum( node_memory_MemAvailable_bytes{job="node"} or ( node_memory_Buffers_bytes{job="node"} + node_memory_Cached_bytes{job="node"} + node_memory_MemFree_bytes{job="node"} + node_memory_Slab_bytes{job="node"} )) by (cluster)' - } - { - record: 'cluster:node_cpu:ratio_rate5m' - expression: 'sum(rate(node_cpu_seconds_total{job="node",mode!="idle",mode!="iowait",mode!="steal"}[5m])) by (cluster) /count(sum(node_cpu_seconds_total{job="node"}) by (cluster, instance, cpu)) by (cluster)' - } - ] - } -} - -resource grafana 'Microsoft.Dashboard/grafana@2022-08-01' = { - name: name - location: location - tags: tags - sku: { - name: 'Standard' - } - identity: { - type: managedIdentityType - userAssignedIdentities: managedIdentityType == 'UserAssigned' ? userAssignedIdentities : null - } - properties: { - apiKey: 'Enabled' - autoGeneratedDomainNameLabelScope: 'TenantReuse' - deterministicOutboundIP: 'Enabled' - grafanaIntegrations: { - azureMonitorWorkspaceIntegrations: [ - { - azureMonitorWorkspaceResourceId: monitor.id - } - ] - } - publicNetworkAccess: publicNetworkAccess ? 'Enabled' : 'Disabled' - zoneRedundancy: zoneRedundancy ? 'Enabled' : 'Disabled' - } -} - -@description('This is the built-in Monitoring Reader role.') -resource monitoringReaderRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { - scope: subscription() - name: '43d0d8ad-25c7-4714-9337-8ba259a9fe05' //Monitoring Reader -} - -resource monitoringReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, grafana.id) - scope: resourceGroup() - properties: { - roleDefinitionId: monitoringReaderRoleDefinition.id - principalId: grafana.identity.principalId - principalType: 'ServicePrincipal' - } -} - -@description('This is the built-in Monitoring Data Reader role.') -resource monitoringDataReaderRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { - scope: subscription() - name: 'b0d8363b-8ddd-447d-831f-62ca05bff136' //Monitoring Data Reader -} - -resource monitorDataReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(monitor.id, grafana.id) - scope: monitor - properties: { - roleDefinitionId: monitoringDataReaderRoleDefinition.id - principalId: grafana.identity.principalId - principalType: 'ServicePrincipal' - } -} - -@description('This is the built-in Grafana Admin role.') -resource grafanaAdminRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { - scope: subscription() - name: '22926164-76b3-42b3-bc55-97df8dab3e41' //Grafana Admin -} - -resource grafanaAdminRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(grafana.id, userObjectId) - scope: grafana - properties: { - roleDefinitionId: grafanaAdminRoleDefinition.id - principalId: userObjectId - principalType: 'User' - } -} diff --git a/bicep/modules/azure-managed-prometheus-grafana-for-aks/metadata.json b/bicep/modules/azure-managed-prometheus-grafana-for-aks/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-managed-prometheus-grafana-for-aks/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-network-security-group/README.md b/bicep/modules/azure-network-security-group/README.md deleted file mode 100644 index ce336da..0000000 --- a/bicep/modules/azure-network-security-group/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# azure-network-security-group - -This module deploys a [Microsoft.Network/networkSecurityGroups](https://learn.microsoft.com/azure/templates/microsoft.network/networksecuritygroups?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | - -## Outputs - -| Name | Description | -|------|-------------| -| `id` | This is the id of the resource | diff --git a/bicep/modules/azure-network-security-group/main.bicep b/bicep/modules/azure-network-security-group/main.bicep deleted file mode 100644 index 8f43dca..0000000 --- a/bicep/modules/azure-network-security-group/main.bicep +++ /dev/null @@ -1,14 +0,0 @@ -param name string -param tags object -param location string - -resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2022-01-01' = { - name: name - location: location - properties: { - securityRules: [] - } - tags: tags -} - -output id string = networkSecurityGroup.id diff --git a/bicep/modules/azure-network-security-group/metadata.json b/bicep/modules/azure-network-security-group/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-network-security-group/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/bicep/modules/azure-virtual-network/README.md b/bicep/modules/azure-virtual-network/README.md deleted file mode 100644 index 3434f99..0000000 --- a/bicep/modules/azure-virtual-network/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# azure-virtual-network - -This module deploys a [Microsoft.Network/virtualNetworks](https://learn.microsoft.com/azure/templates/microsoft.network/virtualnetworks?pivots=deployment-language-bicep) resource with a single [Microsoft.Network/virtualNetworks/subnets](https://learn.microsoft.com/azure/templates/microsoft.network/virtualnetworks/subnets?pivots=deployment-language-bicep) resource using only parameters scoped for these labs. - -## Inputs - -| Name | Description | Expected Value | -|------|-------------|----------------| -| `name` | This is the name of the resource | Whatever you want | -| `location` | Region to deploy resource into | Azure region that offers this resource | -| `tags` | Tags | Object of key/value pairs | -| `vnetAddressPrefix` | Network CIDR range | Ex: 10.21.0.0/16 | -| `snetAddressPrefix` | Subnet CIDR range | Ex: 10.21.0.0/24 | -| `snetName` | Name of the subnet | Whatever you want | -| `networkSecurityGroupId` | Resource ID of the network security group. This will be associated to the subnet | Resource ID | -| `dnsServer` | Optionally, set a DNS server IP or leave empty to use Azure DNS | IP address or empty string | - -## Outputs - -| Name | Description | -|------|-------------| -| `id` | This is the id of the virtual network resource | -| `name` | This is the name of the virtual network resource | -| `subnetId` | This is the id of the subnet resource | diff --git a/bicep/modules/azure-virtual-network/main.bicep b/bicep/modules/azure-virtual-network/main.bicep deleted file mode 100644 index 0685e23..0000000 --- a/bicep/modules/azure-virtual-network/main.bicep +++ /dev/null @@ -1,41 +0,0 @@ -param name string -param location string -param tags object -param vnetAddressPrefix string -param snetAddressPrefix string -param snetName string -param networkSecurityGroupId string -param dnsServer string - -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-01-01' = { - name: name - location: location - tags: tags - properties: { - addressSpace: { - addressPrefixes: [ - vnetAddressPrefix - ] - } - dhcpOptions: (!empty(dnsServer) ? { - dnsServers: [ - dnsServer - ] - } : null) - subnets: [ - { - name: snetName - properties: { - addressPrefix: snetAddressPrefix - networkSecurityGroup: { - id: networkSecurityGroupId - } - } - } - ] - } -} - -output id string = virtualNetwork.id -output name string = virtualNetwork.name -output subnetId string = virtualNetwork.properties.subnets[0].id diff --git a/bicep/modules/azure-virtual-network/metadata.json b/bicep/modules/azure-virtual-network/metadata.json deleted file mode 100644 index 7dd04c0..0000000 --- a/bicep/modules/azure-virtual-network/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": { - "major": 0, - "minor": 1 - } -} \ No newline at end of file diff --git a/cloud-native/README.md b/cloud-native/README.md index 9678adb..8f793fb 100644 --- a/cloud-native/README.md +++ b/cloud-native/README.md @@ -13,12 +13,11 @@ ## Azure Kubernetes Service -- [Lab: Explore KEDA (Kubernetes Event-driven Autoscaling) and the KEDA HTTP Add-on with Azure Kubernetes Service (AKS) and Bicep](aks-bicep-keda/) +- Lab: Explore KEDA (Kubernetes Event-driven Autoscaling) and the KEDA HTTP Add-on with Azure Kubernetes Service (AKS) and Bicep (returning soon) - [Lab: Deploy a Scalable and Secure Azure Kubernetes Service cluster using the Azure CLI](aks-https/) -- [Lab: Azure Kubernetes Service with ARM64 node pools](aks-arm64/) +- Lab: Azure Kubernetes Service with ARM64 node pools (returning soon) - [Lab: Azure Kubernetes Service with ARM64 node pools and Terraform](aks-arm64-terraform/) -- [Lab: Web Application Routing with Azure Kubernetes Service](aks-webapp-routing/) -- [Lab: Azure Kubernetes Service with Open Service Mesh](./aks-open-service-mesh/) +- Lab: Web Application Routing with Azure Kubernetes Service (returning soon) - [Lab: Azure Kubernetes Service with Open Service Mesh and Terraform](./aks-open-service-mesh-terraform/) - [Run scalable and resilient Redis with Kubernetes and Azure Kubernetes Service (techcommunity.microsoft.com)](https://techcommunity.microsoft.com/t5/apps-on-azure-blog/run-scalable-and-resilient-redis-with-kubernetes-and-azure/ba-p/3247956) - [Walkthrough (aaronmsft.com)](https://aaronmsft.com/posts/oss-aks-redis/) diff --git a/cloud-native/aks-arm64/README.md b/cloud-native/aks-arm64/README.md deleted file mode 100644 index 2b76cbc..0000000 --- a/cloud-native/aks-arm64/README.md +++ /dev/null @@ -1,368 +0,0 @@ -# Azure Kubernetes Service with ARM64 node pools - -This lab will walk you though deploying Azure Kubernetes Service (AKS) with ARM64-based user node pools and deploy a sample application to it. - -You will perform the following tasks: - -* Provision Azure resources -* Build and publish ARM64-based container to Azure Container Registry -* Deploy ARM64-based image to Azure Kubernetes Service - -As part of the application deployment process, we'll also explore some things you can do to ensure your container images are prepared for ARM64-based OS architecture. - -## Requirements - -* An Azure Subscription (e.g. [Free](https://aka.ms/azure-free-account) or [Student](https://aka.ms/azure-student-account) account) -* The [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli) -* A [GitHub](https://github.com/) account -* The [GitHub CLI](https://cli.github.com/) -* Bash shell (e.g. macOS, Linux, [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/windows/wsl/about), [Multipass](https://multipass.run/), [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/quickstart), [GitHub Codespaces](https://github.com/features/codespaces), etc) -* The [Docker CLI](https://www.docker.com/products/docker-desktop/) - -> **⚠️ NOTE** -> -> This deployment uses Azure Bicep templates to provision Azure infrastructure. If you'd like to use Terraform instead, head over to [Azure Kubernetes Service with ARM64 node pools and Terraform](../aks-arm64-terraform#deploy-azure-resources-using-terraform) then come back to complete the remainder of the steps in this lab guide. - -[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2Fazure-opensource-labs%2Fmain%2Fcloud-native%2Faks-arm64%2Fmain.json) - -> Use the button above if you'd like to deploy using the Azure Portal instead of Azure CLI commands. - -## Deploy Azure Resources using Azure Bicep - -Start by cloning this repo and navigating to the `cloud-native/aks-arm64` directory. - -```bash -git clone https://github.com/Azure-Samples/azure-opensource-labs.git -cd azure-opensource-labs/cloud-native/aks-arm64 -``` - -Next, make sure you are logged into Azure CLI - -```bash -az login -``` - -If you have access to multiple subscriptions, you can select the proper subscription to use with the following command: - -```bash -az account set -s -``` - -> **⚠️ NOTE** -> -> You will need proper permissions in your subscription as the AKS deployment will require granting the `AcrPull` permissions to the `kubelets` on the AKS cluster, so that images can be pulled from your Azure Container Registry. - -Prepare for deployment by setting a few environment variables. You will need to pass in a `location` (aka Azure region) that [supports your deployment resources](https://azure.microsoft.com/explore/global-infrastructure/products-by-region/?products=container-registry,kubernetes-service) and SKUs as well as a `name` for your resource deployments. - -> **💡 TIP** -> -> To validate that a VM SKU is available in your preferred Azure region you can run a command like this: -> -> az vm list-sizes --location $location --query "[? contains(name, 'Standard_Dpds_v5')]" -o table` - -The `name` variable will be used to name Azure resources. The naming convention used wil be adopted from this [guide](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming#example-names-general). Some resources have specific requirements around resource naming so it is generally safe to use shorter alphanumeric names and ensure they will be globally unique since ACR names must meet this criteria. - -Set up your `location` and `name` variables. - -```bash -location=eastus -name=arm$RANDOM -``` - -Run the Bicep template deployment using the following command: - -```bash -az deployment sub create --name "$name-deploy" --location $location -f ./main.bicep --parameters name=$name location=$location -``` - -The deployment of Azure resources can take up to 10 minutes to complete. If you are interested in learning how the Bicep template modules work, click the `show` link below. - -
show - -The [main.bicep](./main.bicep) file deploys the following resources in your subscription: - -* Azure Resource Group -* Azure Container Registry -* Azure Kubernetes Cluster with system node pool -* ARM64-based user node pool with SKU (`Standard_D4pds_v5`) - -The template leverages Bicep modules which have been published to a separate ACR (`cloudnativeadvocates.azurecr.io`). To avoid having to include the ACR server name in all module calls, the ACR server name has been aliased in the [bicepconfig.json](./bicepconfig.json) file. - -The code for each Bicep module is hosted in this repo in the [bicep/modules](/bicep/modules/) directory. There you will find subdirectories for each of the modules we use for this lab's deployment. - -Within each module's subdirectory, there is a `README.md` file with additional information on the inputs and outputs for each module including links to the [resource template](https://learn.microsoft.com/azure/templates/) documentation. - -Here's a quick summary of the resources being deployed - -### Azure Resource Group - -This deployment is at subscription scope, so we create a resource group in the `main.bicep` file to deploy all resources for this lab. - -### Azure Container Registry - -Uses `br/oss-labs:bicep/modules/azure-container-registry:v0.1` module to deploy a private container registry in which we will publish our sample container image to. - -This ACR resource will have the admin account enabled to be able to publish container images using GitHub Actions. - -### Azure Kubernetes Cluster with system node pool - -Uses `br/oss-labs:bicep/modules/azure-kubernetes-service:v0.1` to deploy a managed cluster with Kubernetes version `1.24.3`. Some of the basic options have been enabled such as using a standard load balancer for inbound services and outbound NAT. The system node pool will use the `Standard_D2s_v5` Virtual Machine Scale Set SKU and deploy `2` instances. - -AKS clusters can be provisioned with Defender enabled; however, at the time of this writing, ARM64-based node pools are not supported when AKS clusters have Defender enabled. - -This AKS cluster will also have the ACR "attached" by granting the `kubelet` managed identity the `AcrPull` role assignment on the ACR resource. - -### ARM64-based user node pool with SKU (`Standard_D4pds_v5`) - -Uses `br/oss-labs:bicep/modules/azure-kubernetes-service-nodepools:v0.1` module to deploy a 2-node ARM64-based node pool with SKU `Standard_D4pds_v5`. This module accepts `userNodes` which is an array of dynamic objects. Each of the dynamic object properties are mapped to Bicep template properties in the module implementation. - -With the node pool type of `VirtualMachineScaleSets`, we can enable autoscaling. You can specify the scale down mode to either `Deallocate` or `Delete`. This lab sets it to `Deallocate` to ensure faster scale up/down times; therefore, the `osDiskType` setting must be set to `Managed` so that Azure persists the OS disks. - -> The default `osDiskType` is `Ephemeral` - -This user node pool will auto scale from `0` to `3` instances based on load - -If you want to ensure only specific workloads are scheduled on your user node pools, you can add `nodeTaints`. Refer to this [doc](https://learn.microsoft.com/azure/aks/use-multiple-node-pools#setting-nodepool-taints) for additional information. -

-
- -Once the deployment has completed, you can run the following command to gain access to the cluster: - -```bash -az aks get-credentials --resource-group "rg-${name}" --name "aks-${name}" -``` - -To verify the cluster is up, run the command `kubectl get nodes -o wide` and should see something like this - -```bash -kubectl get nodes -o wide -NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME -aks-arm64-10552501-vmss000000 NotReady agent 139m v1.24.3 10.21.0.62 Ubuntu 22.04.1 LTS 5.15.0-1019-azure containerd://1.6.4+azure-4 -aks-arm64-10552501-vmss000001 NotReady agent 139m v1.24.3 10.21.0.91 Ubuntu 22.04.1 LTS 5.15.0-1019-azure containerd://1.6.4+azure-4 -aks-arm64-10552501-vmss000002 NotReady agent 139m v1.24.3 10.21.0.120 Ubuntu 22.04.1 LTS 5.15.0-1019-azure containerd://1.6.4+azure-4 -aks-system-23779925-vmss000000 Ready agent 143m v1.24.3 10.21.0.4 Ubuntu 18.04.6 LTS 5.4.0-1090-azure containerd://1.6.4+azure-4 -aks-system-23779925-vmss000001 Ready agent 143m v1.24.3 10.21.0.33 Ubuntu 18.04.6 LTS 5.4.0-1090-azure containerd://1.6.4+azure-4 -``` - -> 💡 TIP -> -> If you do not have `kubectl` installed on your system, you can run the following command to install it: -> -> `az aks install-cli` - -## Deploying `ARM64` workloads to Kubernetes - -With the ARM64-based user node pool deployed, we can begin deploying our first workload onto it. - -We will deploy the famous [Azure Voting App](https://learn.microsoft.com/azure/aks/tutorial-kubernetes-prepare-app) which can be found in many AKS tutorials, labs, blogs, etc. - -![Azure Voting App](https://learn.microsoft.com/en-us/azure/aks/media/container-service-kubernetes-tutorials/azure-vote-local.png) - -This application is a multi-container application and upon inspection of the [`docker-compose.yaml`](https://github.com/Azure-Samples/azure-voting-app-redis/blob/master/docker-compose.yaml) file, we can see it uses the `mcr.microsoft.com/oss/bitnami/redis:6.0.8` image for the backend and the `mcr.microsoft.com/azuredocs/azure-vote-front:v1` for the frontend. - -In order for Kubernetes to schedule containers to your ARM64-based node pool, the container images must be published to support the appropriate OS architectures. - -### Investigation - -You can inspect the container manifests by running the following commands: - -```bash -docker manifest inspect mcr.microsoft.com/azuredocs/azure-vote-front:v1 -docker manifest inspect mcr.microsoft.com/oss/bitnami/redis:6.0.8 -``` - -Unfortunately, neither of these images support `arm64` architecture 😞 - -Let's check if Redis has an updated image on Docker Hub that supports `arm64` - -```bash -docker manifest inspect redis:latest -``` - -From the output, we can see it does 🥳 - -```json -... -{ - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 1572, - "digest": "sha256:6444b125d6e2b7aae5732039a22bf4abb92bcb1535cefe89e52bb269f6374826", - "platform": { - "architecture": "arm64", - "os": "linux", - "variant": "v8" - } -} -... -``` - -Easy enough, we can swap out `mcr.microsoft.com/oss/bitnami/redis:6.0.8` with `redis:latest` and fix that dependency 😅 - -Now, browse to the [source repo](https://github.com/Azure-Samples/azure-voting-app-redis) for the Azure Voting App and view the [Dockerfile](https://github.com/Azure-Samples/azure-voting-app-redis/blob/master/azure-vote/Dockerfile) to see how the image is built. - -From the Dockerfile, we can see it is using `tiangolo/uwsgi-nginx-flask:python3.6` as a base image. - -If we run the `docker manifest inspect` command again, we can see the base image also doesn't support `arm64` architecture 😞 - -```bash -docker manifest inspect tiangolo/uwsgi-nginx-flask:python3.6 -``` - -On Docker Hub, we can see the [tiangolo/uwsgi-nginx-flask](https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask) image is built using this [this Dockerfile](https://github.com/tiangolo/uwsgi-nginx-flask-docker/blob/master/docker-images/python3.6.dockerfile) - -Upon inspection of the Dockerfile, you can see this image sources from yet another base image called `tiangolo/uwsgi-nginx:python3.6` - -Back in Docker Hub, we can view information for the [tiangolo/uwsgi-nginx](https://hub.docker.com/r/tiangolo/uwsgi-nginx) image. Here we see [this Dockerfile](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.6.dockerfile) is used to build the base image. - -In the Dockerfile, we see it's base image is `python:3.6-buster` - -This image is also hosted on Docker Hub so we can check to see if this image supports `arm64` - -```bash -docker manifest inspect python:3.6-buster -``` - -In the output, we can see it supports many architectures including `arm64` 🥳 - -```json -... -{ - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 2217, - "digest": "sha256:293f12079921200fb3b9d17996bb0a06d743828d2bdd7eb49e245aee26d2f802", - "platform": { - "architecture": "arm64", - "os": "linux", - "variant": "v8" - } -} -... -``` - -The existing [Azure Voting App](https://github.com/Azure-Samples/azure-voting-app-redis/blob/master/azure-vote/Dockerfile) container image will not work for us, we must build and publish our own container and have it support multiple OS architectures. Thankfully, we can borrow a lot of [tiangolo's](https://github.com/tiangolo) code and build our own custom Dockerfile from it. - -With the focus of this lab being on deploying `arm64` workloads to AKS, we've saved you some time and combined the container image code from the original [Azure Voting App](https://github.com/Azure-Samples/azure-voting-app-redis) repo and [tiangolo's](https://github.com/tiangolo) Dockerfiles and published a new Azure Voting App repo [here](https://github.com/pauldotyu/azure-voting-app/blob/main/src/Dockerfile). This repo supports both AMD64 and ARM64 OS architectures by building and pushing images using [`docker buildx`](https://docs.docker.com/engine/reference/commandline/buildx/). - -### Deploying the Azure Voting App - -#### Build and publish the container image - -Navigate to the updated [Azure Voting App](https://github.com/pauldotyu/azure-voting-app) repo and click on the green "Use this template" button. This will allow you to create a new repo in your GitHub account. - -With the repo created in your GitHub account, clone the repo and open it in a terminal. - -This repo contains a [GitHub Actions workflow file](https://github.com/pauldotyu/azure-voting-app/blob/main/.github/workflows/docker-image.yml), which builds and publishes the app to your new Azure Container Registry. You will need to [create repository secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) so that your workflow can authenticate and publish to your registry. - -Run the following commands to pull out the registry credentials: - -> If you are using a new terminal, you will need to reset the `name` variable. Run the following command: -> -> name= - -```bash -acrServer=$(az acr show --name "acr${name}" --query loginServer -o tsv) -acrUsername=$(az acr credential show --name "acr${name}" --query username -o tsv) -acrPassword=$(az acr credential show --name "acr${name}" --query "passwords[0].value" -o tsv) -``` - -Using the GitHub CLI, run the following commands to set your repository secrets - -```bash -ghRepo="/" - -gh auth login -gh secret set ACR_SERVER --body $acrServer --repo $ghRepo -gh secret set ACR_USERNAME --body $acrUsername --repo $ghRepo -gh secret set ACR_PASSWORD --body $acrPassword --repo $ghRepo -``` - -To push an image to the Azure Container Registry, create a new release using the following command: - -```bash -gh release create v1.0.0 --notes "" --repo $ghRepo -``` - -Publishing a new release will trigger the GitHub Action workflow to build and publish the container image. - -> The build and publish will take approximately 8-10 minutes - -To view the output of the workflow, you can run these commands: - -```bash -gh run view --repo $ghRepo -gh run view --repo $ghRepo --job=XXXXXXXXX # your job number will be listed in the command above -gh run view --repo $ghRepo --log --job=XXXXXXXXXX # the log will be available when the job is complete -``` - -To validate your image, you can run the following: - -```bash -az acr manifest list-metadata --registry "acr${name}" --name azure-vote-front -``` - -#### Deploy the Kubernetes manifest - -The **azure-voting-app** repo includes a sample [Kubernetes manifest file](https://github.com/pauldotyu/azure-voting-app/blob/main/azure-voting-app-deploy.yaml) which you can use to deploy. There is a `` placeholder in the file and this can be swapped out using the `sed` command. - -The app deployment leverages [Kustomize](https://kustomize.io/) to customize your configuration at deployment time. The `kustomization.yaml` file includes a placeholder which you will swap out with your container registry server name. As the template is deployed to your Kubernetes cluster, Kustomize will replace the image value. - -Run the following command to update your `kustomization.yaml` file. - -```bash -sed -i'' -e "s//$acrServer/" kustomization.yaml -``` - -Now we can deploy the workload with the following command: - -```bash -kubectl apply -k . -``` - -> 📝 NOTE -> -> Kustomize is built into `kubectl` - -Inspect the pods to ensure they've deployed successfully: - -```bash -kubectl get po - -NAME READY STATUS RESTARTS AGE -azure-vote-back-54576c54f-bktkk 1/1 Running 0 3m23s -azure-vote-front-5694d5cc45-fx87s 1/1 Running 0 3m23s -``` - -Inspect the service to ensure you can browse to the site: - -```bash -kubectl get svc - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -azure-vote-back ClusterIP 10.0.136.122 6379/TCP 117s -azure-vote-front LoadBalancer 10.0.74.8 20.81.58.34 80:30303/TCP 117s -kubernetes ClusterIP 10.0.0.1 443/TCP 32m -``` - -Once the `EXTERNAL-IP` is populated for the `azure-vote-front` service, you can use the IP address and browse to the Azure Voting App 🚀 - -## Summary - -Congratulations! 🎉 - -You've deployed an AKS cluster with an ARM64-based user node pool, built and published a new Azure Voting App container image which supports multiple OS architectures, and deployed the app into the AKS cluster. We also explored how we can inspect container image manifests to view the OS architectures they support. If your container images only support AMD64 OS architectures, you can easily re-target to support multiple platforms using Docker Buildx as demonstrated when we created a new release of the Azure Voting App. However, as we found in our exercise, you'll need to inspect the base layers of the container images to see if they also support ARM64. - -## Cleanup - -When you are finished exploring resources in this lab, you can delete the deployment by running the following commands: - -```bash -az group delete --name "rg-${name}" -az deployment sub delete --name "${name}-deploy" -``` - -If you do not wish to keep the Azure Voting App repo in your GitHub account, you can delete it by running the following GitHub CLI commands: - -```bash -gh auth refresh -h github.com -s delete_repo -gh repo delete $ghRepo -``` diff --git a/cloud-native/aks-arm64/azure-voting-app-deploy.yaml b/cloud-native/aks-arm64/azure-voting-app-deploy.yaml deleted file mode 100644 index 99e7859..0000000 --- a/cloud-native/aks-arm64/azure-voting-app-deploy.yaml +++ /dev/null @@ -1,94 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-vote-back -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: redis:latest - env: - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - ports: - - containerPort: 6379 - name: redis ---- -apiVersion: v1 -kind: Service -metadata: - name: azure-vote-back -spec: - ports: - - port: 6379 - selector: - app: azure-vote-back ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-vote-front -spec: - replicas: 1 - selector: - matchLabels: - app: azure-vote-front - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - minReadySeconds: 5 - template: - metadata: - labels: - app: azure-vote-front - spec: - nodeSelector: - "kubernetes.io/os": linux - containers: - - name: azure-vote-front - image: cloudnativeadvocates.azurecr.io/azure-vote-front:v1.0.0 - ports: - - containerPort: 80 - resources: - requests: - cpu: 250m - limits: - cpu: 500m - env: - - name: REDIS - value: "azure-vote-back" ---- -apiVersion: v1 -kind: Service -metadata: - name: azure-vote-front -spec: - type: LoadBalancer - ports: - - port: 80 - selector: - app: azure-vote-front ---- -apiVersion: autoscaling/v1 -kind: HorizontalPodAutoscaler -metadata: - name: azure-vote-front -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: azure-vote-front - minReplicas: 1 - maxReplicas: 50 - targetCPUUtilizationPercentage: 50 diff --git a/cloud-native/aks-arm64/bicepconfig.json b/cloud-native/aks-arm64/bicepconfig.json deleted file mode 100644 index 91b4f8a..0000000 --- a/cloud-native/aks-arm64/bicepconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "moduleAliases": { - "ts": {}, - "br": { - "oss-labs": { - "registry": "cloudnativeadvocates.azurecr.io" - } - } - } -} \ No newline at end of file diff --git a/cloud-native/aks-arm64/kustomization.yaml b/cloud-native/aks-arm64/kustomization.yaml deleted file mode 100644 index f812c85..0000000 --- a/cloud-native/aks-arm64/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -resources: -- azure-voting-app-deploy.yaml - -# Change the image name and version -images: -- name: cloudnativeadvocates.azurecr.io/azure-vote-front:v1.0.0 - newName: /azure-vote-front - newTag: v1.0.0 \ No newline at end of file diff --git a/cloud-native/aks-arm64/main.bicep b/cloud-native/aks-arm64/main.bicep deleted file mode 100644 index 86bca95..0000000 --- a/cloud-native/aks-arm64/main.bicep +++ /dev/null @@ -1,128 +0,0 @@ -targetScope = 'subscription' - -param name string -param location string -param tags object = {} - -var networkPlugin = 'kubenet' -var networkPolicy = 'calico' - -// Set up the resource group -resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { - name: 'rg-${name}' - location: location - tags: tags -} - -// Set up the container registry -module acr '../../bicep/modules/azure-container-registry/main.bicep' = { - scope: rg - name: 'acrDeploy' - params: { - name: 'acr${toLower(name)}' - location: location - tags: tags - sku: 'Basic' - adminUserEnabled: true - managedIdentityType: 'SystemAssigned' - publicNetworkAccess: true - } -} - -// Set up the network security group -module nsg '../../bicep/modules/azure-network-security-group/main.bicep' = if (networkPlugin != 'kubenet') { - scope: rg - name: 'nsgDeploy' - params: { - name: 'nsg-${name}' - location: location - tags: tags - } -} - -// Setup the virtual network and subnet -module vnet '../../bicep/modules/azure-virtual-network/main.bicep' = if (networkPlugin != 'kubenet') { - scope: rg - name: 'vnetDeploy' - params: { - name: 'vnet-${name}' - location: location - tags: tags - vnetAddressPrefix: '10.21.0.0/16' - snetName: 'snet-${name}' - snetAddressPrefix: '10.21.0.0/24' - networkSecurityGroupId: networkPlugin != 'kubenet' ? nsg.outputs.id : '' - dnsServer: '' // Leave empty if you want to use Azure's default DNS - } -} - -// Setup the log analytics workspace -module law '../../bicep/modules/azure-log-analytics-workspace/main.bicep' = { - scope: rg - name: 'lawDeploy' - params: { - name: 'law-${name}' - location: location - tags: tags - } -} - -// Setup the Kubernetes cluster -module aks '../../bicep/modules/azure-kubernetes-service/main.bicep' = { - scope: rg - name: 'aksDeploy' - params: { - name: 'aks-${name}' - location: location - tags: tags - slaTier: 'Free' - managedIdentityType: 'SystemAssigned' - kubernetesVersion: '1.29' - networkPlugin: networkPlugin - networkPolicy: networkPolicy - loadBalancerSku: 'Standard' - outboundType: 'loadBalancer' - dnsServiceIP: '10.0.0.10' - podCidrs: [ - '10.244.0.0/16' - ] - serviceCidrs: [ - '10.0.0.0/16' - ] - ipFamilies: [ - 'IPv4' - ] - defenderEnabled: false - imageCleanerEnabled: false - systemNodeCount: 2 - systemNodeVmSize: 'Standard_D2s_v5' - registryName: acr.outputs.name - vnetSubnetID: networkPlugin != 'kubenet' ? vnet.outputs.subnetId : '' - logAnalyticsWorkspaceResourceId: law.outputs.id - nodeTaints: [ 'CriticalAddonsOnly=true:NoSchedule' ] // If deploying a user node pool too, you can taint the system node pool to prevent application pods from being scheduled on it; otherwise, leave empty - } -} - -// Setup the user node pools and deploy into a subnet -module aksPools '../../bicep/modules/azure-kubernetes-service-nodepools/main.bicep' = { - scope: rg - name: 'armNodePoolsDeploy' - params: { - managedClusterName: aks.outputs.name - userNodes: [ - { - name: 'arm64' - mode: 'User' - vmSize: 'Standard_D4pds_v5' // Make sure the SKU is available in your region. - enableAutoScaling: true - scaleDownMode: 'Delete' // Delete is the default. - minCount: 0 // If autoscale is enabled, then set the min number of nodes you wish to run. - maxCount: 2 // Set this to the maximum number of nodes to run. If autoscale is not enabled, this value will be used as the node count. - type: 'VirtualMachineScaleSets' // If autoscale is enabled, then the node type must be VirtualMachineScaleSets (default is AvailabilitySet). - osDiskType: 'Ephemeral' // If autoscale is enabled and scale down mode is set to Deallocate, then the OS disk must be managed (default is Ephemeral). - nodeTaints: '' // Add a taint like this `key=value:NoSchedule` or leave as empty string to not taint your nodes - vnetSubnetID: networkPlugin != 'kubenet' ? vnet.outputs.subnetId : '' // If the cluster is using azure network plugin, then you can pass in the subnet resource ID like this `vnet.outputs.subnetId`; otherwise, leave it empty - } - ] - } -} diff --git a/cloud-native/aks-arm64/main.json b/cloud-native/aks-arm64/main.json deleted file mode 100644 index 2961961..0000000 --- a/cloud-native/aks-arm64/main.json +++ /dev/null @@ -1,914 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "17685315886462117336" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object", - "defaultValue": {} - } - }, - "variables": { - "networkPlugin": "kubenet", - "networkPolicy": "calico" - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2021-04-01", - "name": "[format('rg-{0}', parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]" - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "acrDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('acr{0}', toLower(parameters('name')))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "sku": { - "value": "Basic" - }, - "adminUserEnabled": { - "value": true - }, - "managedIdentityType": { - "value": "SystemAssigned" - }, - "publicNetworkAccess": { - "value": true - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "17364936891097374484" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "sku": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Basic", - "Standard", - "Premium" - ], - "metadata": { - "description": "Defaults to Standard" - } - }, - "managedIdentityType": { - "type": "string", - "defaultValue": "SystemAssigned", - "allowedValues": [ - "SystemAssigned", - "UserAssigned" - ], - "metadata": { - "description": "Two options are available: SystemAssigned or UserAssigned" - } - }, - "userAssignedIdentities": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Required when managed identity type is set to UserAssigned" - } - }, - "adminUserEnabled": { - "type": "bool", - "defaultValue": false - }, - "anonymousPullEnabled": { - "type": "bool", - "defaultValue": false - }, - "publicNetworkAccess": { - "type": "bool", - "defaultValue": "[if(equals(parameters('sku'), 'Premium'), false(), true())]", - "metadata": { - "description": "Disableing public network access is not supported for Basic and Standard SKUs" - } - } - }, - "resources": [ - { - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2022-02-01-preview", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('sku')]" - }, - "identity": { - "type": "[parameters('managedIdentityType')]", - "userAssignedIdentities": "[if(not(equals(parameters('managedIdentityType'), 'SystemAssigned')), parameters('userAssignedIdentities'), null())]" - }, - "properties": { - "adminUserEnabled": "[parameters('adminUserEnabled')]", - "anonymousPullEnabled": "[parameters('anonymousPullEnabled')]", - "publicNetworkAccess": "[if(parameters('publicNetworkAccess'), 'Enabled', 'Disabled')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "value": "[parameters('name')]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "condition": "[not(equals(variables('networkPlugin'), 'kubenet'))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "nsgDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('nsg-{0}', parameters('name'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "5609067551621364305" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "location": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2022-01-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "properties": { - "securityRules": [] - }, - "tags": "[parameters('tags')]" - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('name'))]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "condition": "[not(equals(variables('networkPlugin'), 'kubenet'))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "vnetDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('vnet-{0}', parameters('name'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "vnetAddressPrefix": { - "value": "10.21.0.0/16" - }, - "snetName": { - "value": "[format('snet-{0}', parameters('name'))]" - }, - "snetAddressPrefix": { - "value": "10.21.0.0/24" - }, - "networkSecurityGroupId": "[if(not(equals(variables('networkPlugin'), 'kubenet')), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'nsgDeploy'), '2022-09-01').outputs.id.value), createObject('value', ''))]", - "dnsServer": { - "value": "" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3087759273833726789" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "vnetAddressPrefix": { - "type": "string" - }, - "snetAddressPrefix": { - "type": "string" - }, - "snetName": { - "type": "string" - }, - "networkSecurityGroupId": { - "type": "string" - }, - "dnsServer": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2022-01-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[parameters('vnetAddressPrefix')]" - ] - }, - "dhcpOptions": "[if(not(empty(parameters('dnsServer'))), createObject('dnsServers', createArray(parameters('dnsServer'))), null())]", - "subnets": [ - { - "name": "[parameters('snetName')]", - "properties": { - "addressPrefix": "[parameters('snetAddressPrefix')]", - "networkSecurityGroup": { - "id": "[parameters('networkSecurityGroupId')]" - } - } - } - ] - } - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "subnetId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Network/virtualNetworks', parameters('name')), '2022-01-01').subnets[0].id]" - } - } - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'nsgDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "lawDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('law-{0}', parameters('name'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4630854867665059244" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2021-12-01-preview", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "retentionInDays": 30, - "sku": { - "name": "PerGB2018" - } - } - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('name'))]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "aksDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('aks-{0}', parameters('name'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "slaTier": { - "value": "Free" - }, - "managedIdentityType": { - "value": "SystemAssigned" - }, - "kubernetesVersion": { - "value": "1.29" - }, - "networkPlugin": { - "value": "[variables('networkPlugin')]" - }, - "networkPolicy": { - "value": "[variables('networkPolicy')]" - }, - "loadBalancerSku": { - "value": "Standard" - }, - "outboundType": { - "value": "loadBalancer" - }, - "dnsServiceIP": { - "value": "10.0.0.10" - }, - "podCidrs": { - "value": [ - "10.244.0.0/16" - ] - }, - "serviceCidrs": { - "value": [ - "10.0.0.0/16" - ] - }, - "ipFamilies": { - "value": [ - "IPv4" - ] - }, - "defenderEnabled": { - "value": false - }, - "imageCleanerEnabled": { - "value": false - }, - "systemNodeCount": { - "value": 2 - }, - "systemNodeVmSize": { - "value": "Standard_D2s_v5" - }, - "registryName": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'acrDeploy'), '2022-09-01').outputs.name.value]" - }, - "vnetSubnetID": "[if(not(equals(variables('networkPlugin'), 'kubenet')), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'vnetDeploy'), '2022-09-01').outputs.subnetId.value), createObject('value', ''))]", - "logAnalyticsWorkspaceResourceId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'lawDeploy'), '2022-09-01').outputs.id.value]" - }, - "nodeTaints": { - "value": [ - "CriticalAddonsOnly=true:NoSchedule" - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "5599997474738078815" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "slaTier": { - "type": "string", - "defaultValue": "Free", - "allowedValues": [ - "Free", - "Paid" - ], - "metadata": { - "description": "Defaults to Free tier" - } - }, - "managedIdentityType": { - "type": "string", - "defaultValue": "SystemAssigned", - "allowedValues": [ - "SystemAssigned", - "UserAssigned" - ], - "metadata": { - "description": "Two options are available: SystemAssigned or UserAssigned" - } - }, - "userAssignedIdentities": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Required when managed identity type is set to UserAssigned" - } - }, - "kubernetesVersion": { - "type": "string", - "defaultValue": "1.29", - "metadata": { - "description": "Default is 1.29" - } - }, - "defenderEnabled": { - "type": "bool", - "defaultValue": false - }, - "imageCleanerEnabled": { - "type": "bool", - "defaultValue": false - }, - "imageCleanerIntervalHours": { - "type": "int", - "defaultValue": 12 - }, - "systemNodeCount": { - "type": "int", - "defaultValue": 3 - }, - "systemNodeVmSize": { - "type": "string", - "defaultValue": "Standard_D2s_v5", - "metadata": { - "description": "Default system node pool size is Standard_D2s_v5" - } - }, - "registryName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional parameter to attach AKS cluster to an existing ACR" - } - }, - "networkPlugin": { - "type": "string", - "defaultValue": "kubenet", - "allowedValues": [ - "kubenet", - "azure", - "none" - ], - "metadata": { - "description": "Network plugin used for building the Kubernetes network." - } - }, - "networkPolicy": { - "type": "string", - "defaultValue": "calico", - "allowedValues": [ - "calico", - "azure" - ], - "metadata": { - "description": "Network policy used for building the Kubernetes network." - } - }, - "loadBalancerSku": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Standard", - "Basic" - ], - "metadata": { - "description": "The default is standard." - } - }, - "dnsServiceIP": { - "type": "string", - "defaultValue": "10.0.0.10", - "metadata": { - "description": "An IP address assigned to the Kubernetes DNS service. It must be within the Kubernetes service address range specified in serviceCidr." - } - }, - "dockerBridgeCidr": { - "type": "string", - "defaultValue": "172.17.0.1/16", - "metadata": { - "description": "A CIDR notation IP range assigned to the Docker bridge network. It must not overlap with any Subnet IP ranges or the Kubernetes service address range." - } - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Resource ID of log analytics workspace for auditing" - } - }, - "outboundType": { - "type": "string", - "defaultValue": "loadBalancer", - "allowedValues": [ - "loadBalancer", - "managedNATGateway", - "userAssignedNATGateway", - "userDefinedRouting" - ], - "metadata": { - "description": "This can only be set at cluster creation time and cannot be changed later." - } - }, - "podCidrs": { - "type": "array", - "defaultValue": [ - "10.244.0.0/16" - ], - "metadata": { - "description": "One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking." - } - }, - "serviceCidrs": { - "type": "array", - "defaultValue": [ - "10.0.0.0/16" - ], - "metadata": { - "description": "One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking. They must not overlap with any Subnet IP ranges." - } - }, - "ipFamilies": { - "type": "array", - "defaultValue": [ - "IPv4" - ], - "allowedValues": [ - "IPv4", - "IPv6" - ] - }, - "vnetSubnetID": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "If the cluster is using azure network plugin, then you can pass in the subnet resource ID like this `vnet.outputs.subnetId`; otherwise, leave it empty" - } - }, - "nodeTaints": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Enable nodeTaints on the system node pool (e.g., ['CriticalAddonsOnly=true:NoSchedule'])" - } - }, - "addonProfiles": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "AKS addons to enable" - } - }, - "enablePrometheusMetrics": { - "type": "bool", - "defaultValue": false - }, - "prometheusMetricLabelsAllowlist": { - "type": "string", - "defaultValue": "" - }, - "prometheusMetricAnnotationsAllowList": { - "type": "string", - "defaultValue": "" - } - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2022-08-03-preview", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "Basic", - "tier": "[parameters('slaTier')]" - }, - "identity": { - "type": "[parameters('managedIdentityType')]", - "userAssignedIdentities": "[if(equals(parameters('managedIdentityType'), 'UserAssigned'), parameters('userAssignedIdentities'), null())]" - }, - "properties": { - "kubernetesVersion": "[parameters('kubernetesVersion')]", - "dnsPrefix": "[parameters('name')]", - "azureMonitorProfile": "[if(parameters('enablePrometheusMetrics'), createObject('metrics', createObject('enabled', true(), 'kubeStateMetrics', createObject('metricLabelsAllowlist', parameters('prometheusMetricLabelsAllowlist'), 'metricAnnotationsAllowList', parameters('prometheusMetricAnnotationsAllowList')))), null())]", - "networkProfile": { - "networkPlugin": "[parameters('networkPlugin')]", - "networkPolicy": "[parameters('networkPolicy')]", - "loadBalancerSku": "[parameters('loadBalancerSku')]", - "dnsServiceIP": "[parameters('dnsServiceIP')]", - "dockerBridgeCidr": "[parameters('dockerBridgeCidr')]", - "outboundType": "[parameters('outboundType')]", - "podCidrs": "[parameters('podCidrs')]", - "serviceCidrs": "[parameters('serviceCidrs')]", - "ipFamilies": "[parameters('ipFamilies')]" - }, - "agentPoolProfiles": [ - { - "name": "system", - "count": "[parameters('systemNodeCount')]", - "vmSize": "[parameters('systemNodeVmSize')]", - "mode": "System", - "vnetSubnetID": "[if(empty(parameters('vnetSubnetID')), null(), parameters('vnetSubnetID'))]", - "nodeTaints": "[if(empty(parameters('nodeTaints')), null(), parameters('nodeTaints'))]" - } - ], - "securityProfile": { - "defender": { - "securityMonitoring": { - "enabled": "[parameters('defenderEnabled')]" - } - }, - "imageCleaner": { - "enabled": "[parameters('imageCleanerEnabled')]", - "intervalHours": "[parameters('imageCleanerIntervalHours')]" - } - }, - "addonProfiles": "[parameters('addonProfiles')]" - } - }, - { - "condition": "[not(equals(parameters('registryName'), ''))]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('registryName'))]", - "name": "[guid(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), parameters('registryName'))]", - "properties": { - "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview').identityProfile.kubeletidentity.objectId]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), resourceGroup().id)]", - "properties": { - "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview', 'full').identity.principalId]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" - ] - } - ], - "outputs": { - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "id": { - "type": "string", - "value": "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" - }, - "kubeletIdentityObjectId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview').identityProfile.kubeletidentity.objectId]" - }, - "nodeResourceGroupName": { - "type": "string", - "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview').nodeResourceGroup]" - } - } - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'acrDeploy')]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'lawDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'vnetDeploy')]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "armNodePoolsDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "managedClusterName": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy'), '2022-09-01').outputs.name.value]" - }, - "userNodes": { - "value": [ - { - "name": "arm64", - "mode": "User", - "vmSize": "Standard_D4pds_v5", - "enableAutoScaling": true, - "scaleDownMode": "Delete", - "minCount": 0, - "maxCount": 2, - "type": "VirtualMachineScaleSets", - "osDiskType": "Ephemeral", - "nodeTaints": "", - "vnetSubnetID": "[if(not(equals(variables('networkPlugin'), 'kubenet')), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'vnetDeploy'), '2022-09-01').outputs.subnetId.value, '')]" - } - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "18243559256984356460" - } - }, - "parameters": { - "managedClusterName": { - "type": "string" - }, - "userNodes": { - "type": "array" - } - }, - "resources": [ - { - "copy": { - "name": "userNodePools", - "count": "[length(range(0, length(parameters('userNodes'))))]" - }, - "type": "Microsoft.ContainerService/managedClusters/agentPools", - "apiVersion": "2024-02-01", - "name": "[format('{0}/{1}', parameters('managedClusterName'), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].name)]", - "properties": { - "vmSize": "[parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].vmSize]", - "mode": "[parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].mode]", - "enableAutoScaling": "[parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].enableAutoScaling]", - "count": "[if(contains(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]], 'maxCount'), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].maxCount, 1)]", - "minCount": "[if(and(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].enableAutoScaling, contains(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]], 'minCount')), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].minCount, null())]", - "maxCount": "[if(and(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].enableAutoScaling, contains(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]], 'maxCount')), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].maxCount, null())]", - "scaleDownMode": "[if(and(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].enableAutoScaling, contains(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]], 'scaleDownMode')), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].scaleDownMode, null())]", - "nodeTaints": "[if(empty(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].nodeTaints), null(), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].nodeTaints)]", - "type": "[parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].type]", - "osDiskType": "[parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].osDiskType]", - "vnetSubnetID": "[if(empty(parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].vnetSubnetID), null(), parameters('userNodes')[range(0, length(parameters('userNodes')))[copyIndex()]].vnetSubnetID)]" - } - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'vnetDeploy')]" - ] - } - ] -} \ No newline at end of file diff --git a/cloud-native/aks-bicep-k8s/README.md b/cloud-native/aks-bicep-k8s/README.md deleted file mode 100644 index 9d17e36..0000000 --- a/cloud-native/aks-bicep-k8s/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# Explore Open Source workloads with Azure Kubernetes Service (AKS) and the Bicep extensibility Kubernetes provider - -In this lab you will deploy an Azure Kubernetes Service (AKS) cluster, other Azure services (Container Registry, Managed Identity, Storage Account), and open source workloads, with [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli), [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) and the [Bicep extensibility Kubernetes provider (Preview)](https://learn.microsoft.com/azure/azure-resource-manager/bicep/bicep-extensibility-kubernetes-provider). - -## Requirements - -- An **Azure Subscription** (e.g. [Free](https://aka.ms/azure-free-account) or [Student](https://aka.ms/azure-student-account) account) -- The [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) -- Bash shell (e.g. macOS, Linux, [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about), [Multipass](https://multipass.run/), [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/quickstart), [GitHub Codespaces](https://github.com/features/codespaces), etc) -- [Go](https://go.dev/dl/) (Optional) -- [Mage](https://magefile.org/) (`go install github.com/magefile/mage@latest`) (Optional) - -## Instructions - -Use the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) templates to deploy the infrastructure for your application. - -Login to the Azure CLI. - -```bash -az login -``` - -Clone this repository. - -```bash -git clone https://github.com/Azure-Samples/azure-opensource-labs.git -``` - -Change to this directory. - -``` -cd azure-opensource-labs/cloud-native/aks-bicep-k8s -``` - -While you can deploy the Bicep templates ([main.bicep](./main.bicep)) via the Azure CLI or Azure Portal, we have included a Magefile, [magefile.go](./magefile.go), with the following targets to make deployment easier. - -``` -$ mage -Targets: - aksCredentials gets credentials for the AKS cluster - aksKubectl ensures kubectl is installed - deployAKS deploys aks.bicep at the Resource Group scope - deployApp DeployAKS uses aks-deploy-app.bicep to deploy AKS_APP_BICEP(=azure-vote.bicep) - deployMain [experimental] deploys main.bicep::q at the Resource Group scope - empty empties the Azure resource group - emptyNamespace has az invoke kubectl delete all on K8S_NAMESPACE - group creates the Azure resource group - groupDelete deletes the Azure resource group -``` - -### Deployment - -``` -mage group deployAks deployApp -``` - -### Delete resources - -``` -mage empty -``` diff --git a/cloud-native/aks-bicep-k8s/aks-deploy-app.bicep b/cloud-native/aks-bicep-k8s/aks-deploy-app.bicep deleted file mode 100644 index b6aeff1..0000000 --- a/cloud-native/aks-bicep-k8s/aks-deploy-app.bicep +++ /dev/null @@ -1,16 +0,0 @@ -param clusterName string = 'aks1' -param namespace string = 'default' - -resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-05-01' existing = { - name: clusterName -} - -module app './azure-vote.bicep' = { - name: '${resourceGroup().name}-app' - params: { - kubeConfig: aksCluster.listClusterAdminCredential().kubeconfigs[0].value - namespace: namespace - } -} - -output appOutputs object = app.outputs diff --git a/cloud-native/aks-bicep-k8s/aks.bicep b/cloud-native/aks-bicep-k8s/aks.bicep deleted file mode 100644 index 91cc6f1..0000000 --- a/cloud-native/aks-bicep-k8s/aks.bicep +++ /dev/null @@ -1,93 +0,0 @@ -param location string = resourceGroup().location -param clusterName string = 'aks1' -param nodeCount int = 1 -param vmSize string = 'standard_d2s_v5' -param kubernetesVersion string = '1.29' - -var rand = substring(uniqueString(resourceGroup().id), 0, 6) - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity' - location: location -} - -resource aks 'Microsoft.ContainerService/managedClusters@2021-05-01' = { - name: clusterName - location: location - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - kubernetesVersion: kubernetesVersion - dnsPrefix: clusterName - enableRBAC: true - agentPoolProfiles: [ - { - name: 'nodepool1' - count: nodeCount - vmSize: vmSize - mode: 'System' - } - ] - } -} - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2019-05-01' = { - name: 'acr${rand}' - location: location - sku: { - name: 'Standard' - } - properties: { - adminUserEnabled: true - } -} - -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { - name: 'storage${rand}' - location: location - kind: 'BlockBlobStorage' - sku: { - name: 'Premium_LRS' - } - properties: { - minimumTlsVersion: 'TLS1_2' - } -} - -// via: https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-resource#subscriptionresourceid-example -var roleDefinitionId = { - Owner: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' - Contributor: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' - AcrPull: '7f951dda-4ed3-4680-a7ca-43fe172d538d' - StorageBlobDataContributor: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' - KubernetesServiceClusterUserRole: '4abbcc35-e782-43d8-92c5-2d3f1bd2253f' -} - -// https://github.com/Azure/bicep/discussions/3181 -var roleAssignmentAcrDefinition = 'AcrPull' -resource roleAssignmentAcr 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(containerRegistry.id, roleAssignmentAcrDefinition) - scope: containerRegistry - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentAcrDefinition]) - principalId: aks.properties.identityProfile.kubeletidentity.objectId - } -} - -var roleAssignmentStorageAccountDefinition = 'StorageBlobDataContributor' -resource roleAssignmentStorageAccount 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(storageAccount.id, roleAssignmentStorageAccountDefinition) - scope: storageAccount - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentStorageAccountDefinition]) - principalId: managedIdentity.properties.principalId - } - dependsOn: [ - aks - ] -} diff --git a/cloud-native/aks-bicep-k8s/azure-vote.bicep b/cloud-native/aks-bicep-k8s/azure-vote.bicep deleted file mode 100644 index 5caf885..0000000 --- a/cloud-native/aks-bicep-k8s/azure-vote.bicep +++ /dev/null @@ -1,150 +0,0 @@ -@secure() -param kubeConfig string -param namespace string = 'default' - -import 'kubernetes@1.0.0' with { - namespace: namespace - kubeConfig: kubeConfig -} - -resource appsDeployment_azureVoteBack 'apps/Deployment@v1' = { - metadata: { - name: 'azure-vote-back' - } - 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: 'mcr.microsoft.com/oss/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' - } - ] - } - ] - } - } - } -} - -resource coreService_azureVoteBack 'core/Service@v1' = { - metadata: { - name: 'azure-vote-back' - } - spec: { - ports: [ - { - port: 6379 - } - ] - selector: { - app: 'azure-vote-back' - } - } -} - -resource appsDeployment_azureVoteFront 'apps/Deployment@v1' = { - metadata: { - name: 'azure-vote-front' - } - 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' - } - ] - } - ] - } - } - } -} - -resource coreService_azureVoteFront 'core/Service@v1' = { - metadata: { - name: 'azure-vote-front' - } - spec: { - type: 'LoadBalancer' - ports: [ - { - port: 80 - } - ] - selector: { - app: 'azure-vote-front' - } - } -} - -output frontendIp string = coreService_azureVoteFront.status.loadBalancer.ingress[0].ip diff --git a/cloud-native/aks-bicep-k8s/azure-vote.yaml b/cloud-native/aks-bicep-k8s/azure-vote.yaml deleted file mode 100644 index b071366..0000000 --- a/cloud-native/aks-bicep-k8s/azure-vote.yaml +++ /dev/null @@ -1,85 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-vote-back -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: mcr.microsoft.com/oss/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 -spec: - ports: - - port: 6379 - selector: - app: azure-vote-back ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-vote-front -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 -spec: - type: LoadBalancer - ports: - - port: 80 - selector: - app: azure-vote-front \ No newline at end of file diff --git a/cloud-native/aks-bicep-k8s/azure-voting-app-rust.bicep b/cloud-native/aks-bicep-k8s/azure-voting-app-rust.bicep deleted file mode 100644 index e94ef75..0000000 --- a/cloud-native/aks-bicep-k8s/azure-voting-app-rust.bicep +++ /dev/null @@ -1,165 +0,0 @@ -@secure() -param kubeConfig string -param namespace string = 'default' - -import 'kubernetes@1.0.0' with { - namespace: namespace - kubeConfig: kubeConfig -} - -resource appsDeployment_postgres 'apps/Deployment@v1' = { - metadata: { - name: 'postgres' - } - spec: { - replicas: 1 - selector: { - matchLabels: { - app: 'postgres' - } - } - template: { - metadata: { - labels: { - app: 'postgres' - } - } - spec: { - nodeSelector: { - 'kubernetes.io/os': 'linux' - } - containers: [ - { - name: 'postgres' - image: 'postgres:15.0-alpine' - env: [ - { - name: 'POSTGRES_PASSWORD' - value: 'mypassword' - } - ] - resources: { - requests: { - cpu: '100m' - memory: '128Mi' - } - limits: { - cpu: '250m' - memory: '256Mi' - } - } - ports: [ - { - containerPort: 5432 - name: 'postgres' - } - ] - } - ] - } - } - } -} - -resource coreService_postgres 'core/Service@v1' = { - metadata: { - name: 'postgres' - } - spec: { - ports: [ - { - port: 5432 - } - ] - selector: { - app: 'postgres' - } - } -} - -resource appsDeployment_azureVotingAppRust 'apps/Deployment@v1' = { - metadata: { - name: 'azure-voting-app-rust' - } - spec: { - replicas: 1 - selector: { - matchLabels: { - app: 'azure-voting-app-rust' - } - } - template: { - metadata: { - labels: { - app: 'azure-voting-app-rust' - } - } - spec: { - nodeSelector: { - 'kubernetes.io/os': 'linux' - } - containers: [ - { - name: 'azure-voting-app-rust' - image: 'ghcr.io/asw101/azure-voting-app-rust:latest' - resources: { - requests: { - cpu: '100m' - memory: '128Mi' - } - limits: { - cpu: '250m' - memory: '256Mi' - } - } - ports: [ - { - containerPort: 8080 - } - ] - env: [ - { - name: 'DATABASE_SERVER' - value: 'postgres' - } - { - name: 'DATABASE_PASSWORD' - value: 'mypassword' - } - { - name: 'FIRST_VALUE' - value: 'Go' - } - { - name: 'SECOND_VALUE' - value: 'Rust' - } - ] - } - ] - } - } - } -} - -resource coreService_azureVotingAppRust 'core/Service@v1' = { - metadata: { - name: 'azure-voting-app-rust' - } - spec: { - type: 'LoadBalancer' - ports: [ - { - protocol: 'TCP' - port: 80 - targetPort: 8080 - } - ] - selector: { - app: 'azure-voting-app-rust' - } - } -} - - -output frontendIp string = coreService_azureVotingAppRust.status.loadBalancer.ingress[0].ip diff --git a/cloud-native/aks-bicep-k8s/azure-voting-app-rust.yaml b/cloud-native/aks-bicep-k8s/azure-voting-app-rust.yaml deleted file mode 100644 index 1578f03..0000000 --- a/cloud-native/aks-bicep-k8s/azure-voting-app-rust.yaml +++ /dev/null @@ -1,93 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: postgres -spec: - replicas: 1 - selector: - matchLabels: - app: postgres - template: - metadata: - labels: - app: postgres - spec: - nodeSelector: - "kubernetes.io/os": linux - containers: - - name: postgres - image: postgres:15.0-alpine - env: - - name: POSTGRES_PASSWORD - value: "mypassword" - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 250m - memory: 256Mi - ports: - - containerPort: 5432 - name: postgres ---- -apiVersion: v1 -kind: Service -metadata: - name: postgres -spec: - ports: - - port: 5432 - selector: - app: postgres ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-voting-app-rust -spec: - replicas: 1 - selector: - matchLabels: - app: azure-voting-app-rust - template: - metadata: - labels: - app: azure-voting-app-rust - spec: - nodeSelector: - "kubernetes.io/os": linux - containers: - - name: azure-voting-app-rust - image: ghcr.io/asw101/azure-voting-app-rust:latest - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 250m - memory: 256Mi - ports: - - containerPort: 8080 - env: - - name: DATABASE_SERVER - value: "postgres" - - name: DATABASE_PASSWORD - value: "mypassword" - - name: FIRST_VALUE - value: "Go" - - name: SECOND_VALUE - value: "Rust" ---- -apiVersion: v1 -kind: Service -metadata: - name: azure-voting-app-rust -spec: - type: LoadBalancer - ports: - - protocol: TCP - port: 80 - targetPort: 8080 - selector: - app: azure-voting-app-rust diff --git a/cloud-native/aks-bicep-k8s/bicepconfig.json b/cloud-native/aks-bicep-k8s/bicepconfig.json deleted file mode 100644 index b59b79d..0000000 --- a/cloud-native/aks-bicep-k8s/bicepconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - // See https://aka.ms/bicep/config for more information on Bicep configuration options - // Press CTRL+SPACE/CMD+SPACE at any location to see Intellisense suggestions - "analyzers": { - "core": { - "rules": { - "no-unused-params": { - "level": "warning" - } - } - } - }, - "experimentalFeaturesEnabled": { - "extensibility": true - } - } \ No newline at end of file diff --git a/cloud-native/aks-bicep-k8s/dotnet-vue-starter.bicep b/cloud-native/aks-bicep-k8s/dotnet-vue-starter.bicep deleted file mode 100644 index a1cfcf5..0000000 --- a/cloud-native/aks-bicep-k8s/dotnet-vue-starter.bicep +++ /dev/null @@ -1,75 +0,0 @@ -@secure() -param kubeConfig string -param namespace string = 'default' - -import 'kubernetes@1.0.0' with { - namespace: namespace - kubeConfig: kubeConfig -} - -resource appsDeployment_dotnetVueStarter 'apps/Deployment@v1' = { - metadata: { - name: 'dotnet-vue-starter' - } - spec: { - replicas: 1 - selector: { - matchLabels: { - app: 'dotnet-vue-starter' - } - } - template: { - metadata: { - labels: { - app: 'dotnet-vue-starter' - } - } - spec: { - nodeSelector: { - 'kubernetes.io/os': 'linux' - } - containers: [ - { - name: 'dotnet-vue-starter' - image: 'ghcr.io/asw101/dotnet-vue-starter:latest' - resources: { - requests: { - cpu: '100m' - memory: '128Mi' - } - limits: { - cpu: '250m' - memory: '256Mi' - } - } - ports: [ - { - containerPort: 80 - } - ] - } - ] - } - } - } -} - -resource coreService_dotnetVueStarter 'core/Service@v1' = { - metadata: { - name: 'dotnet-vue-starter' - } - spec: { - type: 'LoadBalancer' - ports: [ - { - port: 80 - } - ] - selector: { - app: 'dotnet-vue-starter' - } - } -} - - -output frontendIp string = coreService_dotnetVueStarter.status.loadBalancer.ingress[0].ip diff --git a/cloud-native/aks-bicep-k8s/dotnet-vue-starter.yaml b/cloud-native/aks-bicep-k8s/dotnet-vue-starter.yaml deleted file mode 100644 index ff02e80..0000000 --- a/cloud-native/aks-bicep-k8s/dotnet-vue-starter.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: dotnet-vue-starter -spec: - replicas: 1 - selector: - matchLabels: - app: dotnet-vue-starter - template: - metadata: - labels: - app: dotnet-vue-starter - spec: - nodeSelector: - "kubernetes.io/os": linux - containers: - - name: dotnet-vue-starter - image: ghcr.io/asw101/dotnet-vue-starter:latest - resources: - requests: - cpu: 100m - memory: 128Mi - limits: - cpu: 250m - memory: 256Mi - ports: - - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: dotnet-vue-starter -spec: - type: LoadBalancer - ports: - - port: 80 - selector: - app: dotnet-vue-starter \ No newline at end of file diff --git a/cloud-native/aks-bicep-k8s/go.mod b/cloud-native/aks-bicep-k8s/go.mod deleted file mode 100644 index 0fd1d2b..0000000 --- a/cloud-native/aks-bicep-k8s/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module aksbicep - -go 1.19 - -require github.com/magefile/mage v1.14.0 diff --git a/cloud-native/aks-bicep-k8s/go.sum b/cloud-native/aks-bicep-k8s/go.sum deleted file mode 100644 index f8bfb2f..0000000 --- a/cloud-native/aks-bicep-k8s/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= -github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= diff --git a/cloud-native/aks-bicep-k8s/magefile.go b/cloud-native/aks-bicep-k8s/magefile.go deleted file mode 100644 index dc8116c..0000000 --- a/cloud-native/aks-bicep-k8s/magefile.go +++ /dev/null @@ -1,277 +0,0 @@ -//go:build mage - -package main - -import ( - "errors" - "fmt" - "os" - "strings" - "time" - - "github.com/magefile/mage/sh" -) - -// resourceGroup gets resource group name from the -// RESOURCE_GROUP env var, or provides a default -func resourceGroup() string { - name := os.Getenv("RESOURCE_GROUP") - if name == "" { - name = fmt.Sprintf("%s-aks-bicep", time.Now().Format("060100")) - } - return name -} - -// Group creates the Azure resource group -func Group() error { - name := resourceGroup() - location := os.Getenv("LOCATION") - if location == "" { - location = "eastus" - } - cmd := []string{ - "az", - "group", - "create", - "--name", - name, - "--location", - location, - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// DeployAKS deploys aks.bicep at the Resource Group scope -func DeployAKS() error { - name := resourceGroup() - location := os.Getenv("LOCATION") - if location == "" { - location = "eastus" - } - - file1 := "aks.bicep" - cmd := []string{ - "az", - "deployment", - "group", - "create", - "--resource-group", - name, - "--template-file", - file1, - "--parameters", - "location=" + location, - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// DeployAKS uses aks-deploy-app.bicep to deploy AKS_APP_BICEP(=azure-vote.bicep) -func DeployApp() error { - name := resourceGroup() - k8sNamespace := os.Getenv("K8S_NAMESPACE") - if k8sNamespace == "" { - k8sNamespace = "default" - } - appBicep := os.Getenv("AKS_APP_BICEP") - if appBicep == "" { - appBicep = "azure-vote.bicep" - } - fmt.Printf("Deploying AKS_APP_BICEP=%s\n", appBicep) - - // make temporary file - file1 := "aks-deploy-app.bicep" - file2 := "tmp.bicep" - err := sh.Copy(file2, file1) - if err != nil { - return err - } - defer os.RemoveAll(file2) - - replace1 := map[string]string{ - "azure-vote.bicep": appBicep, - } - err = fileReplace(file2, replace1) - if err != nil { - return err - } - - cmd := []string{ - "az", - "deployment", - "group", - "create", - "--resource-group", - name, - "--template-file", - file2, - "--parameters", - "namespace=" + k8sNamespace, - } - err = sh.RunV(cmd[0], cmd[1:]...) - if err != nil { - fmt.Printf("error. retrying once in 20s.\n") - time.Sleep(20 * time.Second) - err = sh.RunV(cmd[0], cmd[1:]...) - } - return err -} - -// DeployMain [experimental] deploys main.bicep at the Resource Group scope -func DeployMain() error { - name := resourceGroup() - location := os.Getenv("LOCATION") - if location == "" { - location = "eastus" - } - aksName := os.Getenv("AKS_NAME") - if aksName == "" { - aksName = "aks1" - } - deployCluster := os.Getenv("DEPLOY_CLUSTER") - if deployCluster == "" { - deployCluster = "true" - } - switch { - case deployCluster == "true" || deployCluster == "false": - default: - return errors.New("DEPLOY_CLUSTER must be true, false, or empty") - } - - file1 := "main.bicep" - cmd := []string{ - "az", - "deployment", - "group", - "create", - "--resource-group", - name, - "--template-file", - file1, - "--parameters", - "location=" + location, - "clusterName=" + aksName, - "deployCluster=" + deployCluster, - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// EmptyNamespace has az invoke kubectl delete all on K8S_NAMESPACE -func EmptyNamespace() error { - name := resourceGroup() - location := os.Getenv("LOCATION") - if location == "" { - location = "eastus" - } - aksName := os.Getenv("AKS_NAME") - if aksName == "" { - aksName = "aks1" - } - k8sNamespace := os.Getenv("K8S_NAMESPACE") - if k8sNamespace == "" { - k8sNamespace = "default" - } - - kubectlCommand := "kubectl delete all --all -n " + k8sNamespace - cmd := []string{ - "az", - "aks", - "command", - "invoke", - "--resource-group", - name, - "--name", - aksName, - "--command", - kubectlCommand, - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// AksCredentials gets credentials for the AKS cluster -func AksCredentials() error { - name := resourceGroup() - aksName := os.Getenv("AKS_NAME") - if aksName == "" { - aksName = "aks1" - } - cmd := []string{ - "az", - "aks", - "get-credentials", - "--resource-group", - name, - "--name", - aksName, - "--overwrite-existing", - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// AksKubectl ensures kubectl is installed -func AksKubectl() error { - cmd := []string{ - "az", - "aks", - "install-cli", - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// Empty empties the Azure resource group -func Empty() error { - name := resourceGroup() - file1 := "empty.bicep" - f, err := os.Create(file1) - if err != nil { - return err - } - f.Close() - cmd := []string{ - "az", - "deployment", - "group", - "create", - "--resource-group", - name, - "--template-file", - file1, - "--mode", - "Complete", - } - err = sh.RunV(cmd[0], cmd[1:]...) - if err != nil { - return err - } - err = os.RemoveAll(file1) - if err != nil { - return err - } - return nil -} - -// GroupDelete deletes the Azure resource group -func GroupDelete() error { - name := resourceGroup() - cmd := []string{ - "az", - "group", - "delete", - "--name", - name, - "--yes", - } - return sh.RunV(cmd[0], cmd[1:]...) -} - -// fileReplace replaces values in a file using a map -func fileReplace(file string, replace map[string]string) error { - b, err := os.ReadFile(file) - if err != nil { - return err - } - val := string(b) - for k, v := range replace { - val = strings.Replace(val, k, v, -1) - } - return os.WriteFile(file, []byte(val), 0644) -} diff --git a/cloud-native/aks-bicep-k8s/main.bicep b/cloud-native/aks-bicep-k8s/main.bicep deleted file mode 100644 index 67cede8..0000000 --- a/cloud-native/aks-bicep-k8s/main.bicep +++ /dev/null @@ -1,29 +0,0 @@ -param location string = resourceGroup().location -param clusterName string = 'aks1' -param namespace string = 'default' -param deployCluster bool = true - -module aks './aks.bicep' = if(deployCluster) { - name: '${resourceGroup().name}-aks' - params: { - location: location - clusterName: clusterName - } -} - -resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-05-01' existing = { - name: clusterName -} - -module app './azure-vote.bicep' = { - name: '${resourceGroup().name}-app' - params: { - kubeConfig: aksCluster.listClusterAdminCredential().kubeconfigs[0].value - namespace: namespace - } - dependsOn: [ - aks - ] -} - -output lbPublicIp string = app.outputs.frontendIp diff --git a/cloud-native/aks-bicep-k8s/main.json b/cloud-native/aks-bicep-k8s/main.json deleted file mode 100644 index 6b9c65e..0000000 --- a/cloud-native/aks-bicep-k8s/main.json +++ /dev/null @@ -1,424 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.1-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "This template uses ARM features that are experimental. Experimental features should be enabled for testing purposes only, as there are no guarantees about the quality or stability of these features. Do not enable these settings for any production usage, or your production environment may be subject to breaking.", - "_EXPERIMENTAL_FEATURES_ENABLED": [ - "Extensibility" - ], - "_generator": { - "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "8744504821534446077" - } - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "clusterName": { - "type": "string", - "defaultValue": "aks1" - }, - "namespace": { - "type": "string", - "defaultValue": "default" - }, - "deployCluster": { - "type": "bool", - "defaultValue": true - } - }, - "resources": { - "aksCluster": { - "existing": true, - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2023-05-01", - "name": "[parameters('clusterName')]" - }, - "aks": { - "condition": "[parameters('deployCluster')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-aks', resourceGroup().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "clusterName": { - "value": "[parameters('clusterName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.1-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "This template uses ARM features that are experimental. Experimental features should be enabled for testing purposes only, as there are no guarantees about the quality or stability of these features. Do not enable these settings for any production usage, or your production environment may be subject to breaking.", - "_EXPERIMENTAL_FEATURES_ENABLED": [ - "Extensibility" - ], - "_generator": { - "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "187541002047123827" - } - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "clusterName": { - "type": "string", - "defaultValue": "aks1" - }, - "nodeCount": { - "type": "int", - "defaultValue": 1 - }, - "vmSize": { - "type": "string", - "defaultValue": "standard_d2s_v5" - }, - "kubernetesVersion": { - "type": "string", - "defaultValue": "1.29" - } - }, - "variables": { - "rand": "[substring(uniqueString(resourceGroup().id), 0, 6)]", - "roleDefinitionId": { - "Owner": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", - "Contributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7", - "AcrPull": "7f951dda-4ed3-4680-a7ca-43fe172d538d", - "StorageBlobDataContributor": "ba92f5b4-2d11-453d-a403-e96b0029c9fe", - "KubernetesServiceClusterUserRole": "4abbcc35-e782-43d8-92c5-2d3f1bd2253f" - }, - "roleAssignmentAcrDefinition": "AcrPull", - "roleAssignmentStorageAccountDefinition": "StorageBlobDataContributor" - }, - "resources": { - "managedIdentity": { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - "aks": { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2021-05-01", - "name": "[parameters('clusterName')]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)))]": {} - } - }, - "properties": { - "kubernetesVersion": "[parameters('kubernetesVersion')]", - "dnsPrefix": "[parameters('clusterName')]", - "enableRBAC": true, - "agentPoolProfiles": [ - { - "name": "nodepool1", - "count": "[parameters('nodeCount')]", - "vmSize": "[parameters('vmSize')]", - "mode": "System" - } - ] - }, - "dependsOn": [ - "managedIdentity" - ] - }, - "containerRegistry": { - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2019-05-01", - "name": "[format('acr{0}', variables('rand'))]", - "location": "[parameters('location')]", - "sku": { - "name": "Standard" - }, - "properties": { - "adminUserEnabled": true - } - }, - "storageAccount": { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-02-01", - "name": "[format('storage{0}', variables('rand'))]", - "location": "[parameters('location')]", - "kind": "BlockBlobStorage", - "sku": { - "name": "Premium_LRS" - } - }, - "roleAssignmentAcr": { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', format('acr{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries', format('acr{0}', variables('rand'))), variables('roleAssignmentAcrDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentAcrDefinition')])]", - "principalId": "[reference('aks').identityProfile.kubeletidentity.objectId]" - }, - "dependsOn": [ - "aks", - "containerRegistry" - ] - }, - "roleAssignmentStorageAccount": { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('storage{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', format('storage{0}', variables('rand'))), variables('roleAssignmentStorageAccountDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentStorageAccountDefinition')])]", - "principalId": "[reference('managedIdentity').principalId]" - }, - "dependsOn": [ - "aks", - "managedIdentity", - "storageAccount" - ] - } - } - } - } - }, - "app": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-app', resourceGroup().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "kubeConfig": { - "value": "[listClusterAdminCredential(resourceId('Microsoft.ContainerService/managedClusters', parameters('clusterName')), '2023-05-01').kubeconfigs[0].value]" - }, - "namespace": { - "value": "[parameters('namespace')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.1-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "This template uses ARM features that are experimental. Experimental features should be enabled for testing purposes only, as there are no guarantees about the quality or stability of these features. Do not enable these settings for any production usage, or your production environment may be subject to breaking.", - "_EXPERIMENTAL_FEATURES_ENABLED": [ - "Extensibility" - ], - "_generator": { - "name": "bicep", - "version": "0.26.170.59819", - "templateHash": "1578784578022569032" - } - }, - "parameters": { - "kubeConfig": { - "type": "securestring" - }, - "namespace": { - "type": "string", - "defaultValue": "default" - } - }, - "imports": { - "kubernetes": { - "provider": "Kubernetes", - "version": "1.0.0", - "config": { - "namespace": "[parameters('namespace')]", - "kubeConfig": "[parameters('kubeConfig')]" - } - } - }, - "resources": { - "appsDeployment_azureVoteBack": { - "import": "kubernetes", - "type": "apps/Deployment@v1", - "properties": { - "metadata": { - "name": "azure-vote-back" - }, - "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": "mcr.microsoft.com/oss/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" - } - ] - } - ] - } - } - } - } - }, - "coreService_azureVoteBack": { - "import": "kubernetes", - "type": "core/Service@v1", - "properties": { - "metadata": { - "name": "azure-vote-back" - }, - "spec": { - "ports": [ - { - "port": 6379 - } - ], - "selector": { - "app": "azure-vote-back" - } - } - } - }, - "appsDeployment_azureVoteFront": { - "import": "kubernetes", - "type": "apps/Deployment@v1", - "properties": { - "metadata": { - "name": "azure-vote-front" - }, - "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" - } - ] - } - ] - } - } - } - } - }, - "coreService_azureVoteFront": { - "import": "kubernetes", - "type": "core/Service@v1", - "properties": { - "metadata": { - "name": "azure-vote-front" - }, - "spec": { - "type": "LoadBalancer", - "ports": [ - { - "port": 80 - } - ], - "selector": { - "app": "azure-vote-front" - } - } - } - } - }, - "outputs": { - "frontendIp": { - "type": "string", - "value": "[reference('coreService_azureVoteFront').status.loadBalancer.ingress[0].ip]" - } - } - } - }, - "dependsOn": [ - "aks", - "aksCluster" - ] - } - }, - "outputs": { - "lbPublicIp": { - "type": "string", - "value": "[reference('app').outputs.frontendIp.value]" - } - } -} \ No newline at end of file diff --git a/cloud-native/aks-bicep-keda/01-aks/README.md b/cloud-native/aks-bicep-keda/01-aks/README.md deleted file mode 100644 index 3fb3e84..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# 01-aks/ - -This folder contains bicep templates and scripts to deploy Azure Kubernetes Service (AKS), Managed Identity, Container Registry and related resources. - -## Build ARM (main.json) from Bicep - -```bash -az bicep build --file main.bicep --outfile main.json -``` - -## Deploy ARM (main.json) via Azure Portal - -[Deploy to Azure](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2Fazure-opensource-labs%2Fmain%2Fcloud-native%2Faks-bicep-keda%2F01-aks%2Fmain.json) - -```bash -TEMPLATE_URL='https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/main/cloud-native/aks-bicep-keda/01-aks/main.json' -OUTPUT_URL='https://portal.azure.com/#create/Microsoft.Template/uri/'$(printf "$TEMPLATE_URL" | jq -s -R -r @uri ) -echo $OUTPUT_URL - -# https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2Fazure-opensource-labs%2Fmain%2Fcloud-native%2Faks-bicep-keda%2F01-aks%2Fmain.json -``` diff --git a/cloud-native/aks-bicep-keda/01-aks/RESOURCES.md b/cloud-native/aks-bicep-keda/01-aks/RESOURCES.md deleted file mode 100644 index b226a09..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/RESOURCES.md +++ /dev/null @@ -1,5 +0,0 @@ -# RESOURCES - -- Initial AKS templates borrowed from: . -- -- diff --git a/cloud-native/aks-bicep-keda/01-aks/aks.bicep b/cloud-native/aks-bicep-keda/01-aks/aks.bicep deleted file mode 100644 index 245999a..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/aks.bicep +++ /dev/null @@ -1,139 +0,0 @@ -param location string = resourceGroup().location -param clusterName string = '' -param nodeCount int = 1 -param vmSize string = 'standard_d2s_v3' -param kubernetesVersion string = '1.29' - -var rand = substring(uniqueString(resourceGroup().id), 0, 6) -var clusterName_var = clusterName != '' ? clusterName : 'aks1' - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity' - location: location -} - -resource aks 'Microsoft.ContainerService/managedClusters@2021-05-01' = { - name: clusterName_var - location: location - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - kubernetesVersion: kubernetesVersion - dnsPrefix: clusterName_var - enableRBAC: true - agentPoolProfiles: [ - { - name: 'pool0' - count: nodeCount - vmSize: vmSize - mode: 'System' - } - ] - } -} - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2019-05-01' = { - name: 'acr${rand}' - location: location - sku: { - name: 'Standard' - } - properties: { - adminUserEnabled: true - } -} - -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { - name: 'storage${rand}' - location: location - kind: 'BlockBlobStorage' - sku: { - name: 'Premium_LRS' - } - properties: { - minimumTlsVersion: 'TLS1_2' - } -} - -resource serviceBus 'Microsoft.ServiceBus/namespaces@2021-06-01-preview' = { - name: 'servicebus${rand}' - location: location - sku: { - capacity: 1 - name: 'Standard' - tier: 'Standard' - } - properties: { - disableLocalAuth: false - } -} - -// via: https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-resource#subscriptionresourceid-example -var roleDefinitionId = { - Owner: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' - Contributor: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' - AcrPull: '7f951dda-4ed3-4680-a7ca-43fe172d538d' - StorageBlobDataContributor: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' - ServiceBusDataOwner: '090c5cfd-751d-490a-894a-3ce6f1109419' - KubernetesServiceClusterUserRole: '4abbcc35-e782-43d8-92c5-2d3f1bd2253f' -} - -// https://github.com/Azure/bicep/discussions/3181 -var roleAssignmentAcrDefinition = 'AcrPull' -resource roleAssignmentAcr 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(containerRegistry.id, roleAssignmentAcrDefinition) - scope: containerRegistry - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentAcrDefinition]) - principalId: aks.properties.identityProfile.kubeletidentity.objectId - } -} - -var roleAssignmentStorageAccountDefinition = 'StorageBlobDataContributor' -resource roleAssignmentStorageAccount 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(storageAccount.id, roleAssignmentStorageAccountDefinition) - scope: storageAccount - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentStorageAccountDefinition]) - principalId: managedIdentity.properties.principalId - } - dependsOn: [ - aks - ] -} - -var roleAssignmentServiceBusDefinition = 'ServiceBusDataOwner' -resource roleAssignmentServiceBus 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(serviceBus.id, roleAssignmentServiceBusDefinition) - scope: serviceBus - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentServiceBusDefinition]) - principalId: managedIdentity.properties.principalId - } - dependsOn: [ - aks - ] -} - -resource managedIdentityDeploy 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity-deploy' - location: location -} - -var roleAssignmentDeploymentContributorDefinition = 'Contributor' -resource roleAssignmentDeploymentContributor 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(managedIdentityDeploy.id, roleAssignmentDeploymentContributorDefinition) - scope: resourceGroup() - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentDeploymentContributorDefinition]) - principalId: managedIdentityDeploy.properties.principalId - } - dependsOn: [ - aks - ] -} diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-aks.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-aks.sh deleted file mode 100644 index 4fe8faa..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-aks.sh +++ /dev/null @@ -1,6 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode complete \ - --template-file ./aks.bicep diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-deploy-script.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-deploy-script.sh deleted file mode 100644 index cdb1cee..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-deploy-script.sh +++ /dev/null @@ -1,9 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${LOCATION:-}" ]] && LOCATION='eastus' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode incremental \ - --template-file ./deploy-script.bicep \ - --parameters \ - scriptUri='https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/main/cloud-native/aks-bicep-keda/01-aks/deploy-script-aks.sh' diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-empty.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-empty.sh deleted file mode 100644 index dd3f0f3..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-empty.sh +++ /dev/null @@ -1,6 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode complete \ - --template-file ./empty.bicep diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-keyvault.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-keyvault.sh deleted file mode 100644 index f1cf287..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-keyvault.sh +++ /dev/null @@ -1,6 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode incremental \ - --template-file ./keyvault.bicep diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-main.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-main.sh deleted file mode 100644 index 3f07d69..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-main.sh +++ /dev/null @@ -1,11 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${LOCATION:-}" ]] && LOCATION='eastus' -[[ -z "${AKS_NAME:-}" ]] && AKS_NAME='aks1' - -az deployment sub create \ - --location $LOCATION \ - --template-file ./main.bicep \ - --parameters \ - deployScript='true' \ - scriptUri='https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/main/cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh' \ - resourceGroup=$RESOURCE_GROUP diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-script-aks.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-script-aks.sh deleted file mode 100644 index 6ed1964..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-script-aks.sh +++ /dev/null @@ -1,8 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${AKS_NAME:-}" ]] && AKS_NAME='aks1' - -echo "az aks command invoke" -az aks command invoke \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --command 'kubectl run nginx --image=nginx' diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh b/cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh deleted file mode 100644 index 70cd14b..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh +++ /dev/null @@ -1,8 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${AKS_NAME:-}" ]] && AKS_NAME='aks1' - -echo "az aks command invoke" -az aks command invoke \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --command 'kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.7.1/keda-2.7.1.yaml' diff --git a/cloud-native/aks-bicep-keda/01-aks/deploy-script.bicep b/cloud-native/aks-bicep-keda/01-aks/deploy-script.bicep deleted file mode 100644 index df50a7e..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/deploy-script.bicep +++ /dev/null @@ -1,65 +0,0 @@ -param location string = resourceGroup().location -param utcValue string = utcNow() -param resourceGroupName string = resourceGroup().name -// url to deploy-script-*.sh in repo -param scriptUri string = '' - -resource managedIdentityDeploy 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity-deploy' - location: location -} - -var roleDefinitionId = { - Owner: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' - Contributor: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' -} - -// https://github.com/Azure/bicep/discussions/3181 -var roleAssignmentDeploymentContributorDefinition = 'Contributor' -resource roleAssignmentDeploymentContributor 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(managedIdentityDeploy.id, roleAssignmentDeploymentContributorDefinition) - scope: resourceGroup() - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentDeploymentContributorDefinition]) - principalId: managedIdentityDeploy.properties.principalId - } -} - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'deploy-script' - location: location - kind: 'AzureCLI' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentityDeploy.id}': {} - } - } - properties: { - environmentVariables: [ - { - name: 'RESOURCE_GROUP' - value: resourceGroupName - } - { - name: 'AKS_NAME' - value: 'aks1' - } - { - name: 'NAMESPACE' - value: 'keda-http' - } - ] - forceUpdateTag: utcValue - azCliVersion: '2.28.0' - timeout: 'PT30M' - //arguments: '\'211200-cloud-native\'' - //scriptContent: 'echo "arg1 is: $1"; value=$1; echo \'{}\' | jq --arg value "$value" \'.Result = $value\' | tee $AZ_SCRIPTS_OUTPUT_PATH' - primaryScriptUri: scriptUri - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - } -} - -//output result object = deploymentScript.properties.outputs diff --git a/cloud-native/aks-bicep-keda/01-aks/empty.bicep b/cloud-native/aks-bicep-keda/01-aks/empty.bicep deleted file mode 100644 index 3d70e64..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/empty.bicep +++ /dev/null @@ -1 +0,0 @@ -output group string = resourceGroup().id diff --git a/cloud-native/aks-bicep-keda/01-aks/keyvault.bicep b/cloud-native/aks-bicep-keda/01-aks/keyvault.bicep deleted file mode 100644 index 5aa5280..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/keyvault.bicep +++ /dev/null @@ -1,34 +0,0 @@ -param location string = resourceGroup().location - -var rand = substring(uniqueString(resourceGroup().id), 0, 6) - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity' - location: location -} - -resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = { - name: 'keyvault${rand}' - location: location - properties: { - enabledForDeployment: true - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - tenantId: subscription().tenantId - sku: { - name: 'standard' - family: 'A' - } - accessPolicies: [ - { - objectId: managedIdentity.properties.principalId - permissions: { - secrets: [ - 'all' - ] - } - tenantId: subscription().tenantId - } - ] - } -} diff --git a/cloud-native/aks-bicep-keda/01-aks/main.bicep b/cloud-native/aks-bicep-keda/01-aks/main.bicep deleted file mode 100644 index 2c9f2a8..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/main.bicep +++ /dev/null @@ -1,31 +0,0 @@ -targetScope = 'subscription' - -param resourceGroup string = '220600-keda' -param location string = deployment().location -param deployScript bool = false -param scriptUri string = 'https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/main/cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh' - -resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { - name: resourceGroup - location: location -} - -module aks './aks.bicep' = { - name: '${resourceGroup}-aks' - scope: rg - params: { - location: location - } -} - -module script './deploy-script.bicep' = if(deployScript) { - name: '${resourceGroup}-deployscript' - scope: rg - params: { - location: location - scriptUri: scriptUri - } - dependsOn: [ - aks - ] -} diff --git a/cloud-native/aks-bicep-keda/01-aks/main.json b/cloud-native/aks-bicep-keda/01-aks/main.json deleted file mode 100644 index dd9f658..0000000 --- a/cloud-native/aks-bicep-keda/01-aks/main.json +++ /dev/null @@ -1,365 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "16764085829659056086" - } - }, - "parameters": { - "resourceGroup": { - "type": "string", - "defaultValue": "220600-keda" - }, - "location": { - "type": "string", - "defaultValue": "[deployment().location]" - }, - "deployScript": { - "type": "bool", - "defaultValue": false - }, - "scriptUri": { - "type": "string", - "defaultValue": "https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/main/cloud-native/aks-bicep-keda/01-aks/deploy-script-keda.sh" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2021-04-01", - "name": "[parameters('resourceGroup')]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-aks', parameters('resourceGroup'))]", - "resourceGroup": "[parameters('resourceGroup')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "7703729210362399507" - } - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "clusterName": { - "type": "string", - "defaultValue": "" - }, - "nodeCount": { - "type": "int", - "defaultValue": 1 - }, - "vmSize": { - "type": "string", - "defaultValue": "standard_d2s_v3" - }, - "kubernetesVersion": { - "type": "string", - "defaultValue": "1.29" - } - }, - "variables": { - "rand": "[substring(uniqueString(resourceGroup().id), 0, 6)]", - "clusterName_var": "[if(not(equals(parameters('clusterName'), '')), parameters('clusterName'), 'aks1')]", - "roleDefinitionId": { - "Owner": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", - "Contributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7", - "AcrPull": "7f951dda-4ed3-4680-a7ca-43fe172d538d", - "StorageBlobDataContributor": "ba92f5b4-2d11-453d-a403-e96b0029c9fe", - "ServiceBusDataOwner": "090c5cfd-751d-490a-894a-3ce6f1109419", - "KubernetesServiceClusterUserRole": "4abbcc35-e782-43d8-92c5-2d3f1bd2253f" - }, - "roleAssignmentAcrDefinition": "AcrPull", - "roleAssignmentStorageAccountDefinition": "StorageBlobDataContributor", - "roleAssignmentServiceBusDefinition": "ServiceBusDataOwner", - "roleAssignmentDeploymentContributorDefinition": "Contributor" - }, - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2021-05-01", - "name": "[variables('clusterName_var')]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)))]": {} - } - }, - "properties": { - "kubernetesVersion": "[parameters('kubernetesVersion')]", - "dnsPrefix": "[variables('clusterName_var')]", - "enableRBAC": true, - "agentPoolProfiles": [ - { - "name": "pool0", - "count": "[parameters('nodeCount')]", - "vmSize": "[parameters('vmSize')]", - "mode": "System" - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name))]" - ] - }, - { - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2019-05-01", - "name": "[format('acr{0}', variables('rand'))]", - "location": "[parameters('location')]", - "sku": { - "name": "Standard" - }, - "properties": { - "adminUserEnabled": true - } - }, - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-02-01", - "name": "[format('storage{0}', variables('rand'))]", - "location": "[parameters('location')]", - "kind": "BlockBlobStorage", - "sku": { - "name": "Premium_LRS" - }, - "properties": { - "minimumTlsVersion": "TLS1_2" - } - }, - { - "type": "Microsoft.ServiceBus/namespaces", - "apiVersion": "2021-06-01-preview", - "name": "[format('servicebus{0}', variables('rand'))]", - "location": "[parameters('location')]", - "sku": { - "capacity": 1, - "name": "Standard", - "tier": "Standard" - }, - "properties": { - "disableLocalAuth": false - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', format('acr{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries', format('acr{0}', variables('rand'))), variables('roleAssignmentAcrDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentAcrDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var')), '2021-05-01').identityProfile.kubeletidentity.objectId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ContainerRegistry/registries', format('acr{0}', variables('rand')))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('storage{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', format('storage{0}', variables('rand'))), variables('roleAssignmentStorageAccountDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentStorageAccountDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name))]", - "[resourceId('Microsoft.Storage/storageAccounts', format('storage{0}', variables('rand')))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', format('servicebus{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.ServiceBus/namespaces', format('servicebus{0}', variables('rand'))), variables('roleAssignmentServiceBusDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentServiceBusDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name))]", - "[resourceId('Microsoft.ServiceBus/namespaces', format('servicebus{0}', variables('rand')))]" - ] - }, - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity-deploy', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), variables('roleAssignmentDeploymentContributorDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentDeploymentContributorDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name))]" - ] - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroup'))]" - ] - }, - { - "condition": "[parameters('deployScript')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-deployscript', parameters('resourceGroup'))]", - "resourceGroup": "[parameters('resourceGroup')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "scriptUri": { - "value": "[parameters('scriptUri')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "9861108784878104103" - } - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "utcValue": { - "type": "string", - "defaultValue": "[utcNow()]" - }, - "resourceGroupName": { - "type": "string", - "defaultValue": "[resourceGroup().name]" - }, - "scriptUri": { - "type": "string", - "defaultValue": "" - } - }, - "variables": { - "roleDefinitionId": { - "Owner": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", - "Contributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7" - }, - "roleAssignmentDeploymentContributorDefinition": "Contributor" - }, - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity-deploy', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), variables('roleAssignmentDeploymentContributorDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentDeploymentContributorDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name))]" - ] - }, - { - "type": "Microsoft.Resources/deploymentScripts", - "apiVersion": "2020-10-01", - "name": "deploy-script", - "location": "[parameters('location')]", - "kind": "AzureCLI", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)))]": {} - } - }, - "properties": { - "environmentVariables": [ - { - "name": "RESOURCE_GROUP", - "value": "[parameters('resourceGroupName')]" - }, - { - "name": "AKS_NAME", - "value": "aks1" - }, - { - "name": "NAMESPACE", - "value": "keda-http" - } - ], - "forceUpdateTag": "[parameters('utcValue')]", - "azCliVersion": "2.28.0", - "timeout": "PT30M", - "primaryScriptUri": "[parameters('scriptUri')]", - "cleanupPreference": "OnSuccess", - "retentionInterval": "P1D" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name))]" - ] - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroup')), 'Microsoft.Resources/deployments', format('{0}-aks', parameters('resourceGroup')))]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroup'))]" - ] - } - ] -} \ No newline at end of file diff --git a/cloud-native/aks-bicep-keda/02-keda/README.md b/cloud-native/aks-bicep-keda/02-keda/README.md deleted file mode 100644 index 3cbaa29..0000000 --- a/cloud-native/aks-bicep-keda/02-keda/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# 02-keda/ - -This folder contains a folder, `deploy/` with Kubernetes templates to deploy the [asw101/go-blob](https://github.com/asw101/go-blob) sample application to Kubernetes and KEDA. diff --git a/cloud-native/aks-bicep-keda/02-keda/deploy/deployment.yaml b/cloud-native/aks-bicep-keda/02-keda/deploy/deployment.yaml deleted file mode 100644 index ac2708a..0000000 --- a/cloud-native/aks-bicep-keda/02-keda/deploy/deployment.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: go-blob - labels: - app.kubernetes.io/name: go-blob -spec: - selector: - matchLabels: - app.kubernetes.io/name: go-blob - template: - metadata: - labels: - app.kubernetes.io/name: go-blob - spec: - serviceAccountName: go-blob - containers: - - name: go-blob - image: "ghcr.io/asw101/go-blob:daemon" - imagePullPolicy: Always - env: - - name: AZURE_STORAGE_ACCOUNT_NAME - valueFrom: - secretKeyRef: - name: az-storage-account - key: AZURE_STORAGE_ACCOUNT_NAME - optional: true - - name: AZURE_STORAGE_PRIMARY_ACCOUNT_KEY - valueFrom: - secretKeyRef: - name: az-storage-account - key: AZURE_STORAGE_PRIMARY_ACCOUNT_KEY - optional: true - \ No newline at end of file diff --git a/cloud-native/aks-bicep-keda/02-keda/deploy/keda.yaml b/cloud-native/aks-bicep-keda/02-keda/deploy/keda.yaml deleted file mode 100644 index 64eb9e4..0000000 --- a/cloud-native/aks-bicep-keda/02-keda/deploy/keda.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: keda.sh/v1alpha1 -kind: TriggerAuthentication -metadata: - name: azure-blob-auth - namespace: go-blob -spec: - secretTargetRef: - - parameter: connection - name: az-storage-account - key: AZURE_STORAGE_CONNECTION_STRING ---- -apiVersion: keda.sh/v1alpha1 -kind: ScaledObject -metadata: - name: go-blob-scaledobject - namespace: go-blob -spec: - scaleTargetRef: - name: go-blob - pollingInterval: 10 - cooldownPeriod: 10 - idleReplicaCount: 0 - minReplicaCount: 0 - maxReplicaCount: 5 - advanced: - restoreToOriginalReplicaCount: true - horizontalPodAutoscalerConfig: - behavior: - scaleDown: - stabilizationWindowSeconds: 20 - policies: - - type: Percent - value: 100 - periodSeconds: 10 - triggers: - - type: azure-blob - metadata: - blobContainerName: mycontainer - # Optional - blobCount: "1" # default 5 - blobPrefix: "" - blobDelimiter: "/" - cloud: AzurePublicCloud - authenticationRef: - name: azure-blob-auth diff --git a/cloud-native/aks-bicep-keda/02-keda/deploy/kustomization.yaml b/cloud-native/aks-bicep-keda/02-keda/deploy/kustomization.yaml deleted file mode 100644 index a978212..0000000 --- a/cloud-native/aks-bicep-keda/02-keda/deploy/kustomization.yaml +++ /dev/null @@ -1,10 +0,0 @@ -resources: -- namespace.yaml -- deployment.yaml -- serviceaccount.yaml -- keda.yaml - -commonLabels: - app.kubernetes.io/name: go-blob - -namespace: go-blob diff --git a/cloud-native/aks-bicep-keda/02-keda/deploy/namespace.yaml b/cloud-native/aks-bicep-keda/02-keda/deploy/namespace.yaml deleted file mode 100644 index 170b965..0000000 --- a/cloud-native/aks-bicep-keda/02-keda/deploy/namespace.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: go-blob - \ No newline at end of file diff --git a/cloud-native/aks-bicep-keda/02-keda/deploy/serviceaccount.yaml b/cloud-native/aks-bicep-keda/02-keda/deploy/serviceaccount.yaml deleted file mode 100644 index 923f9c5..0000000 --- a/cloud-native/aks-bicep-keda/02-keda/deploy/serviceaccount.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: go-blob - labels: - app.kubernetes.io/name: go-blob - \ No newline at end of file diff --git a/cloud-native/aks-bicep-keda/03-keda-http/README.md b/cloud-native/aks-bicep-keda/03-keda-http/README.md deleted file mode 100644 index c2c673b..0000000 --- a/cloud-native/aks-bicep-keda/03-keda-http/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# KEDA HTTP Add-on - -Install KEDA (via [YAML files](https://keda.sh/docs/2.7/deploy/#yaml)). You can also use [Helm](https://keda.sh/docs/2.7/deploy/#helm) or [Operator Hub](https://keda.sh/docs/2.7/deploy/#operatorhub). It may have been deployed to your cluster already. - -```bash -kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.7.1/keda-2.7.1.yaml -``` - -Install KEDA HTTP Add-on (via [Helm](https://github.com/kedacore/http-add-on/blob/main/docs/install.md#install-via-helm-chart)). It will be installed in `keda-http` namespace. - -```bash -helm upgrade --install http-add-on keda-add-ons-http \ - --repo https://kedacore.github.io/charts \ - --create-namespace \ - --namespace keda-http -``` - -Install the NGINX Ingress Controller (via [Helm](https://kubernetes.github.io/ingress-nginx/deploy/#quick-start)). - -```bash -helm upgrade --install ingress-nginx ingress-nginx \ - --repo https://kubernetes.github.io/ingress-nginx \ - --create-namespace \ - --namespace ingress-nginx -``` - -Get the IP address of the Ingress Controller. - -```bash -SERVICE_IP=$(kubectl get service -n ingress-nginx ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}') - -echo $SERVICE_IP -``` - -Clone the [asw101/go-hello](https://github.com/asw101/go-hello) repo locally. - -```bash -git clone https://github.com/asw101/go-hello.git -``` - -Open `go-hello/deploy/kustomization.yaml` and replace the `0.0.0.0` in `hello.0.0.0.0.nip.io` in with the IP address from `$SERVICE_IP` above. - -Deploy the manifests in the [go-hello/deploy](https://github.com/asw101/go-hello/tree/main/deploy) folder using kubectl and [kustomization](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/). - -```bash -kubectl apply -k go-hello/deploy -``` - -Output URL and open it in a web browser. - -```bash -echo "http://hello.${SERVICE_IP}.nip.io" -``` - -curl the `/echo` endpoint. - -```bash -curl "http://hello.${SERVICE_IP}.nip.io/echo" -``` - -If you would like to see the pods scale up and down, and/or tail the logs, in real-time, open [k9s](https://github.com/derailed/k9s#installation) in another terminal window and view the `hello` deployment. - -Use [hey](https://github.com/rakyll/hey) to generate load against `/wait?ms=450`, which will wait 450ms before responding. This command will use 250 concurrent workers to send a total of 10,000 requests. - -```bash -hey -c 250 -n 10000 "http://hello.${SERVICE_IP}.nip.io/wait?ms=450" -``` diff --git a/cloud-native/aks-bicep-keda/README.md b/cloud-native/aks-bicep-keda/README.md deleted file mode 100644 index 51608c0..0000000 --- a/cloud-native/aks-bicep-keda/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# Explore KEDA (Kubernetes Event-driven Autoscaling) and the KEDA HTTP Add-on with Azure Kubernetes Service (AKS) and Bicep - -In this lab you will deploy an Azure Kubernetes Service (AKS) cluster and other Azure services (Container Registry, Managed Identity, Storage Account, Service Bus, Key Vault), the open source KEDA (Kubernetes Event-driven Autoscaling) project with [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview). - -## Requirements - -- An **Azure Subscription** (e.g. [Free](https://aka.ms/azure-free-account) or [Student](https://aka.ms/azure-student-account) account) -- The [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) -- Bash shell (e.g. macOS, Linux, [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about), [Multipass](https://multipass.run/), [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/quickstart), [GitHub Codespaces](https://github.com/features/codespaces), etc) -- A [GitHub Account](https://github.com) - -## 1. Setup - -Use the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) templates to deploy the infrastructure for your application. - -Login to the Azure CLI. - -```bash -az login -``` - -Install kubectl using the Azure CLI, if required. - -```bash -az aks install-cli -``` - -Deploy the Bicep template for your Azure Kubernetes Service (AKS) cluster. - -```bash -cd cloud-native/aks-bicep-keda/01-aks -bash deploy-main.sh -``` - -## 2. KEDA - -Set environment variables. - -```bash -RESOURCE_GROUP='220600-keda' -AKS_NAME='aks1' -``` - -Invoke kubectl command on AKS cluster. - -```bash -cd ../02-keda/deploy - -az aks command invoke \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --file . \ - --command 'kubectl apply -k .' -``` - -Authenticate local kubectl. - -```bash -az aks get-credentials \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --overwrite-existing -``` - -Create secrets for Azure Blob Storage. - -```bash -export AZURE_STORAGE_ACCOUNT_NAME="$(az storage account list -g $RESOURCE_GROUP --out tsv --query '[0].name')" - -AZURE_STORAGE_PRIMARY_ACCOUNT_KEY=$(az storage account keys list \ - --account-name "$AZURE_STORAGE_ACCOUNT_NAME" \ - --out tsv \ - --query '[0].value') - -AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string \ - -g $RESOURCE_GROUP \ - --name "$AZURE_STORAGE_ACCOUNT_NAME" \ - --out tsv \ - --query 'connectionString') - -kubectl delete -k . - -kubectl apply -k . - -kubectl create secret generic az-storage-account \ - --namespace go-blob \ - --from-literal=AZURE_STORAGE_ACCOUNT_NAME="${AZURE_STORAGE_ACCOUNT_NAME}" \ - --from-literal=AZURE_STORAGE_PRIMARY_ACCOUNT_KEY="${AZURE_STORAGE_PRIMARY_ACCOUNT_KEY}" \ - --from-literal=AZURE_STORAGE_CONNECTION_STRING="${AZURE_STORAGE_CONNECTION_STRING}" -``` - -## 3. KEDA HTTP Add-on - -Follow the steps in [03-keda-http](./03-keda-http/) to install the [HTTP Add-on](https://github.com/kedacore/http-add-on) and deploy the [asw101/go-hello](https://github.com/asw101/go-hello) application to it. diff --git a/cloud-native/aks-bicep/01-aks/README.md b/cloud-native/aks-bicep/01-aks/README.md deleted file mode 100644 index 08d3038..0000000 --- a/cloud-native/aks-bicep/01-aks/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# 01-aks/ - -This folder contains bicep templates and scripts to deploy Azure Kubernetes Service (AKS), Managed Identity, Container Registry and related resources. - -## Build ARM (main.json) from Bicep - -```bash -az bicep build --file main.bicep --outfile main.json -``` - -## Deploy ARM (main.json) via Azure Portal - -[Deploy to Azure](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2Fazure-opensource-labs%2Faks-bicep%2Fcloud-native%2Faks-bicep%2F01-aks%2Fmain.json) - -```bash -TEMPLATE_URL='https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/aks-bicep/cloud-native/aks-bicep/01-aks/main.json' -OUTPUT_URL='https://portal.azure.com/#create/Microsoft.Template/uri/'$(printf "$TEMPLATE_URL" | jq -s -R -r @uri ) -echo $OUTPUT_URL - -# https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2Fazure-opensource-labs%2Faks-bicep%2Fcloud-native%2Faks-bicep%2F01-aks%2Fmain.json -``` diff --git a/cloud-native/aks-bicep/01-aks/RESOURCES.md b/cloud-native/aks-bicep/01-aks/RESOURCES.md deleted file mode 100644 index b226a09..0000000 --- a/cloud-native/aks-bicep/01-aks/RESOURCES.md +++ /dev/null @@ -1,5 +0,0 @@ -# RESOURCES - -- Initial AKS templates borrowed from: . -- -- diff --git a/cloud-native/aks-bicep/01-aks/aks.bicep b/cloud-native/aks-bicep/01-aks/aks.bicep deleted file mode 100644 index 245999a..0000000 --- a/cloud-native/aks-bicep/01-aks/aks.bicep +++ /dev/null @@ -1,139 +0,0 @@ -param location string = resourceGroup().location -param clusterName string = '' -param nodeCount int = 1 -param vmSize string = 'standard_d2s_v3' -param kubernetesVersion string = '1.29' - -var rand = substring(uniqueString(resourceGroup().id), 0, 6) -var clusterName_var = clusterName != '' ? clusterName : 'aks1' - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity' - location: location -} - -resource aks 'Microsoft.ContainerService/managedClusters@2021-05-01' = { - name: clusterName_var - location: location - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - kubernetesVersion: kubernetesVersion - dnsPrefix: clusterName_var - enableRBAC: true - agentPoolProfiles: [ - { - name: 'pool0' - count: nodeCount - vmSize: vmSize - mode: 'System' - } - ] - } -} - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2019-05-01' = { - name: 'acr${rand}' - location: location - sku: { - name: 'Standard' - } - properties: { - adminUserEnabled: true - } -} - -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { - name: 'storage${rand}' - location: location - kind: 'BlockBlobStorage' - sku: { - name: 'Premium_LRS' - } - properties: { - minimumTlsVersion: 'TLS1_2' - } -} - -resource serviceBus 'Microsoft.ServiceBus/namespaces@2021-06-01-preview' = { - name: 'servicebus${rand}' - location: location - sku: { - capacity: 1 - name: 'Standard' - tier: 'Standard' - } - properties: { - disableLocalAuth: false - } -} - -// via: https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-resource#subscriptionresourceid-example -var roleDefinitionId = { - Owner: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' - Contributor: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' - AcrPull: '7f951dda-4ed3-4680-a7ca-43fe172d538d' - StorageBlobDataContributor: 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' - ServiceBusDataOwner: '090c5cfd-751d-490a-894a-3ce6f1109419' - KubernetesServiceClusterUserRole: '4abbcc35-e782-43d8-92c5-2d3f1bd2253f' -} - -// https://github.com/Azure/bicep/discussions/3181 -var roleAssignmentAcrDefinition = 'AcrPull' -resource roleAssignmentAcr 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(containerRegistry.id, roleAssignmentAcrDefinition) - scope: containerRegistry - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentAcrDefinition]) - principalId: aks.properties.identityProfile.kubeletidentity.objectId - } -} - -var roleAssignmentStorageAccountDefinition = 'StorageBlobDataContributor' -resource roleAssignmentStorageAccount 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(storageAccount.id, roleAssignmentStorageAccountDefinition) - scope: storageAccount - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentStorageAccountDefinition]) - principalId: managedIdentity.properties.principalId - } - dependsOn: [ - aks - ] -} - -var roleAssignmentServiceBusDefinition = 'ServiceBusDataOwner' -resource roleAssignmentServiceBus 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(serviceBus.id, roleAssignmentServiceBusDefinition) - scope: serviceBus - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentServiceBusDefinition]) - principalId: managedIdentity.properties.principalId - } - dependsOn: [ - aks - ] -} - -resource managedIdentityDeploy 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity-deploy' - location: location -} - -var roleAssignmentDeploymentContributorDefinition = 'Contributor' -resource roleAssignmentDeploymentContributor 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(managedIdentityDeploy.id, roleAssignmentDeploymentContributorDefinition) - scope: resourceGroup() - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentDeploymentContributorDefinition]) - principalId: managedIdentityDeploy.properties.principalId - } - dependsOn: [ - aks - ] -} diff --git a/cloud-native/aks-bicep/01-aks/deploy-aks.sh b/cloud-native/aks-bicep/01-aks/deploy-aks.sh deleted file mode 100644 index 4fe8faa..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-aks.sh +++ /dev/null @@ -1,6 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode complete \ - --template-file ./aks.bicep diff --git a/cloud-native/aks-bicep/01-aks/deploy-deploy-script.sh b/cloud-native/aks-bicep/01-aks/deploy-deploy-script.sh deleted file mode 100644 index ddea718..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-deploy-script.sh +++ /dev/null @@ -1,9 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${LOCATION:-}" ]] && LOCATION='eastus' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode incremental \ - --template-file ./deploy-script.bicep \ - --parameters \ - scriptUri='https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/aks-bicep/cloud-native/aks-bicep/01-aks/deploy-script-aks.sh' diff --git a/cloud-native/aks-bicep/01-aks/deploy-empty.sh b/cloud-native/aks-bicep/01-aks/deploy-empty.sh deleted file mode 100644 index dd3f0f3..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-empty.sh +++ /dev/null @@ -1,6 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode complete \ - --template-file ./empty.bicep diff --git a/cloud-native/aks-bicep/01-aks/deploy-keyvault.sh b/cloud-native/aks-bicep/01-aks/deploy-keyvault.sh deleted file mode 100644 index f1cf287..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-keyvault.sh +++ /dev/null @@ -1,6 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' - -az deployment group create \ - --resource-group $RESOURCE_GROUP \ - --mode incremental \ - --template-file ./keyvault.bicep diff --git a/cloud-native/aks-bicep/01-aks/deploy-main.sh b/cloud-native/aks-bicep/01-aks/deploy-main.sh deleted file mode 100644 index 053a941..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-main.sh +++ /dev/null @@ -1,11 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${LOCATION:-}" ]] && LOCATION='eastus' -[[ -z "${AKS_NAME:-}" ]] && AKS_NAME='aks1' - -az deployment sub create \ - --location $LOCATION \ - --template-file ./main.bicep \ - --parameters \ - deployScript='true' \ - scriptUri='https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/aks-bicep/cloud-native/aks-bicep/01-aks/deploy-script-keda.sh' \ - resourceGroup=$RESOURCE_GROUP diff --git a/cloud-native/aks-bicep/01-aks/deploy-script-aks.sh b/cloud-native/aks-bicep/01-aks/deploy-script-aks.sh deleted file mode 100644 index 6ed1964..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-script-aks.sh +++ /dev/null @@ -1,8 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${AKS_NAME:-}" ]] && AKS_NAME='aks1' - -echo "az aks command invoke" -az aks command invoke \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --command 'kubectl run nginx --image=nginx' diff --git a/cloud-native/aks-bicep/01-aks/deploy-script-keda.sh b/cloud-native/aks-bicep/01-aks/deploy-script-keda.sh deleted file mode 100644 index 70cd14b..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-script-keda.sh +++ /dev/null @@ -1,8 +0,0 @@ -[[ -z "${RESOURCE_GROUP:-}" ]] && RESOURCE_GROUP='220600-keda' -[[ -z "${AKS_NAME:-}" ]] && AKS_NAME='aks1' - -echo "az aks command invoke" -az aks command invoke \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --command 'kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.7.1/keda-2.7.1.yaml' diff --git a/cloud-native/aks-bicep/01-aks/deploy-script.bicep b/cloud-native/aks-bicep/01-aks/deploy-script.bicep deleted file mode 100644 index df50a7e..0000000 --- a/cloud-native/aks-bicep/01-aks/deploy-script.bicep +++ /dev/null @@ -1,65 +0,0 @@ -param location string = resourceGroup().location -param utcValue string = utcNow() -param resourceGroupName string = resourceGroup().name -// url to deploy-script-*.sh in repo -param scriptUri string = '' - -resource managedIdentityDeploy 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity-deploy' - location: location -} - -var roleDefinitionId = { - Owner: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' - Contributor: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' -} - -// https://github.com/Azure/bicep/discussions/3181 -var roleAssignmentDeploymentContributorDefinition = 'Contributor' -resource roleAssignmentDeploymentContributor 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = { - name: guid(managedIdentityDeploy.id, roleAssignmentDeploymentContributorDefinition) - scope: resourceGroup() - properties: { - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId[roleAssignmentDeploymentContributorDefinition]) - principalId: managedIdentityDeploy.properties.principalId - } -} - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'deploy-script' - location: location - kind: 'AzureCLI' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentityDeploy.id}': {} - } - } - properties: { - environmentVariables: [ - { - name: 'RESOURCE_GROUP' - value: resourceGroupName - } - { - name: 'AKS_NAME' - value: 'aks1' - } - { - name: 'NAMESPACE' - value: 'keda-http' - } - ] - forceUpdateTag: utcValue - azCliVersion: '2.28.0' - timeout: 'PT30M' - //arguments: '\'211200-cloud-native\'' - //scriptContent: 'echo "arg1 is: $1"; value=$1; echo \'{}\' | jq --arg value "$value" \'.Result = $value\' | tee $AZ_SCRIPTS_OUTPUT_PATH' - primaryScriptUri: scriptUri - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - } -} - -//output result object = deploymentScript.properties.outputs diff --git a/cloud-native/aks-bicep/01-aks/empty.bicep b/cloud-native/aks-bicep/01-aks/empty.bicep deleted file mode 100644 index 3d70e64..0000000 --- a/cloud-native/aks-bicep/01-aks/empty.bicep +++ /dev/null @@ -1 +0,0 @@ -output group string = resourceGroup().id diff --git a/cloud-native/aks-bicep/01-aks/keyvault.bicep b/cloud-native/aks-bicep/01-aks/keyvault.bicep deleted file mode 100644 index 5aa5280..0000000 --- a/cloud-native/aks-bicep/01-aks/keyvault.bicep +++ /dev/null @@ -1,34 +0,0 @@ -param location string = resourceGroup().location - -var rand = substring(uniqueString(resourceGroup().id), 0, 6) - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${resourceGroup().name}-identity' - location: location -} - -resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = { - name: 'keyvault${rand}' - location: location - properties: { - enabledForDeployment: true - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - tenantId: subscription().tenantId - sku: { - name: 'standard' - family: 'A' - } - accessPolicies: [ - { - objectId: managedIdentity.properties.principalId - permissions: { - secrets: [ - 'all' - ] - } - tenantId: subscription().tenantId - } - ] - } -} diff --git a/cloud-native/aks-bicep/01-aks/main.bicep b/cloud-native/aks-bicep/01-aks/main.bicep deleted file mode 100644 index c384033..0000000 --- a/cloud-native/aks-bicep/01-aks/main.bicep +++ /dev/null @@ -1,31 +0,0 @@ -targetScope = 'subscription' - -param resourceGroup string = '220600-keda' -param location string = deployment().location -param deployScript bool = false -param scriptUri string = 'https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/aks-bicep/cloud-native/aks-bicep/01-aks/deploy-script-keda.sh' - -resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { - name: resourceGroup - location: location -} - -module aks './aks.bicep' = { - name: '${resourceGroup}-aks' - scope: rg - params: { - location: location - } -} - -module script './deploy-script.bicep' = if(deployScript) { - name: '${resourceGroup}-deployscript' - scope: rg - params: { - location: location - scriptUri: scriptUri - } - dependsOn: [ - aks - ] -} diff --git a/cloud-native/aks-bicep/01-aks/main.json b/cloud-native/aks-bicep/01-aks/main.json deleted file mode 100644 index 656d80f..0000000 --- a/cloud-native/aks-bicep/01-aks/main.json +++ /dev/null @@ -1,365 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "9190321452261239824" - } - }, - "parameters": { - "resourceGroup": { - "type": "string", - "defaultValue": "220600-keda" - }, - "location": { - "type": "string", - "defaultValue": "[deployment().location]" - }, - "deployScript": { - "type": "bool", - "defaultValue": false - }, - "scriptUri": { - "type": "string", - "defaultValue": "https://raw.githubusercontent.com/Azure-Samples/azure-opensource-labs/aks-bicep/cloud-native/aks-bicep/01-aks/deploy-script-keda.sh" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2021-04-01", - "name": "[parameters('resourceGroup')]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-aks', parameters('resourceGroup'))]", - "resourceGroup": "[parameters('resourceGroup')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "7703729210362399507" - } - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "clusterName": { - "type": "string", - "defaultValue": "" - }, - "nodeCount": { - "type": "int", - "defaultValue": 1 - }, - "vmSize": { - "type": "string", - "defaultValue": "standard_d2s_v3" - }, - "kubernetesVersion": { - "type": "string", - "defaultValue": "1.29" - } - }, - "variables": { - "rand": "[substring(uniqueString(resourceGroup().id), 0, 6)]", - "clusterName_var": "[if(not(equals(parameters('clusterName'), '')), parameters('clusterName'), 'aks1')]", - "roleDefinitionId": { - "Owner": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", - "Contributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7", - "AcrPull": "7f951dda-4ed3-4680-a7ca-43fe172d538d", - "StorageBlobDataContributor": "ba92f5b4-2d11-453d-a403-e96b0029c9fe", - "ServiceBusDataOwner": "090c5cfd-751d-490a-894a-3ce6f1109419", - "KubernetesServiceClusterUserRole": "4abbcc35-e782-43d8-92c5-2d3f1bd2253f" - }, - "roleAssignmentAcrDefinition": "AcrPull", - "roleAssignmentStorageAccountDefinition": "StorageBlobDataContributor", - "roleAssignmentServiceBusDefinition": "ServiceBusDataOwner", - "roleAssignmentDeploymentContributorDefinition": "Contributor" - }, - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2021-05-01", - "name": "[variables('clusterName_var')]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)))]": {} - } - }, - "properties": { - "kubernetesVersion": "[parameters('kubernetesVersion')]", - "dnsPrefix": "[variables('clusterName_var')]", - "enableRBAC": true, - "agentPoolProfiles": [ - { - "name": "pool0", - "count": "[parameters('nodeCount')]", - "vmSize": "[parameters('vmSize')]", - "mode": "System" - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name))]" - ] - }, - { - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2019-05-01", - "name": "[format('acr{0}', variables('rand'))]", - "location": "[parameters('location')]", - "sku": { - "name": "Standard" - }, - "properties": { - "adminUserEnabled": true - } - }, - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-02-01", - "name": "[format('storage{0}', variables('rand'))]", - "location": "[parameters('location')]", - "kind": "BlockBlobStorage", - "sku": { - "name": "Premium_LRS" - }, - "properties": { - "minimumTlsVersion": "TLS1_2" - } - }, - { - "type": "Microsoft.ServiceBus/namespaces", - "apiVersion": "2021-06-01-preview", - "name": "[format('servicebus{0}', variables('rand'))]", - "location": "[parameters('location')]", - "sku": { - "capacity": 1, - "name": "Standard", - "tier": "Standard" - }, - "properties": { - "disableLocalAuth": false - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', format('acr{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries', format('acr{0}', variables('rand'))), variables('roleAssignmentAcrDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentAcrDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var')), '2021-05-01').identityProfile.kubeletidentity.objectId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ContainerRegistry/registries', format('acr{0}', variables('rand')))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', format('storage{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', format('storage{0}', variables('rand'))), variables('roleAssignmentStorageAccountDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentStorageAccountDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name))]", - "[resourceId('Microsoft.Storage/storageAccounts', format('storage{0}', variables('rand')))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', format('servicebus{0}', variables('rand')))]", - "name": "[guid(resourceId('Microsoft.ServiceBus/namespaces', format('servicebus{0}', variables('rand'))), variables('roleAssignmentServiceBusDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentServiceBusDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity', resourceGroup().name))]", - "[resourceId('Microsoft.ServiceBus/namespaces', format('servicebus{0}', variables('rand')))]" - ] - }, - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity-deploy', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), variables('roleAssignmentDeploymentContributorDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentDeploymentContributorDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', variables('clusterName_var'))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name))]" - ] - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroup'))]" - ] - }, - { - "condition": "[parameters('deployScript')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-deployscript', parameters('resourceGroup'))]", - "resourceGroup": "[parameters('resourceGroup')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "scriptUri": { - "value": "[parameters('scriptUri')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "9861108784878104103" - } - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "utcValue": { - "type": "string", - "defaultValue": "[utcNow()]" - }, - "resourceGroupName": { - "type": "string", - "defaultValue": "[resourceGroup().name]" - }, - "scriptUri": { - "type": "string", - "defaultValue": "" - } - }, - "variables": { - "roleDefinitionId": { - "Owner": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635", - "Contributor": "b24988ac-6180-42a0-ab88-20f7382dd24c", - "Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7" - }, - "roleAssignmentDeploymentContributorDefinition": "Contributor" - }, - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[format('{0}-identity-deploy', resourceGroup().name)]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-08-01-preview", - "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), variables('roleAssignmentDeploymentContributorDefinition'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', variables('roleDefinitionId')[variables('roleAssignmentDeploymentContributorDefinition')])]", - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)), '2018-11-30').principalId]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name))]" - ] - }, - { - "type": "Microsoft.Resources/deploymentScripts", - "apiVersion": "2020-10-01", - "name": "deploy-script", - "location": "[parameters('location')]", - "kind": "AzureCLI", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name)))]": {} - } - }, - "properties": { - "environmentVariables": [ - { - "name": "RESOURCE_GROUP", - "value": "[parameters('resourceGroupName')]" - }, - { - "name": "AKS_NAME", - "value": "aks1" - }, - { - "name": "NAMESPACE", - "value": "keda-http" - } - ], - "forceUpdateTag": "[parameters('utcValue')]", - "azCliVersion": "2.28.0", - "timeout": "PT30M", - "primaryScriptUri": "[parameters('scriptUri')]", - "cleanupPreference": "OnSuccess", - "retentionInterval": "P1D" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('{0}-identity-deploy', resourceGroup().name))]" - ] - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroup')), 'Microsoft.Resources/deployments', format('{0}-aks', parameters('resourceGroup')))]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroup'))]" - ] - } - ] -} \ No newline at end of file diff --git a/cloud-native/aks-bicep/README.md b/cloud-native/aks-bicep/README.md deleted file mode 100644 index 9e355df..0000000 --- a/cloud-native/aks-bicep/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Explore Open Source workloads with Azure Kubernetes Service (AKS) and Bicep - -In this lab you will deploy an Azure Kubernetes Service (AKS) cluster and other Azure services (Container Registry, Managed Identity, Storage Account, Service Bus, Key Vault), the open source KEDA (Kubernetes Event-driven Autoscaling) project with [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview). - -## Requirements - -- An **Azure Subscription** (e.g. [Free](https://aka.ms/azure-free-account) or [Student](https://aka.ms/azure-student-account) account) -- The [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) -- Bash shell (e.g. macOS, Linux, [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about), [Multipass](https://multipass.run/), [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/quickstart), [GitHub Codespaces](https://github.com/features/codespaces), etc) -- A [GitHub Account](https://github.com) - -## Instructions - -Use the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) templates to deploy the infrastructure for your application. - -Login to the Azure CLI. - -```bash -az login -``` - -Install kubectl using the Azure CLI, if required. - -```bash -az aks install-cli -``` - -Deploy the Bicep template for your Azure Kubernetes Service (AKS) cluster. - -```bash -cd cloud-native/aks-bicep/01-aks -bash deploy-main.sh -``` - -Invoke kubectl command on AKS cluster. - -```bash -RESOURCE_GROUP='220600-keda' -AKS_NAME='aks1' - -az aks command invoke \ - --resource-group $RESOURCE_GROUP \ - --name $AKS_NAME \ - --command 'kubectl run nginx --image=nginx' -``` diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/README.md b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/README.md deleted file mode 100644 index f83aa18..0000000 --- a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/README.md +++ /dev/null @@ -1,225 +0,0 @@ -# Part 2: Bookstore application deployment - -With an AKS cluster deployed, let's focus on deploying an application and configuring it to work with OSM and NGINX ingress. - -The sample app deployed here is the same application demonstrated in [OSM's Getting Started guide](https://release-v1-2.docs.openservicemesh.io/docs/getting_started/install_apps/). The getting started guide uses [port-forwarding for exposing the application](https://release-v1-2.docs.openservicemesh.io/docs/getting_started/install_apps/#view-the-application-uis), but you will use the managed NGINX ingress controller instead. You will also need to deploy OSM `IngressBackend` configurations to route NGINX-managed ingress traffic to OSM-managed service backends. - -## Application overview - -Here is a simple diagram of the application pods that will be deployed into the cluster. - -![Bookstore Application Diagram](./bookstore_app.png) - -The `mysql` database pod is where book transactions are recorded. The `bookwarehouse` pod is responsible for reading/writing data to the database and should only be reachable from the `bookstore` pod. The `bookbuyer` and `bookthief` pods act as clients of the `bookstore` app. As the names suggest, one buys books from the bookstore while the other steals books. - -The intent of this part of the lab is to just get the application up an running and demonstrate a working service mesh in permissive mode (the default). - -Please ensure you have completed the steps in [Part 1](../README.md) before you proceed. - -Make sure you are in the correct working directory (`cloud-native/aks-open-service-mesh/02-deploying-bookstore-app`) - -```bash -cd 02-deploying-bookstore-app -``` - -## Deploy the namespaces to Kubernetes - -As mentioned in Part 1, you need to add namespaces to OSM so that it can start managing traffic for them. - -Run the following commands to create the application namespaces. - -```bash -kubectl create namespace bookstore -kubectl create namespace bookbuyer -kubectl create namespace bookthief -kubectl create namespace bookwarehouse -``` - -Onboard the applications to OSM by adding the namespaces to OSM. - -```bash -osm namespace add bookstore bookbuyer bookthief bookwarehouse -``` - -You should see output similar to the following: - -```text -Namespace [bookstore] successfully added to mesh [osm] -Namespace [bookbuyer] successfully added to mesh [osm] -Namespace [bookthief] successfully added to mesh [osm] -Namespace [bookwarehouse] successfully added to mesh [osm] -``` - -Let's take a look at the labels that have been added to these namespaces. - -```bash -kubectl get namespace -A --show-labels | grep book -``` - -The namespaces have also been annotated by OSM to specify whether or not the control plane should be injecting data plane side cars into pods. You can see the annotation for each with these commands. - -```bash -kubectl get namespace bookstore -o jsonpath='{.metadata.annotations}' -kubectl get namespace bookbuyer -o jsonpath='{.metadata.annotations}' -kubectl get namespace bookthief -o jsonpath='{.metadata.annotations}' -kubectl get namespace bookwarehouse -o jsonpath='{.metadata.annotations}' -``` - -You can also verify using the OSM CLI. - -```bash -osm namespace list -``` - -## Deploy the application to Kubernetes - -The deployment manifests are hosted in the [OSM docs repo](https://github.com/openservicemesh/osm-docs/tree/main/manifests/apps), so you can deploy them directly from there. - -Run the following commands to deploy the applications. - -```bash -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/apps/bookbuyer.yaml -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/apps/bookthief.yaml -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/apps/bookstore.yaml -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/apps/bookwarehouse.yaml -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/apps/mysql.yaml -``` - -## Exploring the `bookbuyer` pod and viewing `osm` configuration - -Check on the `bookbuyer` pods - -```bash -kubectl get pod -n bookbuyer -``` - -You should see an output similar to this: - -```text -NAME READY STATUS RESTARTS AGE -bookbuyer-6c759555b8-n4m7c 2/2 Running 0 112s -``` - -Do you notice the `READY` column reporting `2/2`? This means OSM sidecar injector has done its job. If you inspect the `bookbuyer` pod, you will see some event logs that indicate OSM was in there initializing itself and injecting the Envoy Proxy sidecar. - -```bash -kubectl describe pod -l app=bookbuyer -n bookbuyer -``` - -## Exposing the `bookbuyer`, `bookthief` and `bookstore` web applications - -Let's make use of the NGINX ingress and expose the `bookbuyer`, `bookthief` and `bookstore` web applications so that we can connect to them from a web browser. - -> These web applications are setup to auto-refresh with a running counter indicating how many books were purchased, stolen, and the version of bookstore that was running at the time of transaction. - -Expose the `bookbuyer` app by deploying a service and ingress. - -```bash -kubectl apply -f ./bookbuyer-ui.yaml -``` - -Check the status of the ingress. - -```bash -kubectl get ingress -n bookbuyer -``` - -You should see output similar to this: - -```text -NAME CLASS HOSTS ADDRESS PORTS AGE -bookbuyer webapprouting.kubernetes.azure.com * 4.236.214.31 80 51s -``` - -A public IP address has been assigned to the ingress; however, the site will not work yet. The `bookstore` namespace is participating in the service mesh, so an `IngressBackend` resource is required to allow HTTP communication between the ingress and the backend service. - -Deploy the `IngressBackend` for `bookbuyer` with the following command: - -```bash -kubectl apply -f ./bookbuyer-ui-ingressbackend.yaml -``` - -Check the status of the ingress backend. - -```bash -kubectl get ingressbackend -n bookbuyer -``` - -You should see output similar to this: - -```text -NAME STATUS -bookbuyer committed -``` - -> Once you see a `STATUS` of `committed`, your application should be accessible to the internet. - -Repeat the steps above for `bookthief` and `bookstore` apps. - -```bash -kubectl apply -f ./bookthief-ui.yaml -kubectl apply -f ./bookstore-ui.yaml -kubectl apply -f ./bookthief-ui-ingressbackend.yaml -kubectl apply -f ./bookstore-ui-ingressbackend.yaml -``` - -Run the following command again to view the status of the `IngressBackends`. - -```bash -kubectl get ingressbackend -A -``` - -You should see output similar to this: - -```text -NAMESPACE NAME STATUS -bookbuyer bookbuyer committed -bookstore bookstore committed -bookthief bookthief committed -``` - -Now you should be able to access all of the sites. Issue the commands below and click each link to open the site in a web browser. - -```bash -nginx_ingress_host="$(kubectl -n app-routing-system get service nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" - -# these are the urls you should open in your browser -echo http://$nginx_ingress_host/bookbuyer -echo http://$nginx_ingress_host/bookthief -echo http://$nginx_ingress_host/bookstore -``` - -You should see each application auto-incrementing its sales, thefts, and books sold counters. - -### Bookbuyer - -![bookbuyer](./bookbuyer.png) - -### Bookthief - -![bookthief](./bookthief.png) - -### Bookstore v1 - -![bookstore-v1](./bookstore-v1.png) - -## Next steps - -We've successfully deployed the `bookbuyer`, `bookthief`, and `bookstore` applications and exposed their frontend UIs via ingress and configured OSM to allow traffic between the ingress endpoints and backend services. By default, OSM is configured in permissive traffic policy mode and we've enabled traffic to flow between ingress and backend service pods. - -Now, head over to [Part 3: Applying Zero-Trust to the Bookstore application](../03-applying-zero-trust/README.md) to apply some Zero-Trust principles! - -## Resources - -* [Bookstore Sample Application][osm_bookstore_sample] -* [OSM and NGINX Ingress Controller Configuration][osm_nginx_ing] -* [OSM Permissive Traffic Policy][osm_permissive_traffic_policy] -* [Kubernetes: Service][k8s_svc] -* [Kubernetes: Ingress][k8s_ing] - - -[osm_bookstore_sample]:https://release-v1-2.docs.openservicemesh.io/docs/getting_started/install_apps/ -[osm_nginx_ing]:https://release-v1-2.docs.openservicemesh.io/docs/demos/ingress_k8s_nginx/ -[osm_permissive_traffic_policy]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/permissive_mode/ -[k8s_svc]:https://kubernetes.io/docs/concepts/services-networking/service/ -[k8s_ing]:https://kubernetes.io/docs/concepts/services-networking/ingress/ diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui-ingressbackend.yaml b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui-ingressbackend.yaml deleted file mode 100644 index 2073fd2..0000000 --- a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui-ingressbackend.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: policy.openservicemesh.io/v1alpha1 -kind: IngressBackend -metadata: - name: bookbuyer - namespace: bookbuyer -spec: - backends: - - name: bookbuyer - port: - number: 14001 # targetPort of bookbuyer service - protocol: http - sources: - - kind: Service - namespace: app-routing-system - name: nginx \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui.yaml b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui.yaml deleted file mode 100644 index 24a6f7f..0000000 --- a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer-ui.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: bookbuyer - namespace: bookbuyer - labels: - app: bookbuyer - service: bookbuyer -spec: - ports: - - name: http - port: 14001 - selector: - app: bookbuyer - version: v1 ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: bookbuyer - namespace: bookbuyer - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / -spec: - ingressClassName: webapprouting.kubernetes.azure.com # managed nginx ingress class name - rules: - - http: - paths: - - path: /bookbuyer - pathType: Prefix - backend: - service: - name: bookbuyer - port: - number: 14001 \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer.png b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookbuyer.png deleted file mode 100644 index 5babaaf995a98307fe935ca97f6d462b5ce17c8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57396 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≦EyLx4XD+> z-yf4Rp#hS%YtQiJxMq6zZfG37ImrhDya)lP9^F8ps04f_;nh@Z`Bz(xx6z zKJ!<$uvYthX@zy@E!py7fa1E?>0e|e7rOlQ@wY^`b{9zFLnD$Bx6e}Ahy%X22yNlt zNC)&N9y`Prj@;EM9>@j21Ahz;+wi21R#+XjfPAdE&HW4p8q6SJ4-Fq>TuPTZ3z&*$ zIFOb~ZE-w_hp(}$w`Qu!RCV#kC)!gT|4(*hQc(R($0rkU) zMmJ1Ud6bAz>xH?|D>0G#oyq6cf0rM$Ae#dhVAlFM&pCh&r&qu&(A+yszdT0dJE4n0F>-;FTYzyY)K$FUbL@Xslq~HM}*+(a9Cc zlBSCt@uBcyd^Wvg$$lY<=rK0LexxWP1)GbA9kZ@-1(kdUp>iEYm#kl!H$ch!{vm1%a1 z1$aF1cJ;#%2-_QzMy(j!BbTzJ$t=irmn+ax^D<%TEKuIU5AM%5tzgPwX985J4XDnH zEh$j@)40-eg0esoed3PHZSvvw+i2VYz+gTv_x>NAMJfo;m47e!S1y18o%&Z9{xy>S fPkV-X61ClM+~@k9DKYZvTQ%?K-Y&TH`1yYWOL_l@ diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui-ingressbackend.yaml b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui-ingressbackend.yaml deleted file mode 100644 index 3c991c6..0000000 --- a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui-ingressbackend.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: policy.openservicemesh.io/v1alpha1 -kind: IngressBackend -metadata: - name: bookthief - namespace: bookthief -spec: - backends: - - name: bookthief - port: - number: 14001 # targetPort of bookthief service - protocol: http - sources: - - kind: Service - namespace: app-routing-system - name: nginx \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui.yaml b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui.yaml deleted file mode 100644 index a36d71a..0000000 --- a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief-ui.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: bookthief - namespace: bookthief - labels: - app: bookthief - service: bookthief -spec: - ports: - - name: http - port: 14001 - selector: - app: bookthief ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: bookthief - namespace: bookthief - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / -spec: - ingressClassName: webapprouting.kubernetes.azure.com # managed nginx ingress class name - rules: - - http: - paths: - - path: /bookthief - pathType: Prefix - backend: - service: - name: bookthief - port: - number: 14001 diff --git a/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief.png b/cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/bookthief.png deleted file mode 100644 index dc0f75e6bfe1d9bd8727877f87b9372323d710a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54135 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 AY5)KL diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/README.md b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/README.md deleted file mode 100644 index 643782a..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/README.md +++ /dev/null @@ -1,226 +0,0 @@ -# Part 3: Applying Zero-Trust to the Bookstore application - -So far you have deployed and exposed the Bookstore app via managed NGINX ingress controller and onboarded the Bookstore namespaces to OSM. Communication between pods within the service mesh is wide-open with the **permissive traffic policy** enabled and books are being stolen by the `bookthief` app. You need to lock things down and ensure `bookthief` is no longer able to communicate with `bookstore` and steal any more books. You will also ensure you have end-to-end encryption in place for internal communication between the ingress and backend services using mutual TLS (mTLS). - -Please ensure you have completed the steps in [Part 2: Bookstore application deployment](../02-deploying-bookstore-app/README.md) before you proceed. - -Make sure you are in the right working directory (this command assumes you are currently in the `cloud-native/aks-open-service-mesh/02-deploying-bookstore-app/` directory). - -```bash -cd ../03-applying-zero-trust -``` - -## Securing communications between ingress and backend services - -You will start by enforcing mTLS between the NGINX ingress controller. In order to secure communications between our managed ingress controller and OSM, you will need to update the `Ingress` manifests to include NGINX controller-specific [`annotations`][nginx_annotations] and update our [`IngressBackend`][osm_ingressbackend_api] manifest to enforce HTTPS traffic using TLS certificates which have been created by OSM. - -### Updating `Ingress` manifests - -To secure communications, NGINX it will need to present a certificate to OSM. The following NGINX-specific `annotations` need to be added to the `Ingress` manifests: - -* [`nginx.ingress.kubernetes.io/backend-protocol`][nginx_annotations_backend_protocol] tells NGINX how to communicate with the backend service. In our case, this will be set to `HTTPS` -* [`nginx.ingress.kubernetes.io/configuration-snippet`][nginx_annotations_configuration_snippet] to pass in additional configuration information for OSM. In our case, this will be set to `proxy_ssl_name "bookbuyer.bookbuyer.cluster.local";` -* [`nginx.ingress.kubernetes.io/proxy-ssl-secret`][nginx_annotations_proxy_ssl_secret] is the secret name formatted as `namespace/secretName` where the client certificate is stored. This certificate is used by NGINX to proxy HTTPS connects to TLS backends. In our case, this will be set to `kube-system/osm-ingress-client-cert` -* [`nginx.ingress.kubernetes.io/proxy-ssl-verify`][nginx_annotations_proxy_ssl_verify] enables or disables verification of proxied HTTPS server certificate. In our case, this will be set to `on` - -Typically you would need to manually [edit the OSM `meshconfig` resource](https://release-v1-2.docs.openservicemesh.io/docs/demos/ingress_k8s_nginx/#https-ingress-mtls-and-tls) so that OSM can issue and store certificates within a [Kubernetes secret][k8s_secret]. With managed-OSM, this configuration is done for you. - -To retrieve the details of the certificate for ingress gateway, you can run the following command: - -```bash -kubectl get meshconfig osm-mesh-config -n kube-system -o yaml -``` - -In the output, you should see `certificate` details. Here is the snippet of code you should look for. - -```yaml -... -certificate: - certKeyBitSize: 2048 - ingressGateway: - secret: - name: osm-ingress-client-cert - namespace: kube-system - subjectAltNames: - - ingress-nginx.ingress.cluster.local - validityDuration: 24h - serviceCertValidityDuration: 24h -... -``` - -The truncated output above lists the certificate details which will be used by the ingress; it includes the secret's `name`, `namespace`, and the `subjectAltNames` (SAN) of the TLS certificate. - -### Updating `IngressBackend` manifests - -You will need to update the `IngressBackend` manifests using the certificate information listed above. - -First, you need to update the [`IngressBackendSpec`][osm_ingressbackendspec] and change the `PortSpec` from `http` to `https`. Then you will need to add a `TLSSpec` element and set the `skipClientCertValidation` to `false`. - -From there, you need to update the [`IngressSourceSpec`][osm_ingresssourcespec] and add a new source with the `kind` attribute being set to `AuthenticatedPrincipal` and set the `name` attribute to `ingress-nginx.ingress.cluster.local`. This tells OSM to expect traffic from the NGINX ingress controller. - -OSM provisioned a client certificate for the NGINX ingress service with the Subject ALternative Name (SAN) `ingress-nginx.ingress.cluster.local`, so the `IngressBackend` configuration needs to reference the same SAN for mTLS authentication (between the Nginx ingress service and the backend services). - -The name of the `subjectAltNames` object can also be pulled from the OSM `meshconfig` resource. You can view it with the following command. - -```bash -kubectl get meshconfig osm-mesh-config -n kube-system -o jsonpath='{.spec.certificate.ingressGateway}' | jq -r .subjectAltNames | jq -r '.[0]' -``` - -Here is an example of what the new `IngressBackend` looks like for the `bookbuyer` app: - -![bookbuyer](./bookbuyer.png) - -### Apply the updated ingress configurations - -The `Ingress` and `IngressBackend` manifests have been updated for you so you can simply apply the configuration to lock down the ingress to backend service traffic with OSM. - -Let's re-deploy `Ingress` and `IngressBackend` resources for `bookbuyer`, `bookthief`, and `bookstore` using the following commands. - -```bash -kubectl apply -f bookbuyer-ui-secure-ingress.yaml -kubectl apply -f bookthief-ui-secure-ingress.yaml -kubectl apply -f bookstore-ui-secure-ingress.yaml -``` - -> Whenever changes are made to Ingress resources, IngressBackend resources are re-synced. - -Confirm the `IngressBackend` statuses show as "committed". - -```bash -kubectl get ingressbackend -A -``` - -If you still have your apps open in a browser, you might need to refresh the pages to confirm the app is still running. - -If you need the site URLs again, run the following commands: - -```bash -nginx_ingress_host="$(kubectl -n app-routing-system get service nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" - -# these are the urls you should open in your browser -echo http://$nginx_ingress_host/bookbuyer -echo http://$nginx_ingress_host/bookthief -echo http://$nginx_ingress_host/bookstore -``` - -## Configure SMI traffic policies - -OSM is running in permissive mode, which means all resources enrolled in the mesh can talk freely with each other. One of the main reasons why you would want to implement a service mesh is to enforce end-to-end encryption of network communications. This is one of the key features of OSM and you can enabled it using [SMI traffic policies][osm_smi_traffic_policy]. - -### Disable permissive traffic policies - -Run this command to disable permissive traffic policy mode. - -```bash -kubectl patch meshconfig osm-mesh-config -n kube-system -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":false}}}' --type=merge -``` - -### Enable SMI traffic policies - -With the permissive traffic policy mode disabled, the application pods can no longer communicate with each other. If you have the **bookbuyer**, **bookthief**, and **bookstore** applications still open in your web browser, you will see the counters have stopped incrementing. - -Communication within the service mesh has gone from default allow, to default deny. OSM now requires [SMI access control policies][osm_smi_access_control_policy] (e.g., `TrafficTarget`, `HTTPRouteGroup`, and `TCPRoute` CRDs) to enable traffic flow. - -Here's an overview of each resource: - -**[`TrafficTarget`][smi_traffictarget]**: Used to associate a set of traffic definitions (rules) with a service identity. Access control is based on [service identity][k8s_serviceaccount] which can be allocated to groups of pods. - -**[`HTTPRouteGroup`][smi_httproutegroup]**: Describes the HTTP/1 and HTTP/2 traffic characteristics to filter on in `TrafficTarget` rule definitions. Filters can be applied to combinations of HTTP headers, paths using Regex, and methods. - -**[`TCPRoute`][smi_tcproute]**: Describes the L4 TCP traffic to filter on in `TrafficTarget` rule definitions. - -**[`UDPRoute`][smi_udproute]**: Describes the L4 UDP traffic to filter on in `TrafficTarget` rule definitions. - -Using the `HTTPRouteGroup` resource, you can define a traffic filter for GET requests that are made to the `/books-bought` path with specific header information like this. - -```yaml -apiVersion: specs.smi-spec.io/v1alpha4 -kind: HTTPRouteGroup -metadata: - name: bookstore-service-routes - namespace: bookstore -spec: - matches: - - name: books-bought - pathRegex: /books-bought - methods: - - GET - headers: - - "user-agent": ".*-http-client/*.*" - - "client-app": "bookbuyer" - - name: buy-a-book - pathRegex: ".*a-book.*new" - methods: - - GET -``` - -The manifest above will filter network requests and can be used to define rules for allowing traffic flow. Using the `TrafficTarget` resource, you can apply the filter to specific source/destination pairs. - -```yaml -kind: TrafficTarget -apiVersion: access.smi-spec.io/v1alpha3 -metadata: - name: bookstore - namespace: bookstore -spec: - destination: - kind: ServiceAccount - name: bookstore - namespace: bookstore - rules: - - kind: HTTPRouteGroup - name: bookstore-service-routes - matches: - - buy-a-book - - books-bought - sources: - - kind: ServiceAccount - name: bookbuyer - namespace: bookbuyer -``` - -The manifest above will create a new access policy that filters traffic based on the `HTTPRouteGroup` named `bookstore-service-routes` and allow pods that are running as the `bookbuyer` service account to communicate with pods running as the `bookstore` service account. - -> Note that OSM uses `ServiceAccounts` to identify groups of resources. - -Run the command below to deploy the SMI traffic access policies. - -```bash -kubectl apply -f smi-traffic-to-mysql.yaml -kubectl apply -f smi-traffic-to-bookwarehouse.yaml -kubectl apply -f smi-traffic-to-bookstore.yaml -``` - -Now if you re-visit the **bookbuyer** and **bookstore** web applications, you'll see the counters are incrementing again. However, the **bookthief** application was not given access to communicate to **bookstore** and therefore, the counter remains idle. - -## Next steps - -Congratulations, you have successfully blocked the **bookthief** application from stealing books 🎉 - -Next, head over to [Part 4: Traffic splitting with OSM](../04-osm-traffic-splitting/README.md) where you will deploy a new version of the **bookstore** app and take a canary approach to release **bookstore v2**. - -## Resources - -* [IngressBackend API][osm_ingressbackend_api] -* [Traffic Access Control][smi_traffictarget] -* [Traffic Specs][smi_trafficspecs] -* [NGINX Ingress Controller Annotations][nginx_annotations] - - -[osm_smi_traffic_policy]:https://release-v1-2.docs.openservicemesh.io/docs/getting_started/traffic_policies/#smi-traffic-policy-mode -[osm_smi_access_control_policy]:https://release-v1-2.docs.openservicemesh.io/docs/getting_started/traffic_policies/#deploy-smi-access-control-policies -[osm_ingressbackend_api]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/ingress -[osm_ingressbackendspec]:https://release-v1-2.docs.openservicemesh.io/docs/api_reference/policy/v1alpha1/#policy.openservicemesh.io/v1alpha1.BackendSpec -[osm_ingresssourcespec]:https://release-v1-2.docs.openservicemesh.io/docs/api_reference/policy/v1alpha1/#policy.openservicemesh.io/v1alpha1.IngressSourceSpec -[smi_trafficspecs]:https://github.com/servicemeshinterface/smi-spec/blob/v0.6.0/apis/traffic-specs/v1alpha4/traffic-specs.md -[smi_traffictarget]:https://github.com/servicemeshinterface/smi-spec/blob/v0.6.0/apis/traffic-access/v1alpha2/traffic-access.md#traffictarget -[smi_httproutegroup]:https://github.com/servicemeshinterface/smi-spec/blob/v0.6.0/apis/traffic-specs/v1alpha4/traffic-specs.md#httproutegroup -[smi_tcproute]:https://github.com/servicemeshinterface/smi-spec/blob/v0.6.0/apis/traffic-specs/v1alpha4/traffic-specs.md#tcproute -[smi_udproute]:https://github.com/servicemeshinterface/smi-spec/blob/v0.6.0/apis/traffic-specs/v1alpha4/traffic-specs.md#udproute -[nginx_annotations]:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations -[nginx_annotations_backend_protocol]:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol -[nginx_annotations_configuration_snippet]:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#configuration-snippet -[nginx_annotations_proxy_ssl_secret]:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-certificate-authentication -[nginx_annotations_proxy_ssl_verify]:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-certificate-authentication -[k8s_secret]:https://kubernetes.io/docs/concepts/configuration/secret -[k8s_serviceaccount]:https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer-ui-secure-ingress.yaml b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer-ui-secure-ingress.yaml deleted file mode 100644 index 4b7045e..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer-ui-secure-ingress.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: bookbuyer - namespace: bookbuyer - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / - nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" - # proxy_ssl_name for a service is of the form ..cluster.local - nginx.ingress.kubernetes.io/configuration-snippet: | - proxy_ssl_name "bookbuyer.bookbuyer.cluster.local"; - nginx.ingress.kubernetes.io/proxy-ssl-secret: "kube-system/osm-ingress-client-cert" - nginx.ingress.kubernetes.io/proxy-ssl-verify: "on" -spec: - ingressClassName: webapprouting.kubernetes.azure.com - rules: - - http: - paths: - - path: /bookbuyer - pathType: Prefix - backend: - service: - name: bookbuyer - port: - number: 14001 ---- -apiVersion: policy.openservicemesh.io/v1alpha1 -kind: IngressBackend -metadata: - name: bookbuyer - namespace: bookbuyer -spec: - backends: - - name: bookbuyer - port: - number: 14001 # targetPort of bookbuyer service - protocol: https - tls: - skipClientCertValidation: false - sources: - - kind: Service - namespace: app-routing-system - name: nginx - - kind: AuthenticatedPrincipal - name: ingress-nginx.ingress.cluster.local \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer.png b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookbuyer.png deleted file mode 100644 index d5850427f90b576b04d16f4d3f54c223421c87ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59642 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 diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookstore-ui-secure-ingress.yaml b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookstore-ui-secure-ingress.yaml deleted file mode 100644 index 7a6ac11..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookstore-ui-secure-ingress.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: bookstore - namespace: bookstore - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / - nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" - # proxy_ssl_name for a service is of the form ..cluster.local - nginx.ingress.kubernetes.io/configuration-snippet: | - proxy_ssl_name "bookstore.bookstore.cluster.local"; - nginx.ingress.kubernetes.io/proxy-ssl-secret: "kube-system/osm-ingress-client-cert" - nginx.ingress.kubernetes.io/proxy-ssl-verify: "on" -spec: - ingressClassName: webapprouting.kubernetes.azure.com - rules: - - http: - paths: - - path: /bookstore - pathType: Prefix - backend: - service: - name: bookstore - port: - number: 14001 ---- -apiVersion: policy.openservicemesh.io/v1alpha1 -kind: IngressBackend -metadata: - name: bookstore - namespace: bookstore -spec: - backends: - - name: bookstore - port: - number: 14001 # targetPort of bookstore service - protocol: https - tls: - skipClientCertValidation: false - sources: - - kind: Service - namespace: app-routing-system - name: nginx - - kind: AuthenticatedPrincipal - name: ingress-nginx.ingress.cluster.local \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookthief-ui-secure-ingress.yaml b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookthief-ui-secure-ingress.yaml deleted file mode 100644 index f7d97a4..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/bookthief-ui-secure-ingress.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: bookthief - namespace: bookthief - annotations: - nginx.ingress.kubernetes.io/rewrite-target: / - nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" - # proxy_ssl_name for a service is of the form ..cluster.local - nginx.ingress.kubernetes.io/configuration-snippet: | - proxy_ssl_name "bookthief.bookthief.cluster.local"; - nginx.ingress.kubernetes.io/proxy-ssl-secret: "kube-system/osm-ingress-client-cert" - nginx.ingress.kubernetes.io/proxy-ssl-verify: "on" -spec: - ingressClassName: webapprouting.kubernetes.azure.com - rules: - - http: - paths: - - path: /bookthief - pathType: Prefix - backend: - service: - name: bookthief - port: - number: 14001 ---- -apiVersion: policy.openservicemesh.io/v1alpha1 -kind: IngressBackend -metadata: - name: bookthief - namespace: bookthief -spec: - backends: - - name: bookthief - port: - number: 14001 # targetPort of bookthief service - protocol: https - tls: - skipClientCertValidation: false - sources: - - kind: Service - namespace: app-routing-system - name: nginx - - kind: AuthenticatedPrincipal - name: ingress-nginx.ingress.cluster.local \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookstore.yaml b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookstore.yaml deleted file mode 100644 index 74d1d99..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookstore.yaml +++ /dev/null @@ -1,39 +0,0 @@ -kind: TrafficTarget -apiVersion: access.smi-spec.io/v1alpha3 -metadata: - name: bookstore - namespace: bookstore -spec: - destination: - kind: ServiceAccount - name: bookstore - namespace: bookstore - rules: - - kind: HTTPRouteGroup - name: bookstore-service-routes - matches: - - buy-a-book - - books-bought - sources: - - kind: ServiceAccount - name: bookbuyer - namespace: bookbuyer ---- -apiVersion: specs.smi-spec.io/v1alpha4 -kind: HTTPRouteGroup -metadata: - name: bookstore-service-routes - namespace: bookstore -spec: - matches: - - name: books-bought - pathRegex: /books-bought - methods: - - GET - headers: - - "user-agent": ".*-http-client/*.*" - - "client-app": "bookbuyer" - - name: buy-a-book - pathRegex: ".*a-book.*new" - methods: - - GET diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookwarehouse.yaml b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookwarehouse.yaml deleted file mode 100644 index 20ddaba..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-bookwarehouse.yaml +++ /dev/null @@ -1,31 +0,0 @@ ---- -kind: TrafficTarget -apiVersion: access.smi-spec.io/v1alpha3 -metadata: - name: bookstore-access-bookwarehouse - namespace: bookwarehouse -spec: - destination: - kind: ServiceAccount - name: bookwarehouse - namespace: bookwarehouse - rules: - - kind: HTTPRouteGroup - name: bookwarehouse-service-routes - matches: - - restock-books - sources: - - kind: ServiceAccount - name: bookstore - namespace: bookstore ---- -apiVersion: specs.smi-spec.io/v1alpha4 -kind: HTTPRouteGroup -metadata: - name: bookwarehouse-service-routes - namespace: bookwarehouse -spec: - matches: - - name: restock-books - methods: - - POST \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-mysql.yaml b/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-mysql.yaml deleted file mode 100644 index 6996b3e..0000000 --- a/cloud-native/aks-open-service-mesh/03-applying-zero-trust/smi-traffic-to-mysql.yaml +++ /dev/null @@ -1,27 +0,0 @@ -kind: TrafficTarget -apiVersion: access.smi-spec.io/v1alpha3 -metadata: - name: mysql - namespace: bookwarehouse -spec: - destination: - kind: ServiceAccount - name: mysql - namespace: bookwarehouse - rules: - - kind: TCPRoute - name: mysql - sources: - - kind: ServiceAccount - name: bookwarehouse - namespace: bookwarehouse ---- -apiVersion: specs.smi-spec.io/v1alpha4 -kind: TCPRoute -metadata: - name: mysql - namespace: bookwarehouse -spec: - matches: - ports: - - 3306 diff --git a/cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/README.md b/cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/README.md deleted file mode 100644 index cc6921d..0000000 --- a/cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/README.md +++ /dev/null @@ -1,134 +0,0 @@ -# Part 4: Traffic splitting with OSM - -Another core component of OSM is [traffic splitting][osm_traffic_splitting] which allows you to implement a/b testing, blue-green deployment, or canary deployment practices. - -Please ensure you have completed the steps in [Part 3: Applying Zero-Trust to the Bookstore application](../03-applying-zero-trust/README.md) before you proceed. - -Make sure you are in the right working directory (this command assumes you are currently in the `cloud-native/aks-open-service-mesh/03-applying-zero-trust/` directory).: - -```bash -cd ../04-osm-traffic-splitting -``` - -Deploy a new version of bookstore (`bookstore-v2`). - -```bash -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/apps/bookstore-v2.yaml -``` - -Inspect the resources within `bookstore` namespace to see what is new. - -```bash -kubectl get all -n bookstore -``` - -You should see output similar to the following: - -```text -NAME READY STATUS RESTARTS AGE -pod/bookstore-97956675d-dfrlq 2/2 Running 0 84m -pod/bookstore-v2-6ccc9b8746-cqxn6 2/2 Running 0 45s - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -service/bookstore ClusterIP 10.0.132.170 14001/TCP 84m -service/bookstore-v1 ClusterIP 10.0.181.65 14001/TCP 84m -service/bookstore-v2 ClusterIP 10.0.117.98 14001/TCP 46s - -NAME READY UP-TO-DATE AVAILABLE AGE -deployment.apps/bookstore 1/1 1 1 84m -deployment.apps/bookstore-v2 1/1 1 1 45s - -NAME DESIRED CURRENT READY AGE -replicaset.apps/bookstore-97956675d 1 1 1 84m -replicaset.apps/bookstore-v2-6ccc9b8746 1 1 1 45s -``` - -With the new version of `bookstore` running, we can use the `TrafficSplit` CRD to split traffic evenly between `bookstore-v1` and `bookstore-v2` backend services. - -```yml -apiVersion: split.smi-spec.io/v1alpha2 -kind: TrafficSplit -metadata: - name: bookstore-split - namespace: bookstore -spec: - service: bookstore.bookstore # . - backends: - - service: bookstore-v1 # matches app:bookstore,version:v1 - weight: 50 - - service: bookstore-v2 # matches app:bookstore,version:v2 - weight: 50 -``` - -Run the following command to evenly split the traffic. - -```bash -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/split/traffic-split-50-50.yaml -``` - -If you take a look at our **bookbuyer** web page again, you will see both versions of the **bookstore** are selling books. - -> If you do not have the **bookbuyer** app, run the following commands to retrieve the URL and open in a web browser - -```bash -nginx_ingress_host="$(kubectl -n app-routing-system get service nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" - -# these are the urls you should open in your browser -echo http://$nginx_ingress_host/bookbuyer -echo http://$nginx_ingress_host/bookthief -echo http://$nginx_ingress_host/bookstore -``` - -![bookstore split](./bookstore-split.png) - -After some testing you are now ready to cutover all traffic from v1 to v2. Run the following command up distribute 100% of the traffic to v2. - -```bash -kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.2/manifests/split/traffic-split-v2.yaml -``` - -If you take a look at our **bookbuyer** web page again, we can see only **bookstore-v2** is selling books. - -With **bookstore-v1** no longer taking any requests, lets redeploy the `service`, `ingress`, and `ingressbackend` and point them all to **bookstore-v2**. - -```bash -kubectl apply -f bookstore-ui-v2.yaml -``` - -Navigate back to the **bookstore** app in your web browser and you will now see `bookstore-v2` with an incrementing counter. - -> You might need to refresh the **bookstore** app. - -![bookstore-v2](./bookstore-v2.png) - -## Wrap up and next steps - -In this multi-part lab, we deployed an AKS cluster using Bicep and enabled the Web Application Routing and Open Service Mesh add-ons. These open-source components can be installed in your cluster manually; however, when you enable them as add-ons, they are managed by the Azure platform and are fully supported. - -There's more to OSM than what we explored in this lab. We only controlled traffic from an ingress perspective but with OSM, you can also control [egress traffic][osm_egress]. You can also implement patterns and practices to help with application resiliency using techniques like [rate limiting][osm_rate_limiting], [retry][osm_retry], and [circuit breakers][osm_circuit_breaker]. I encourage you to visit the links in the resources section below to learn and implement more. - -Once you have finished exploring, you should delete the deployment to avoid any further charges. - -```bash -az group delete --name rg-${name} --yes -``` - -If you found this lab helpful, please give the repo a ⭐️ or let us know your questions or feedback by filing a [new issue](https://github.com/Azure-Samples/azure-opensource-labs/issues/new), or joining the Discord in the [README](https://github.com/Azure-Samples/azure-opensource-labs#azure-open-source-labs). - -Cheers! - -## Resources - -* [Traffic Splitting][osm_traffic_splitting] -* [Canary Rollouts using SMI Traffic Split][osm_canary_rollouts] -* [Rate Limiting][osm_rate_limiting] -* [Retry][osm_retry] -* [Circuit Breaking][osm_circuit_breaker] - - -[osm_traffic_splitting]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/traffic_split -[osm_canary_rollouts]:https://release-v1-2.docs.openservicemesh.io/docs/demos/canary_rollout -[osm_egress]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/egress/ -[osm_circuit_breaker]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/circuit_breaking/ -[osm_retry]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/retry_policy/ -[osm_rate_limiting]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/rate_limiting/ \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/bookstore-split.png b/cloud-native/aks-open-service-mesh/04-osm-traffic-splitting/bookstore-split.png deleted file mode 100644 index 16ed14d6c7eb7ef00e8b9caa6453031ea7e0d71b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57825 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

qCTzHBsr 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 z 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 z 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 b%3?RlzMGr2Q0ub~_|bk~aKG&ClUM%_R3?&C diff --git a/cloud-native/aks-webapp-routing/bicepconfig.json b/cloud-native/aks-webapp-routing/bicepconfig.json deleted file mode 100644 index 91b4f8a..0000000 --- a/cloud-native/aks-webapp-routing/bicepconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "moduleAliases": { - "ts": {}, - "br": { - "oss-labs": { - "registry": "cloudnativeadvocates.azurecr.io" - } - } - } -} \ No newline at end of file diff --git a/cloud-native/aks-webapp-routing/deployment.yaml b/cloud-native/aks-webapp-routing/deployment.yaml deleted file mode 100644 index 40dc78c..0000000 --- a/cloud-native/aks-webapp-routing/deployment.yaml +++ /dev/null @@ -1,117 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-vote-back -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: redis:latest - env: - - name: ALLOW_EMPTY_PASSWORD - value: "yes" - ports: - - containerPort: 6379 - name: redis ---- -apiVersion: v1 -kind: Service -metadata: - name: azure-vote-back -spec: - ports: - - port: 6379 - selector: - app: azure-vote-back ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: azure-vote-front -spec: - replicas: 1 - selector: - matchLabels: - app: azure-vote-front - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - minReadySeconds: 5 - template: - metadata: - labels: - app: azure-vote-front - spec: - nodeSelector: - "kubernetes.io/os": linux - containers: - - name: azure-vote-front - image: cloudnativeadvocates.azurecr.io/azure-vote-front:v1.0.0 - ports: - - containerPort: 80 - resources: - requests: - cpu: 250m - limits: - cpu: 500m - env: - - name: REDIS - value: "azure-vote-back" ---- -apiVersion: v1 -kind: Service -metadata: - name: azure-vote-front -spec: - ports: - - port: 80 - selector: - app: azure-vote-front ---- -apiVersion: autoscaling/v1 -kind: HorizontalPodAutoscaler -metadata: - name: azure-vote-front -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: azure-vote-front - minReplicas: 1 - maxReplicas: 50 - targetCPUUtilizationPercentage: 50 ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.azure.com/tls-cert-keyvault-uri: - name: azure-vote-front -spec: - ingressClassName: webapprouting.kubernetes.azure.com - rules: - - host: - http: - paths: - - backend: - service: - name: azure-vote-front - port: - number: 80 - path: / - pathType: Prefix - tls: - - hosts: - - - secretName: keyvault-azure-vote \ No newline at end of file diff --git a/cloud-native/aks-webapp-routing/hello-deployment-2.yaml b/cloud-native/aks-webapp-routing/hello-deployment-2.yaml deleted file mode 100644 index 565d184..0000000 --- a/cloud-native/aks-webapp-routing/hello-deployment-2.yaml +++ /dev/null @@ -1,65 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: hello-web-app-routing ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: aks-helloworld-2 - namespace: hello-web-app-routing -spec: - replicas: 1 - selector: - matchLabels: - app: aks-helloworld-2 - template: - metadata: - labels: - app: aks-helloworld-2 - spec: - containers: - - name: aks-helloworld-2 - image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 - ports: - - containerPort: 80 - env: - - name: TITLE - value: "Welcome again to Azure Kubernetes Service (AKS) with Web Application Routing!" ---- -apiVersion: v1 -kind: Service -metadata: - name: aks-helloworld-2 - namespace: hello-web-app-routing -spec: - type: ClusterIP - ports: - - port: 80 - selector: - app: aks-helloworld-2 ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - annotations: - kubernetes.azure.com/tls-cert-keyvault-uri: https://akv-books24543.vault.azure.net/certificates/hello-2/0ccf1df2eb384153a074ce6dcbe8e3a2 - name: aks-helloworld-2 - namespace: hello-web-app-routing -spec: - ingressClassName: webapprouting.kubernetes.azure.com - rules: - - host: hello2.contoso.work - http: - paths: - - backend: - service: - name: aks-helloworld-2 - port: - number: 80 - path: / - pathType: Prefix - tls: - - hosts: - - hello2.contoso.work - secretName: keyvault-aks-helloworld-2 \ No newline at end of file diff --git a/cloud-native/aks-webapp-routing/hello-deployment-validation.png b/cloud-native/aks-webapp-routing/hello-deployment-validation.png deleted file mode 100644 index 8b46b5a05d13952c82734657898b4fddeaefa153..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41039 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 diff --git a/cloud-native/aks-webapp-routing/hello-deployment.png b/cloud-native/aks-webapp-routing/hello-deployment.png deleted file mode 100644 index dc886543e421d8970b95f4e2cf212aa8d266364b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198400 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 Use the button above if you'd like to deploy using the Azure Portal instead of Azure CLI commands. - -Clone this repo and drop into the `aks-open-service-mesh` directory. - -```bash -git clone https://github.com/Azure-Samples/azure-opensource-labs.git -cd azure-opensource-labs/cloud-native/aks-open-service-mesh -``` - -Before you proceed, ensure you have the `Microsoft.ContainerService` and `Microsoft.Insights` providers registered. - -```bash -az provider register --namespace Microsoft.ContainerService -az provider register --namespace Microsoft.Insights -``` - -Open a terminal and initialize the following variables which will be passed into the deployment. - -```bash -# azure region where resources will be deployed to -location=eastus -# random name that will be used for azure resources -name=books$RANDOM -# get the latest (n-1) version of kubernetes -kubernetesVersion=$(az aks get-versions -l $location --out tsv --query 'orchestrators[-1].orchestratorVersion') -# kubernetes node count -systemNodeCount=3 -# azure vm size for nodes -systemNodeSize=Standard_D4s_v5 -# get your user name -userName=$(az account show --out tsv --query user.name) -# get your user principal id -userObjectId=$(az ad user show --id $userName --out tsv --query id) -``` - -Deploy Azure infrastructure with the Bicep template. - -> Take a look at this [blog post](https://dev.to/azure/sharing-bicep-modules-with-azure-container-registry-4mo0) to see how the Bicep modules are put together. - -```bash -az deployment sub create \ - --name "$name-deploy" \ - --location $location \ - --template-file main.bicep \ - --parameters \ - name=$name \ - location=$location \ - kubernetesVersion=$kubernetesVersion \ - systemNodeCount=$systemNodeCount \ - systemNodeSize=$systemNodeSize \ - userObjectId=$userObjectId -``` - -The template will deploy the following resources into your subscription: - -* [Azure Resource Group][rg] to deploy resources into -* [Azure Log Analytics Workspace][law] to serve as a data store for the monitoring add-on -* [Azure Kubernetes Service][aks] your managed Kubernetes cluster with [`kubenet`][kubenet] as the container network plugin, [`calico`][calico] for network policy, and the following [AKS add-ons][aks_addons] - * [`azure-keyvault-secrets-provider`](https://learn.microsoft.com/azure/aks/csi-secrets-store-driver) - * [`monitoring`](https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-overview) - * [`open-service-mesh`](https://learn.microsoft.com/azure/aks/open-service-mesh-about) - * [`web_application_routing`](https://learn.microsoft.com/azure/aks/web-app-routing?tabs=with-osm) - -## Validate the Azure deployment - -View a list of resources deployed in your resource group by running the following command or view from the [Azure Portal](https://portal.azure.com): - -```bash -az resource list \ - --resource-group rg-${name} \ - --out table -``` - -To view the AKS add-ons that have been installed and its configurations, run the command below: - -```bash -az aks show \ - --resource-group rg-${name} \ - --name aks-${name} \ - --query "addonProfiles" -``` - -## Validate access to the Kubernetes cluster - -Before you pull down credentials from AKS make sure you have `kubectl` CLI locally. - -> If you do not have `kubectl` installed yet, run the `az aks install-cli` to install it using Azure CLI. - -Authenticate `kubectl` against the AKS cluster. - -```bash -az aks get-credentials \ - --resource-group rg-${name} \ - --name aks-${name} -``` - -Verify you have access to the cluster. - -```bash -kubectl cluster-info -``` - -## Validate OSM resources and configurations - -Now let's check the OSM add-on is enabled by running the following command and ensure `openServiceMesh` has the `enabled` property set to `true`. - -```bash -az aks show \ - --resource-group rg-${name} \ - --name aks-${name} \ - --query "addonProfiles.openServiceMesh" -``` - -Next, run the following command to check the OSM resources have been deployed into your cluster successfully. - -```bash -kubectl api-resources | grep openservicemesh -``` - -You should see output similar to the following: - -```text -meshconfigs meshconfig config.openservicemesh.io/v1alpha2 true MeshConfig -meshrootcertificates mrc config.openservicemesh.io/v1alpha2 true MeshRootCertificate -egresses egress policy.openservicemesh.io/v1alpha1 true Egress -ingressbackends ingressbackend policy.openservicemesh.io/v1alpha1 true IngressBackend -retries retry policy.openservicemesh.io/v1alpha1 true Retry -upstreamtrafficsettings upstreamtrafficsetting policy.openservicemesh.io/v1alpha1 true UpstreamTrafficSetting -``` - -OSM installs several new [Custom Resource Definitions (CRDs)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) as part of its implementation. - -Let's view OSM deployments by querying for deployments that start with `osm`. - -```bash -kubectl get deploy -A | grep osm -``` - -You should see output similar to this: - -```text -kube-system osm-bootstrap 1/1 1 1 132m -kube-system osm-controller 2/2 2 2 132m -kube-system osm-injector 2/2 2 2 132m -``` - -Here is a high-level overview of the [OSM components][osm] that are installed: - -* `osm-bootstrap` runs on a single node and is responsible for installing itself in the cluster and installing CRDs -* `osm-controller` runs on all nodes and is the control plane of the service mesh -* `osm-injecter` runs on all nodes and is responsible for injecting data plane components (i.e., Envoy proxy sidecars) into application pods - -These resources are typically [installed manually using the OSM CLI command `osm install`](https://release-v1-2.docs.openservicemesh.io/docs/getting_started/setup_osm/#installing-osm-on-kubernetes). However, with the AKS add-on, the installation and configuration is done for you. When OSM is deployed with the Web Application Routing add-on, Azure automatically adds additional configuration to allow NGINX and OSM to work together. - -> With open-source OSM, you have an option on the namespace where `osm` is installed (normally in the `osm-system` namespace), but since this is managed by AKS, it has been installed in the `kube-system` namespace for you. - -To view the default configuration for OSM, you can run the following command. - -```bash -kubectl get meshconfig osm-mesh-config -n kube-system -o yaml -``` - -Pay special attention to the `traffic` configuration; a snippet has been included below. - -```text -... -traffic: - enableEgress: true - enablePermissiveTrafficPolicyMode: true - inboundExternalAuthorization: - enable: false - failureModeAllow: false - statPrefix: inboundExtAuthz - timeout: 1s -... -``` - -The `enablePermissiveTrafficPolicyMode` has been set to `true`. This is the default configuration and when set to `true`, pods enrolled in the service mesh communicate freely. For more info on this see: [Permissive Traffic Policy Mode][osm_permissive_traffic_policy] - -### Namespaces are vital to OSM - -Applications are added to OSM based on namespaces. By binding to [Kubernetes namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/), the OSM controller labels and annotates these resources so that it can discover and manage data plane components of the mesh. - -Run this command to view the services meshes deployed withing OSM. - -```bash -osm mesh list -``` - -You should see output similar to the following: - -```text -MESH NAME MESH NAMESPACE VERSION ADDED NAMESPACES -osm kube-system v1.2.1 app-routing-system - -MESH NAME MESH NAMESPACE SMI SUPPORTED -osm kube-system HTTPRouteGroup:v1alpha4,TCPRoute:v1alpha4,TrafficSplit:v1alpha2,TrafficTarget:v1alpha3 - -To list the OSM controller pods for a mesh, please run the following command passing in the mesh's namespace - kubectl get pods -n -l app=osm-controller -``` - -> Note the Service Mesh Interface (SMI) specs that are supported by OSM. These may be subject to change with the ongoing dialog on the [GAMMA Initiative](https://gateway-api.sigs.k8s.io/contributing/gamma/) within the community. - -As suggested in the output above, let's get a list of OSM controller pods. - -```bash -kubectl get pods -n kube-system -l app=osm-controller -``` - -Run this command to view the namespaces OSM is currently monitoring: - -```bash -osm namespace list -``` - -You should see output similar to the following: - -```text -NAMESPACE MESH SIDECAR-INJECTION -app-routing-system osm disabled -``` - -As mentioned above, you have added both the `web_application_routing` and `open-service-mesh` add-ons and Azure has automatically configured OSM to monitor the NGINX ingress controller's namespace 🎉 - -One important thing to note in the output above is that `SIDECAR-INJECTION` has been set to `disabled`. OSM integration with NGINX requires monitoring of the ingress controller's namespace for service discovery and management of ingress endpoints to backend services. However, OSM should not inject sidecars into the NGINX pods to function properly. - -Now, let's inspect the namespace labels added by OSM. - -```bash -kubectl get namespace --show-labels | grep openservicemesh.io/monitored-by=osm -``` - -## Next steps - -You have successfully deployed the AKS cluster and inspected how the Web Application Routing and OSM add-ons are deployed and configured in the cluster. The cluster is now ready for application deployments. - -Head over to [Part 2: Bookstore application deployment](./02-deploying-bookstore-app/README.md) to deploy our first app. - -## Resources - -* [AKS Add-On: Web Application Routing (Preview)][aks_addon_web_app_routing] -* [AKS Add-On: Open Service Mesh][aks_addon_osm] - - -[aks_addons]:https://learn.microsoft.com/azure/aks/integrations#available-add-ons -[aks_addon_osm]:https://learn.microsoft.com/azure/aks/open-service-mesh-about -[aks_addon_web_app_routing]:https://learn.microsoft.com/azure/aks/web-app-routing?tabs=with-osm -[osm]:https://release-v1-2.docs.openservicemesh.io/docs/overview/about/ -[osm_bookstore_sample]:https://release-v1-2.docs.openservicemesh.io/docs/getting_started/install_apps/ -[osm_permissive_traffic_policy]:https://release-v1-2.docs.openservicemesh.io/docs/guides/traffic_management/permissive_mode/ -[kubenet]:https://learn.microsoft.com/azure/aks/configure-kubenet -[calico]:https://projectcalico.docs.tigera.io/security/kubernetes-policy -[rg]:https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal#what-is-a-resource-group -[law]:https://learn.microsoft.com/azure/azure-monitor/logs/log-analytics-workspace-overview -[aks]:https://learn.microsoft.com/azure/aks/intro-kubernetes diff --git a/cloud-native/aks-open-service-mesh/bicepconfig.json b/cloud-native/aks-open-service-mesh/bicepconfig.json deleted file mode 100644 index 91b4f8a..0000000 --- a/cloud-native/aks-open-service-mesh/bicepconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "moduleAliases": { - "ts": {}, - "br": { - "oss-labs": { - "registry": "cloudnativeadvocates.azurecr.io" - } - } - } -} \ No newline at end of file diff --git a/cloud-native/aks-open-service-mesh/main.bicep b/cloud-native/aks-open-service-mesh/main.bicep deleted file mode 100644 index cbb3f5c..0000000 --- a/cloud-native/aks-open-service-mesh/main.bicep +++ /dev/null @@ -1,142 +0,0 @@ -targetScope = 'subscription' - -param name string -param location string -param tags object = {} - -param kubernetesVersion string = '1.29' -param systemNodeCount int = 3 -param systemNodeSize string = 'Standard_D4s_v5' - -param userObjectId string -// param dnsName string - -var networkPlugin = 'kubenet' -var networkPolicy = 'calico' - -// Set up the resource group -resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { - name: 'rg-${name}' - location: location - tags: tags -} - -module kv '../../bicep/modules/azure-key-vault/main.bicep' = { - scope: rg - name: 'akvDeploy' - params: { - location: location - name: 'akv-${name}' - sku: 'standard' - tags: tags - userObjectId: userObjectId - tenantId: tenant().tenantId - } -} - -// Setup the log analytics workspace -module law '../../bicep/modules/azure-log-analytics-workspace/main.bicep' = { - scope: rg - name: 'lawDeploy' - params: { - name: 'law-${name}' - location: location - tags: tags - } -} - -// Setup the Kubernetes cluster -module aks '../../bicep/modules/azure-kubernetes-service/main.bicep' = { - scope: rg - name: 'aksDeploy' - params: { - name: 'aks-${name}' - location: location - tags: tags - slaTier: 'Free' - managedIdentityType: 'SystemAssigned' - kubernetesVersion: kubernetesVersion - networkPlugin: networkPlugin - networkPolicy: networkPolicy - loadBalancerSku: 'Standard' - outboundType: 'loadBalancer' - dnsServiceIP: '10.0.0.10' - podCidrs: [ - '10.244.0.0/16' - ] - serviceCidrs: [ - '10.0.0.0/16' - ] - ipFamilies: [ - 'IPv4' - ] - defenderEnabled: false - imageCleanerEnabled: false - systemNodeCount: systemNodeCount - systemNodeVmSize: systemNodeSize - // registryName: acr.outputs.name - addonProfiles: { - omsagent: { - config: { - logAnalyticsWorkspaceResourceID: law.outputs.id - } - enabled: true - } - } - } -} - -// Deploy the key vault secrets provider add-on -module aksAddonKv '../../bicep/modules/azure-kubernetes-service-addons/main.bicep' = { - scope: rg - name: 'aksAddonKvDeploy' - params: { - location: location - clusterId: aks.outputs.id - addonProfiles: { - azureKeyvaultSecretsProvider: { - config: { - enableSecretRotation: 'true' - rotationPollInterval: '2m' - } - enabled: true - } - } - } - dependsOn: [ - aks - kv - ] -} - -// Deploy the web app routing add-on -module aksAddonIng '../../bicep/modules/azure-kubernetes-service-ingress/main.bicep' = { - scope: rg - name: 'aksAddonIngDeploy' - params: { - location: location - clusterId: aks.outputs.id - } - dependsOn: [ - aksAddonKv - ] -} - -// Deploy the open service mesh add-on -module aksAddonOsm '../../bicep/modules/azure-kubernetes-service-addons/main.bicep' = { - scope: rg - name: 'aksAddonOsmDeploy' - params: { - location: location - clusterId: aks.outputs.id - addonProfiles: { - openServiceMesh: { - config: {} - enabled: true - } - } - } - dependsOn: [ - aksAddonIng - ] -} diff --git a/cloud-native/aks-open-service-mesh/main.json b/cloud-native/aks-open-service-mesh/main.json deleted file mode 100644 index d27dc41..0000000 --- a/cloud-native/aks-open-service-mesh/main.json +++ /dev/null @@ -1,874 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "10734555654774304097" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object", - "defaultValue": {} - }, - "kubernetesVersion": { - "type": "string", - "defaultValue": "1.29" - }, - "systemNodeCount": { - "type": "int", - "defaultValue": 3 - }, - "systemNodeSize": { - "type": "string", - "defaultValue": "Standard_D4s_v5" - }, - "userObjectId": { - "type": "string" - } - }, - "variables": { - "networkPlugin": "kubenet", - "networkPolicy": "calico" - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2021-04-01", - "name": "[format('rg-{0}', parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]" - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "akvDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "name": { - "value": "[format('akv-{0}', parameters('name'))]" - }, - "sku": { - "value": "standard" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "userObjectId": { - "value": "[parameters('userObjectId')]" - }, - "tenantId": { - "value": "[tenant().tenantId]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "6723983789050081110" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "sku": { - "type": "string", - "defaultValue": "standard", - "allowedValues": [ - "premium", - "standard" - ] - }, - "userObjectId": { - "type": "string", - "metadata": { - "description": "The object ID of a user, service principal or security group in AAD tenant." - } - }, - "tenantId": { - "type": "string" - }, - "accessPolicies": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "List of AccessPolicyEntry which is used when granting additional permissions for other users or managed identities" - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2022-07-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "accessPolicies": [ - { - "objectId": "[parameters('userObjectId')]", - "permissions": { - "certificates": [ - "all" - ], - "keys": [ - "all" - ], - "secrets": [ - "all" - ], - "storage": [ - "all" - ] - }, - "tenantId": "[parameters('tenantId')]" - } - ], - "sku": { - "family": "A", - "name": "[parameters('sku')]" - }, - "tenantId": "[parameters('tenantId')]" - } - }, - { - "condition": "[not(empty(parameters('accessPolicies')))]", - "type": "Microsoft.KeyVault/vaults/accessPolicies", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('name'), 'add')]", - "properties": { - "accessPolicies": "[parameters('accessPolicies')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', parameters('name'))]" - ] - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "lawDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('law-{0}', parameters('name'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "4630854867665059244" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2021-12-01-preview", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "retentionInDays": 30, - "sku": { - "name": "PerGB2018" - } - } - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('name'))]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "aksDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('aks-{0}', parameters('name'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "slaTier": { - "value": "Free" - }, - "managedIdentityType": { - "value": "SystemAssigned" - }, - "kubernetesVersion": { - "value": "[parameters('kubernetesVersion')]" - }, - "networkPlugin": { - "value": "[variables('networkPlugin')]" - }, - "networkPolicy": { - "value": "[variables('networkPolicy')]" - }, - "loadBalancerSku": { - "value": "Standard" - }, - "outboundType": { - "value": "loadBalancer" - }, - "dnsServiceIP": { - "value": "10.0.0.10" - }, - "podCidrs": { - "value": [ - "10.244.0.0/16" - ] - }, - "serviceCidrs": { - "value": [ - "10.0.0.0/16" - ] - }, - "ipFamilies": { - "value": [ - "IPv4" - ] - }, - "defenderEnabled": { - "value": false - }, - "imageCleanerEnabled": { - "value": false - }, - "systemNodeCount": { - "value": "[parameters('systemNodeCount')]" - }, - "systemNodeVmSize": { - "value": "[parameters('systemNodeSize')]" - }, - "addonProfiles": { - "value": { - "omsagent": { - "config": { - "logAnalyticsWorkspaceResourceID": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'lawDeploy'), '2022-09-01').outputs.id.value]" - }, - "enabled": true - } - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "5599997474738078815" - } - }, - "parameters": { - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "slaTier": { - "type": "string", - "defaultValue": "Free", - "allowedValues": [ - "Free", - "Paid" - ], - "metadata": { - "description": "Defaults to Free tier" - } - }, - "managedIdentityType": { - "type": "string", - "defaultValue": "SystemAssigned", - "allowedValues": [ - "SystemAssigned", - "UserAssigned" - ], - "metadata": { - "description": "Two options are available: SystemAssigned or UserAssigned" - } - }, - "userAssignedIdentities": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Required when managed identity type is set to UserAssigned" - } - }, - "kubernetesVersion": { - "type": "string", - "defaultValue": "1.29", - "metadata": { - "description": "Default is 1.29" - } - }, - "defenderEnabled": { - "type": "bool", - "defaultValue": false - }, - "imageCleanerEnabled": { - "type": "bool", - "defaultValue": false - }, - "imageCleanerIntervalHours": { - "type": "int", - "defaultValue": 12 - }, - "systemNodeCount": { - "type": "int", - "defaultValue": 3 - }, - "systemNodeVmSize": { - "type": "string", - "defaultValue": "Standard_D2s_v5", - "metadata": { - "description": "Default system node pool size is Standard_D2s_v5" - } - }, - "registryName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional parameter to attach AKS cluster to an existing ACR" - } - }, - "networkPlugin": { - "type": "string", - "defaultValue": "kubenet", - "allowedValues": [ - "kubenet", - "azure", - "none" - ], - "metadata": { - "description": "Network plugin used for building the Kubernetes network." - } - }, - "networkPolicy": { - "type": "string", - "defaultValue": "calico", - "allowedValues": [ - "calico", - "azure" - ], - "metadata": { - "description": "Network policy used for building the Kubernetes network." - } - }, - "loadBalancerSku": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Standard", - "Basic" - ], - "metadata": { - "description": "The default is standard." - } - }, - "dnsServiceIP": { - "type": "string", - "defaultValue": "10.0.0.10", - "metadata": { - "description": "An IP address assigned to the Kubernetes DNS service. It must be within the Kubernetes service address range specified in serviceCidr." - } - }, - "dockerBridgeCidr": { - "type": "string", - "defaultValue": "172.17.0.1/16", - "metadata": { - "description": "A CIDR notation IP range assigned to the Docker bridge network. It must not overlap with any Subnet IP ranges or the Kubernetes service address range." - } - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Resource ID of log analytics workspace for auditing" - } - }, - "outboundType": { - "type": "string", - "defaultValue": "loadBalancer", - "allowedValues": [ - "loadBalancer", - "managedNATGateway", - "userAssignedNATGateway", - "userDefinedRouting" - ], - "metadata": { - "description": "This can only be set at cluster creation time and cannot be changed later." - } - }, - "podCidrs": { - "type": "array", - "defaultValue": [ - "10.244.0.0/16" - ], - "metadata": { - "description": "One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking." - } - }, - "serviceCidrs": { - "type": "array", - "defaultValue": [ - "10.0.0.0/16" - ], - "metadata": { - "description": "One IPv4 CIDR is expected for single-stack networking. Two CIDRs, one for each IP family (IPv4/IPv6), is expected for dual-stack networking. They must not overlap with any Subnet IP ranges." - } - }, - "ipFamilies": { - "type": "array", - "defaultValue": [ - "IPv4" - ], - "allowedValues": [ - "IPv4", - "IPv6" - ] - }, - "vnetSubnetID": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "If the cluster is using azure network plugin, then you can pass in the subnet resource ID like this `vnet.outputs.subnetId`; otherwise, leave it empty" - } - }, - "nodeTaints": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Enable nodeTaints on the system node pool (e.g., ['CriticalAddonsOnly=true:NoSchedule'])" - } - }, - "addonProfiles": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "AKS addons to enable" - } - }, - "enablePrometheusMetrics": { - "type": "bool", - "defaultValue": false - }, - "prometheusMetricLabelsAllowlist": { - "type": "string", - "defaultValue": "" - }, - "prometheusMetricAnnotationsAllowList": { - "type": "string", - "defaultValue": "" - } - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2022-08-03-preview", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "Basic", - "tier": "[parameters('slaTier')]" - }, - "identity": { - "type": "[parameters('managedIdentityType')]", - "userAssignedIdentities": "[if(equals(parameters('managedIdentityType'), 'UserAssigned'), parameters('userAssignedIdentities'), null())]" - }, - "properties": { - "kubernetesVersion": "[parameters('kubernetesVersion')]", - "dnsPrefix": "[parameters('name')]", - "azureMonitorProfile": "[if(parameters('enablePrometheusMetrics'), createObject('metrics', createObject('enabled', true(), 'kubeStateMetrics', createObject('metricLabelsAllowlist', parameters('prometheusMetricLabelsAllowlist'), 'metricAnnotationsAllowList', parameters('prometheusMetricAnnotationsAllowList')))), null())]", - "networkProfile": { - "networkPlugin": "[parameters('networkPlugin')]", - "networkPolicy": "[parameters('networkPolicy')]", - "loadBalancerSku": "[parameters('loadBalancerSku')]", - "dnsServiceIP": "[parameters('dnsServiceIP')]", - "dockerBridgeCidr": "[parameters('dockerBridgeCidr')]", - "outboundType": "[parameters('outboundType')]", - "podCidrs": "[parameters('podCidrs')]", - "serviceCidrs": "[parameters('serviceCidrs')]", - "ipFamilies": "[parameters('ipFamilies')]" - }, - "agentPoolProfiles": [ - { - "name": "system", - "count": "[parameters('systemNodeCount')]", - "vmSize": "[parameters('systemNodeVmSize')]", - "mode": "System", - "vnetSubnetID": "[if(empty(parameters('vnetSubnetID')), null(), parameters('vnetSubnetID'))]", - "nodeTaints": "[if(empty(parameters('nodeTaints')), null(), parameters('nodeTaints'))]" - } - ], - "securityProfile": { - "defender": { - "securityMonitoring": { - "enabled": "[parameters('defenderEnabled')]" - } - }, - "imageCleaner": { - "enabled": "[parameters('imageCleanerEnabled')]", - "intervalHours": "[parameters('imageCleanerIntervalHours')]" - } - }, - "addonProfiles": "[parameters('addonProfiles')]" - } - }, - { - "condition": "[not(equals(parameters('registryName'), ''))]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('registryName'))]", - "name": "[guid(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), parameters('registryName'))]", - "properties": { - "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview').identityProfile.kubeletidentity.objectId]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), resourceGroup().id)]", - "properties": { - "principalId": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview', 'full').identity.principalId]", - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" - ] - } - ], - "outputs": { - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "id": { - "type": "string", - "value": "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" - }, - "kubeletIdentityObjectId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview').identityProfile.kubeletidentity.objectId]" - }, - "nodeResourceGroupName": { - "type": "string", - "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), '2022-08-03-preview').nodeResourceGroup]" - } - } - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'lawDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "aksAddonKvDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "clusterId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy'), '2022-09-01').outputs.id.value]" - }, - "addonProfiles": { - "value": { - "azureKeyvaultSecretsProvider": { - "config": { - "enableSecretRotation": "true", - "rotationPollInterval": "2m" - }, - "enabled": true - } - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "15950648950143392136" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "clusterId": { - "type": "string" - }, - "addonProfiles": { - "type": "object", - "metadata": { - "description": "AKS addons to enable" - } - } - }, - "variables": { - "clusterName": "[split(parameters('clusterId'), '/')[8]]" - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2022-08-03-preview", - "name": "[variables('clusterName')]", - "location": "[parameters('location')]", - "properties": { - "mode": "Incremental", - "id": "[parameters('clusterId')]", - "addonProfiles": "[parameters('addonProfiles')]" - } - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy')]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'akvDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "aksAddonIngDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "clusterId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy'), '2022-09-01').outputs.id.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "2186650111419086884" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "clusterId": { - "type": "string" - }, - "dnsZoneResourceId": { - "type": "string", - "defaultValue": "" - } - }, - "variables": { - "clusterName": "[split(parameters('clusterId'), '/')[8]]", - "attachDnsZone": "[not(equals(parameters('dnsZoneResourceId'), ''))]" - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2022-08-03-preview", - "name": "[variables('clusterName')]", - "location": "[parameters('location')]", - "properties": { - "mode": "Incremental", - "id": "[parameters('clusterId')]", - "ingressProfile": { - "webAppRouting": { - "dnsZoneResourceId": "[if(variables('attachDnsZone'), parameters('dnsZoneResourceId'), null())]", - "enabled": true - } - } - } - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy')]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksAddonKvDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "aksAddonOsmDeploy", - "resourceGroup": "[format('rg-{0}', parameters('name'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "clusterId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy'), '2022-09-01').outputs.id.value]" - }, - "addonProfiles": { - "value": { - "openServiceMesh": { - "config": {}, - "enabled": true - } - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "15950648950143392136" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "clusterId": { - "type": "string" - }, - "addonProfiles": { - "type": "object", - "metadata": { - "description": "AKS addons to enable" - } - } - }, - "variables": { - "clusterName": "[split(parameters('clusterId'), '/')[8]]" - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2022-08-03-preview", - "name": "[variables('clusterName')]", - "location": "[parameters('location')]", - "properties": { - "mode": "Incremental", - "id": "[parameters('clusterId')]", - "addonProfiles": "[parameters('addonProfiles')]" - } - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksDeploy')]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, format('rg-{0}', parameters('name'))), 'Microsoft.Resources/deployments', 'aksAddonIngDeploy')]", - "[subscriptionResourceId('Microsoft.Resources/resourceGroups', format('rg-{0}', parameters('name')))]" - ] - } - ] -} \ No newline at end of file diff --git a/cloud-native/aks-webapp-routing/README.md b/cloud-native/aks-webapp-routing/README.md deleted file mode 100644 index 4e0bcf2..0000000 --- a/cloud-native/aks-webapp-routing/README.md +++ /dev/null @@ -1,404 +0,0 @@ -# Web Application Routing with Azure Kubernetes Service - -In this lab, you will deploy an [AKS][aks] cluster and enable the [Web Application Routing (Preview)][aks_addon_web_app_routing] add-on. This add-on deploys a fully-managed Open-Source NGINX ingress controller into your cluster. We will explore the components that get installed then deploy and expose the [Azure Voting App](https://github.com/pauldotyu/azure-voting-app). - -## Requirements - -Before you get started, make sure you have the following: - -* An Azure Subscription (e.g. [Free](https://aka.ms/azure-free-account) or [Student](https://aka.ms/azure-student-account) account) -* The [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli) with [Azure Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/install#azure-cli) installed -* The [Git CLI](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) -* The [`kubectl` CLI](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/) -* Bash shell (e.g. macOS, Linux, [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/windows/wsl/about), [Multipass](https://multipass.run/), [Azure Cloud Shell](https://docs.microsoft.com/azure/cloud-shell/quickstart), [GitHub Codespaces](https://github.com/features/codespaces), etc) -* Domain registered through a [ICANN-Accredited Registrar](https://www.icann.org/registrar-reports/accredited-list.html) - -> **IMPORTANT** -> -> You will need to [delegate your DNS zone with Azure DNS](https://learn.microsoft.com/azure/dns/dns-domain-delegation) for the **Web App Routing** and **Azure DNS** integration to work properly. See this [link](https://learn.microsoft.com/azure/dns/dns-delegate-domain-azure-dns) for more info. - -Make sure you have all requisite providers registered and the `aks-preview` extension installed: - -```bash -# install provider for aks -az provider register --namespace Microsoft.ContainerService -# install aks-preview extension -az extension add --name aks-preview -``` - -[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure-Samples%2Fazure-opensource-labs%2Fmain%2Fcloud-native%2Faks-webapp-routing%2Fmain.json) - -> Use the button above if you'd like to deploy using the Azure Portal instead of Azure CLI commands. - -## Deploy Azure Resources - -Clone this repo and drop into the `aks-webapp-routing` directory. - -```bash -git clone https://github.com/Azure-Samples/azure-opensource-labs.git -cd azure-opensource-labs/cloud-native/aks-webapp-routing -``` - -Open a terminal and initialize the following variables which will be passed into the deployment. - -```bash -# azure region where resources will be deployed to -location=eastus - -# random name that will be used for azure resources -name=vote$RANDOM - -# get the latest (n-1) version of kubernetes -kubernetesVersion=$(az aks get-versions -l $location -o table | head -4 | tail -n 1 | cut -f 1 -d ' ') - -# kubernetes node count -systemNodeCount=3 - -# azure vm size for nodes -systemNodeSize=Standard_D4ds_v5 - -# get your user name -userName=$(az account show --query user.name -o tsv) - -# get your user principal id -userObjectId=$(az ad user show --id $userName --query id -o tsv) - -# a domain name you wish to use with the web_app_routing add-on -dnsName=contoso.work -``` - -Deploy Azure infrastructure with the Azure Bicep template. - -```bash -az deployment sub create \ - --name "$name-deploy" \ - --location $location \ - --template-file ./main.bicep \ - --parameters name=$name \ - location=$location \ - kubernetesVersion=$kubernetesVersion \ - systemNodeCount=$systemNodeCount \ - systemNodeSize=$systemNodeSize \ - userObjectId=$userObjectId \ - dnsName=$dnsName -``` - -> The deployment should take ~11 mins to complete - -The template will deploy the following resources into your subscription: - -* [Azure Resource Group][rg] to deploy resources into -* [Azure Kubernetes Service][aks] your managed Kubernetes cluster with [`kubenet`][kubenet] as the container network plugin and [`calico`][calico] for network policy and include the following [AKS add-ons][aks_addons] - * [`monitoring`](https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-overview) - * [`azure-keyvault-secrets-provider`](https://learn.microsoft.com/azure/aks/csi-secrets-store-driver) - * [`web_application_routing`](https://learn.microsoft.com/azure/aks/web-app-routing?tabs=without-osm) -* [Azure Key Vault][kv] to store your TLS certificates -* [Azure DNS][dns] will be integrated with the `web_application_routing` add-on and manage your domain names - -> If you are curious to know how these Bicep modules are deployed to Azure Container Registry, take a look at this [blog post](https://dev.to/azure/sharing-bicep-modules-with-azure-container-registry-4mo0). - -## Validate the Azure deployment - -View a list of resources deployed in your resource group by running the following command or view from the [Azure Portal](https://portal.azure.com): - -```bash -az resource list --resource-group rg-$name -o table -``` - -To view the AKS add-ons that have been installed, run the command below: - -```bash -az aks show --resource-group rg-${name} --name aks-${name} --query addonProfiles -``` - -You'll notice that the AKS `web_app_routing` add-on is not included in the `addonProfiles` result. The metadata for this add-on is actually kept in the `ingressProfile` object. Run the command below to view the `web_app_routing` configuration: - -```bash -az aks show --resource-group rg-${name} --name aks-${name} --query ingressProfile -``` - -One last step to complete the `web_app_routing` integration with Azure DNS. We need to grant the user assigned managed identity resource the proper permissions to manage record sets for the DNS zone. Run the following commands to grant access. - -```bash -# Retrieve user managed identity object ID for the add-on -SUBSCRIPTION_ID=$(az account show --query id --output tsv) -MANAGEDIDENTITYNAME="webapprouting-aks-${name}" -MCRGNAME=$(az aks show -g rg-${name} -n aks-${name} --query nodeResourceGroup -o tsv) -USERMANAGEDIDENTITY_RESOURCEID="/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${MCRGNAME}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${MANAGEDIDENTITYNAME}" -MANAGEDIDENTITY_OBJECTID=$(az resource show --id $USERMANAGEDIDENTITY_RESOURCEID --query properties.principalId -o tsv | tr -d '[:space:]') -# Configure the add-on to use Azure DNS to manage creating DNS zones -ZONEID=$(az network dns zone show -g rg-${name} -n $dnsName --query id --output tsv) -az role assignment create --role "DNS Zone Contributor" --assignee $MANAGEDIDENTITY_OBJECTID --scope $ZONEID -``` - -## Delegate DNS to Azure DNS - -Now is a good time to log into your domain name registrar's management portal and [delegate your DNS zone to Azure DNS](https://learn.microsoft.com/azure/dns/dns-delegate-domain-azure-dns#delegate-the-domain). - -Run this command to view the nameservers for your DNS zone in Azure DNS: - -```bash -az network dns record-set list -g rg-${name} -z $dnsName --query "[0].nsRecords[].nsdname" -``` - -> **NOTE** -> -> Azure will return nameservers that end with a dot (.). Some DNS registrars like GoDaddy will not accept the dot at the end so you will need to omit it. - -If you do not have a domain registered with an [ICANN-Accredited Registrar](https://www.icann.org/registrar-reports/accredited-list.html), you can still continue the lab. Your website will not be routable over the public internet but you can use host file entries to manually point to a public IP. - -## Validate access to the Kubernetes cluster - -Before we pull down credentials from AKS make sure you have `kubectl` CLI locally. - -> If you do not have `kubectl` installed yet, you can run the following command to install it using Azure CLI command: `az aks install-cli` - -Run the following command to download credential for `kubectl` CLI: - -```bash -az aks get-credentials --resource-group rg-${name} --name aks-${name} -``` - -Run the following command to see the namespaces that are installed so far: - -```bash -kubectl get namespaces -``` - -You should see an output similar to this: - -```output -NAME STATUS AGE -app-routing-system Active 16m -calico-system Active 25m -default Active 25m -kube-node-lease Active 25m -kube-public Active 25m -kube-system Active 25m -tigera-operator Active 25m -``` - -The `web_application_routing` add-on deploys a managed [OSS NGINX controller](https://kubernetes.github.io/ingress-nginx/). Check all the resources that it installed in the cluster with the following command: - -```bash -kubectl get all --namespace app-routing-system -``` - -You should see output similar to this: - -```output -NAME READY STATUS RESTARTS AGE -pod/external-dns-7989f85cbb-jhmng 1/1 Running 0 19m -pod/nginx-687969b887-g48cf 1/1 Running 0 18m -pod/nginx-687969b887-qtjmp 1/1 Running 0 19m - -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -service/nginx LoadBalancer 10.0.102.60 20.120.120.189 80:30282/TCP,443:30079/TCP 19m - -NAME READY UP-TO-DATE AVAILABLE AGE -deployment.apps/external-dns 1/1 1 1 19m -deployment.apps/nginx 2/2 2 2 19m - -NAME DESIRED CURRENT READY AGE -replicaset.apps/external-dns-7989f85cbb 1 1 1 19m -replicaset.apps/nginx-687969b887 2 2 2 19m - -NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE -horizontalpodautoscaler.autoscaling/nginx Deployment/nginx 0%/90% 2 100 2 19m -``` - -> The OSS NGINX ingress controller can be [installed manually via Helm chart](https://learn.microsoft.com/en-us/azure/aks/ingress-basic?tabs=azure-cli#create-an-ingress-controller), but with this being a managed NGINX controller, the installation is taken care of for you 🎉 - -Inspect the NGINX deployment: - -```bash -kubectl get deployment nginx --namespace app-routing-system --output yaml -``` - -One important thing to note is the ingress controller is deployed with an ingress class name of `webapprouting.kubernetes.azure.com`. We'll need this later in the lab as you configure your `Ingress` resources. If you run the following command, you will see the class name of the ingress controller: - -```bash -kubectl get ingressclasses -``` - -You should see output similar to this: - -```output -NAME CONTROLLER PARAMETERS AGE -webapprouting.kubernetes.azure.com k8s.io/ingress-nginx 21m -``` - -Optionally, inspect the managed NGINX controller pods that have been deployed: - -```bash -# get the name of the first running pod in the list -pod=$(kubectl get po -n app-routing-system --no-headers=true | grep nginx | grep Running | head -1 | cut -f 1 -d ' ') -kubectl get po -n app-routing-system $pod -o yaml -``` - -### Wait... what is this `external-dns` deployment that I saw? - -You may have noticed in the output above when you performed the `kubectl get all` command that there is a pod name that starts with `external-dns` and a deployment named `external-dns`. Run the following command to inspect its deployment details. - -```bash -kubectl get deployment external-dns --namespace app-routing-system --output yaml -``` - -As the name suggests, this pod is responsible for managing DNS records in your Azure DNS zone which was provisioned as part of our Bicep deployment. - -As part of our deployment process, we took the user-assigned managed identity that is created by the `web_application_routing` add-on deployment and granted it the **DNS Zone Contributor** role so that the pod can write entries for your zone. So this pod will essentially take care of writing DNS entries for you as you deploy `Ingress` resources to your cluster. - -## Application Deployment - -Make a copy of the [`deployment.yaml`](./deployment.yaml) file and name it `azure-vote-deployment.yaml`. We will need to update this manifest for our deployment. - -### Create a self-signed certificate - -When deploying an `Ingress` resource with a HTTPS-based hostname, you will need to include a SSL certificate. The `web_application_routing` add-on will be able to inject the certificate directly from Azure Key Vault. - -If you have a valid certificate for your custom domain name, you are welcome to [upload that to Azure Key Vault](https://learn.microsoft.com/azure/key-vault/certificates/tutorial-import-certificate?tabs=azure-portal). - -If you do not have a certificate for your custom domain name, we can create a self-signed certificate using the following commands: - -```bash -# Create a self-signed SSL certificate -# NOTE: The can be a subdomain (e.g. vote.contoso.work) -openssl req -new -x509 -nodes -out aks-ingress-tls.crt -keyout aks-ingress-tls.key -subj "/CN=" -addext "subjectAltName=DNS:" - -# Export the SSL certificate -# NOTE: You must skip the password prompt (i.e. leave it blank) -openssl pkcs12 -export -in aks-ingress-tls.crt -inkey aks-ingress-tls.key -out aks-ingress-tls.pfx -``` - -### Import the certificate to Azure Key Vault - -```bash -az keyvault certificate import --vault-name akv-$name -n azure-vote -f aks-ingress-tls.pfx -``` - -The command above will output a large JSON object to the terminal. You will need the certificate URI for the next step. This value can be found in within the `id` attribute for the resource. - -If you want to be sure you are retrieving the correct certificate URI, you can run the following command: - -```bash -az keyvault certificate show --vault-name akv-$name -n azure-vote --query id --output tsv -``` - -Copy the value to your clipboard as you will need to add this to your deployment manifest. - -### Update the `azure-vote-deployment.yaml` manifest - -Open the `azure-vote-deployment.yaml` manifest using your favorite text editor, and replace the `` with your DNS zone name and the `` with certificate URI from Azure Key Vault. - -Here is an example of what the new file should look like: - -![Updated manifest](./azure-vote-deployment.png) - -> `secretName` is the name of the secret that going to be generated to store the certificate. This is the certificate that's going to be presented in the browser. - -### Deploy the `azure-vote-deployment.yaml` manifest - -Run the following command to deploy the manifest - -```bash -kubectl apply -f azure-vote-deployment.yaml -``` - -Confirm the deployment by running this command. - -```bash -kubectl get ingress -``` - -After about a minute, you should see the `ADDRESS` column populated with a public IP address within a minute or two and the output will look similar to this: - -```output -NAME CLASS HOSTS ADDRESS PORTS AGE -azure-vote-front webapprouting.kubernetes.azure.com vote.contoso.work 20.246.231.104 80, 443 45s -``` - -You can also check your DNS zone for updated A records that points to your ingress' IP using the following command: - -```bash -az network dns record-set list -g rg-${name} -z $dnsName --query "[?type=='Microsoft.Network/dnszones/A']" -``` - -Your output will look similar to this: - -```output -[ - { - "aRecords": [ - { - "ipv4Address": "20.246.231.104" - } - ], - "aaaaRecords": null, - "caaRecords": null, - "cnameRecord": null, - "etag": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "fqdn": "vote.contoso.work.", - "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg-vote24543/providers/Microsoft.Network/dnszones/contoso.work/A/hello", - "metadata": null, - "mxRecords": null, - "name": "hello", - "nsRecords": null, - "provisioningState": "Succeeded", - "ptrRecords": null, - "resourceGroup": "rg-vote6045", - "soaRecord": null, - "srvRecords": null, - "targetResource": { - "id": null - }, - "ttl": 300, - "txtRecords": null, - "type": "Microsoft.Network/dnszones/A" - } -] -``` - -You can also view the `external-dns` pod logs to see it making changes to your DNS zone using the following command: - -```bash -pod=$(kubectl get po -n app-routing-system --no-headers=true | grep external-dns | grep Running | head -1 | cut -f 1 -d ' ') -kubectl logs $pod -n app-routing-system -``` - -Finally, validate the deployment by opening a web browser and navigating to your custom domain name. - -> If you have not [delegated your DNS zone to Azure DNS](https://learn.microsoft.com/azure/dns/dns-delegate-domain-azure-dns#delegate-the-domain) at your registrar's DNS management tool, you could setup an [entry in your local host file](https://www.howtogeek.com/howto/27350/beginner-geek-how-to-edit-your-hosts-file/) to point your custom domain to the public ingress IP. - -![Deployment validation](./azure-vote-deployment-validation.png) - -> Some browsers may not let you view websites that are secured using self-signed certificates. In this case you may need to update your browser configuration. - -## Wrap up - -In lab, we deployed an AKS cluster using Bicep templates and enabled the Web Application Routing add-on. - -We then examined the resources that been deployed into our cluster and uncovered how the integrations work. This add-on includes integrations with Azure Key Vault and Azure DNS which enables you to easily expose applications to the internet. Using annotations on the NGINX ingress controller, we can simply bind the `Ingress` resource to a TLS certificate in Azure Key Vault to secure our website. - -Also, with Azure DNS integrated with the add-on, we observed that it deployed an `external-dns` controller and we gave the add-on proper permissions to manipulate DNS records. As you expose additional sites (as subdomains) you will have additional DNS entries which should save you a bit of time. - -Best part of the add-on is that it is a OSS component that is fully-managed and fully-supported by Microsoft 🥳 - -Once you have finished exploring, you should delete the deployment to avoid any further charges. - -```bash -az group delete --name rg-${name} -y -``` - -## Resources - -* [AKS Add-On: Web Application Routing (Preview)][aks_addon_web_app_routing] - - -[aks_addons]:https://learn.microsoft.com/azure/aks/integrations#available-add-ons -[aks_addon_web_app_routing]:https://learn.microsoft.com/azure/aks/web-app-routing?tabs=without-osm -[kubenet]:https://learn.microsoft.com/azure/aks/configure-kubenet -[calico]:https://projectcalico.docs.tigera.io/security/kubernetes-policy -[rg]:https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal#what-is-a-resource-group -[aks]:https://learn.microsoft.com/azure/aks/intro-kubernetes -[kv]:https://learn.microsoft.com/azure/key-vault/general/overview -[dns]:https://learn.microsoft.com/azure/dns/dns-overview diff --git a/cloud-native/aks-webapp-routing/azure-vote-deployment-validation.png b/cloud-native/aks-webapp-routing/azure-vote-deployment-validation.png deleted file mode 100644 index b0baec0a86ed8e1c0821846ae124e6b9a10358cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40669 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�-D*2Q`wf&H&rBBDetN80|uZj(S? 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%0D?LT_DeB&3Ji@=)|V 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