From b4fd6649d7add9112cb41fa77564970f78d6a5dc Mon Sep 17 00:00:00 2001 From: naman-msft <146123940+naman-msft@users.noreply.github.com> Date: Wed, 20 Mar 2024 12:55:55 -0700 Subject: [PATCH 1/4] Created the deployHAPGSLonAKS scenario For BUILD --- scenarios/DeployHAPGSQLonAKS/README.md | 517 +++++++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 scenarios/DeployHAPGSQLonAKS/README.md diff --git a/scenarios/DeployHAPGSQLonAKS/README.md b/scenarios/DeployHAPGSQLonAKS/README.md new file mode 100644 index 000000000..ec1586b6c --- /dev/null +++ b/scenarios/DeployHAPGSQLonAKS/README.md @@ -0,0 +1,517 @@ +--- +title: Create a Highly Available PostgreSQL Cluster on Azure Kubernetes Service +description: This tutorial shows how to create a Highly Available PostgreSQL cluster on Azure Kubernetes Service (AKS) using the CloudNativePG operator +author: russd2357, kenkilty +ms.author: rdepina, kkilty +ms.topic: article +ms.date: 03/19/2024 +ms.custom: innovation-engine, linux-related content +--- + +# Create a Highly Available PostgreSQL Cluster on Azure Kubernetes Service + +## Define Environment Variables + +The First step in this tutorial is to define environment variables. + +```bash +export RED=$(tput setaf 1) +export GREEN=$(tput setaf 2) +export NC=$(tput sgr0) +export LOCAL_NAME="cnpg" +export RGTAGS="owner=cnpg" +export LOCATION="eastus" +export CLUSTER_VERSION="1.27" +export AKS_NODE_COUNT=2 +export SUFFIX=$(tr -dc a-z0-9 /dev/null; then + echo "aks-preview extension is not installed. Please install it using the following command=" + az extension add --name aks-preview +fi +``` + +```bash +# This block checks if NodeAutoProvisioningPreview feature is already enabled. If not, then do the following: Register the NodeAutoProvisioningPreview feature flag, wait for the feature registration to complete, and refresh the registration of the Microsoft.ContainerService resource provider until the feature is registered. +if ! az feature show --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" --subscription "$SUBSCRIPTION_ID" --query "properties.state" --output tsv | grep -wq "Registered"; then + az feature register --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" + status="" + timeout=60 + start_time=$(date +%s) + while true; do + current_time=$(date +%s) + elapsed_time=$((current_time - start_time)) + if [ $elapsed_time -ge $timeout ]; then + echo "Unable to register NodeAutoProvisioningPreview feature. Exiting..." + fi + status=$(az feature show --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" --subscription "$SUBSCRIPTION_ID" --query "properties.state" --output tsv | tr '[=upper=]' '[=lower=]') + if [ "$(echo "$status" | tr '[=upper=]' '[=lower=]')" = "registered" ]; then + break + else + sleep 5 + fi + done + az feature register --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" +else + echo ${GREEN} "NodeAutoProvisioningPreview feature is already registered." +fi +``` + +```bash +# This block checks if helm is installed +echo ${GREEN} "Checking prerequisites... " ${NC} +if ! command -v helm &> /dev/null; then + echo ${RED} "Helm is not installed. Please install it using the following command:" + curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 + chmod 700 get_helm.sh + ./get_helm.sh +fi +``` + +```bash +# This block checks if kubectl is installed +if ! command -v kubectl &> /dev/null; then + echo ${RED} "kubectl is not installed. Please install it using the following command:" + az aks install-cli --install-location ./kubectl +fi +echo ${GREEN} "Prerequisites are met." ${NC} +``` + +## Create a Resource Group + +A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $RG_NAME and $LOCATION parameters. + +```bash +# This block checks to see if resource group already exists. If not, it creates the resource group +export RG_NAME="rg-${LOCAL_NAME}-${SUFFIX}" +if ! az group show -n $RG_NAME &> /dev/null; then + az group create -n $RG_NAME -l $LOCATION --tags $RGTAGS +else + echo ${RED} "Resource group $RG_NAME already exists." +fi +``` + +Results: + + +```json +{ + "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myVMResourceGroup", + "location": "eastus", + "managedBy": null, + "name": "myVMResourceGroup", + "properties": { + "provisioningState": "Succeeded" + }, + "tags": null, + "type": "Microsoft.Resources/resourceGroups" +} +``` + +## Create an Azure Storage Account and Container for Postgres Backups + +In this part of the process, you'll be creating an Azure Storage Account and a container for Postgres backups. + +Start by creating a storage account. Here, the az storage account create command is used. You'll need to provide the name of the storage account, the resource group it belongs to, the location (region) where it should be created, and the type of storage account you want to create. In this case, a Standard_LRS (Locally redundant storage) account is created. + +If the storage account is created successfully, you'll see a message indicating "Storage account created." If the storage account already exists, you'll see a message stating "Storage account already exists." + +This storage account will be used for backing up your Postgres database in this deployment. + +```bash +# This block sets up the storage account used for the backing up Postgres in this deployment. Specifically, it checks for the existence of the storage account. If not, it creates an Azure Storage Account and container for the Postgres backups +if ! az storage account show --name "${STORAGE_ACCOUNT_NAME}" --resource-group "${RG_NAME}" &> /dev/null; then + az storage account create --name "${STORAGE_ACCOUNT_NAME}" --resource-group "${RG_NAME}" --location "${LOCATION}" --sku Standard_LRS +else + echo ${RED} "Storage account already exists." ${NC} +fi +``` + +Results: + + +```json +{ + "accessTier": "Hot", + "accountMigrationInProgress": null, + "allowBlobPublicAccess": false, + "allowCrossTenantReplication": false, + "allowSharedKeyAccess": null, + "allowedCopyScope": null, + "azureFilesIdentityBasedAuthentication": null, + "blobRestoreStatus": null, + "creationTime": "xxxx-xx-xxxx:xx:xx.xxxxx+xx:xx", + "customDomain": null, + "defaultToOAuthAuthentication": null, + "dnsEndpointType": null, + "enableHttpsTrafficOnly": true, + "enableNfsV3": null, + "encryption": { + "encryptionIdentity": null, + "keySource": "Microsoft.Storage", + "keyVaultProperties": null, + "requireInfrastructureEncryption": null, + "services": { + "blob": { + "enabled": true, + "keyType": "Account", + "lastEnabledTime": "xxxx-xx-xxxx:xx:xx.xxxxx+xx:xx" + }, + "file": { + "enabled": true, + "keyType": "Account", + "lastEnabledTime": "xxxx-xx-xxxx:xx:xx.xxxxx+xx:xx" + }, + "queue": null, + "table": null + } + }, + "extendedLocation": null, + "failoverInProgress": null, + "geoReplicationStats": null, + "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx-xxxx-xxxx/providers/Microsoft.Storage/storageAccounts/xxxxxxxxxx", + "identity": null, + "immutableStorageWithVersioning": null, + "isHnsEnabled": null, + "isLocalUserEnabled": null, + "isSftpEnabled": null, + "isSkuConversionBlocked": null, + "keyCreationTime": { + "key1": "xxxx-xx-xxxx:xx:xx.xxxxx+xx:xx", + "key2": "xxxx-xx-xxxx:xx:xx.xxxxx+xx:xx" + }, + "keyPolicy": null, + "kind": "StorageV2", + "largeFileSharesState": null, + "lastGeoFailoverTime": null, + "location": "eastus", + "minimumTlsVersion": "TLS1_0", + "name": "xxxxxxxxxx", + "networkRuleSet": { + "bypass": "AzureServices", + "defaultAction": "Allow", + "ipRules": [], + "ipv6Rules": [], + "resourceAccessRules": null, + "virtualNetworkRules": [] + }, + "primaryEndpoints": { + "blob": "https://storcnpgdfpu2m.blob.core.windows.net/", + "dfs": "https://storcnpgdfpu2m.dfs.core.windows.net/", + "file": "https://storcnpgdfpu2m.file.core.windows.net/", + "internetEndpoints": null, + "microsoftEndpoints": null, + "queue": "https://storcnpgdfpu2m.queue.core.windows.net/", + "table": "https://storcnpgdfpu2m.table.core.windows.net/", + "web": "https://storcnpgdfpu2m.z22.web.core.windows.net/" + }, + "primaryLocation": "eastus", + "privateEndpointConnections": [], + "provisioningState": "Succeeded", + "publicNetworkAccess": null, + "resourceGroup": "xxxxxxxxxx", + "routingPreference": null, + "sasPolicy": null, + "secondaryEndpoints": null, + "secondaryLocation": null, + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "statusOfPrimary": "available", + "statusOfSecondary": null, + "storageAccountSkuConversionStatus": null, + "tags": {}, + "type": "Microsoft.Storage/storageAccounts" +} +``` + +Next, you'll be creating a container in your Azure Storage Account specifically for Postgres backups. This is done using the az storage container create command. You'll need to provide the name of the container and the name of the storage account it belongs to. + +```bash +# This block creates a container for the Postgres backups +if ! az storage container show --name "${BARMAN_CONTAINER_NAME}" --account-name "${STORAGE_ACCOUNT_NAME}" &> /dev/null; then + az storage container create --name "${BARMAN_CONTAINER_NAME}" --account-name "${STORAGE_ACCOUNT_NAME}" +else + echo ${RED} "Container already exists." ${NC} +fi +``` + +Results: + + +```json +{ + "created": true +} +``` + +## Create AKS Cluster + +The next step is to create an Azure Kubernetes Service (AKS) cluster. This is done using the az aks create command. In the first phase, you'll need to check if the user assigned managed identity for the AKS cluster exists. If not, you'll create the managed identity. Next, you'll create the AKS cluster. This is done using the az aks create command. You'll need to provide the name of the AKS cluster, the resource group it belongs to, the number of nodes in the cluster, and the name of the user assigned managed identity for the AKS cluster. + +```bash +# This block stands up the AKS cluster. As the first step in that, it checks if the user assigned managed identity for the AKS cluster exists. If not, it creates the managed identity. +managedIdentity=$(az identity create --name "${AKS_MANAGED_IDENTITY_NAME}" --resource-group "${RG_NAME}") +managedIdentityObjectId=$(echo "${managedIdentity}" | jq -r '.principalId') +managedIdentityResourceId=$(echo "${managedIdentity}" | jq -r '.id') +if ! az aks show --name "${AKS_CLUSTER_NAME}" --resource-group "${RG_NAME}" &> /dev/null; then + az aks create --tags "$RGTAGS" --name "${AKS_CLUSTER_NAME}" --resource-group "${RG_NAME}" --enable-keda --enable-managed-identity --assign-identity $managedIdentityResourceId --node-provisioning-mode Auto --network-plugin azure --network-plugin-mode overlay --network-dataplane cilium --nodepool-taints CriticalAddonsOnly=true:NoSchedule --node-count "$AKS_NODE_COUNT" --enable-oidc-issuer --generate-ssh-keys +else + echo ${RED} "Cluster already exists." +fi +``` + +Results: + + +```json +{ + "aadProfile": null, + "addonProfiles": { + "KubeDashboard": { + "config": null, + "enabled": false + }, + "azurepolicy": { + "config": null, + "enabled": false + } + }, + "agentPoolProfiles": [ + { + "availabilityZones": null, + "count": 3, + "enableAutoScaling": null, + "enableNodePublicIp": false, + "maxCount": null, + "maxPods": 110, + "minCount": null, + "mode": "System", + "name": "nodepool1", + "nodeImageVersion": "AKSUbuntu-1804gen2containerd-2021.09.22", + "nodeLabels": {}, + "nodeTaints": null, + "orchestratorVersion": "1.20.7", + "osDiskSizeGb": 128, + "osDiskType": "Managed", + "osType": "Linux", + "provisioningState": "Succeeded", + "scaleSetEvictionPolicy": null, + "scaleSetPriority": null, + "spotMaxPrice": null, + "tags": null, + "type": "VirtualMachineScaleSets", + "vmSize": "Standard_D2s_v3" + } + ], + "apiServerAccessProfile": null, + "autoScalerProfile": null, + "autoUpgradeProfile": null, + "azurePortalFQDN": "xxxxxxxxxx-xxxxxxx.xxx.xxxxxx.xxxxx.xx", + "diskEncryptionSetId": null, + "dnsPrefix": "xxxxxxxxxx", + "enablePodSecurityPolicy": null, + "enableRbac": true, + "fqdn": "xxxxxxxxxx-xxxxxxx.xxx.xxxxxx.xxxxx.xx", + "id": "/subscriptions/xxxxxxxxxx-xx-xxxx-xxx-xxx/resourcegroups/myResourceGroup/providers/Microsoft.ContainerService/managedClusters/xxxxxxxxxx", + "identity": null, + "kubernetesVersion": "1.20.7", + "linuxProfile": null, + "location": "eastus", + "maxAgentPools": 100, + "name": "xxxxxxxxxx", + "networkProfile": { + "dnsServiceIp": "xx.x.x.xx", + "dockerBridgeCidr": "xxx.xx.x.x/xx", + "loadBalancerProfile": null, + "networkMode": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "outboundType": "loadBalancer", + "podCidr": "xx.xxx.x.x/xx", + "serviceCidr": "xx.xxx.x.x/xx" + }, + "nodeResourceGroup": "MC_xxxxxxxxxx_xxxxxxxxxx_eastus", + "powerState": { + "code": "Running" + }, + "privateFqdn": null, + "provisioningState": "Succeeded", + "resourceGroup": "xxxxxxxxxx", + "servicePrincipalProfile": null, + "sku": { + "name": "Basic", + "tier": "Free" + }, + "tags": { + "Environment": "Production" + }, + "type": "Microsoft.ContainerService/ManagedClusters", + "windowsProfile": null +} +``` + +By this point the cluster should be up and running. This step ensures that by getting access credentials for the cluster. + +```bash +# By this point the cluster should be up and running. This block gets access credentials for the k8s cluster +echo ${GREEN} "Getting access credentials for the k8s cluster..." ${NC} +if ! az aks get-credentials --name ${AKS_CLUSTER_NAME} --resource-group ${RG_NAME}; then + echo ${RED} "Failed to retrieve credentials for cluster ${AKS_CLUSTER_NAME}" ${NC} +fi +``` + +## Install the Postgres Cluster + +The next step is to install the Postgres Cluster. This is done using the CloudNativePG operator. The CloudNativePG operator is a Kubernetes operator that manages PostgreSQL clusters. It is designed to be cloud-native and to provide a high level of automation for managing PostgreSQL clusters. The CloudNativePG operator is installed using the kubectl apply command. + +### Install the CloudNativePG Operator + +First, install the CloudNativePG operator on the AKS cluster. + +```bash +# This block installs the CloudNativePG operator on the AKS cluster +sudo /usr/local/bin/kubectl +kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-1.22.0.yaml +``` + +### Enable Expanding Volumes for AKS + +Next, update the configuration of the CloudNativePG operator to enable expanding volumes for AKS. + +```bash +# This block updates the configuration of the CloudNativePG operator to enable expanding volumes for AKS +kubectl apply -f az-expanding-vols.yaml +``` + +```bash +# This block restarts the CloudNativePG controller to apply the new configuration +kubectl rollout restart deployment -n cnpg-system cnpg-controller-manager +``` + +### Create the Storage Class for the Postgres Deployment + +Next, create the storage class for the Postgres deployment. + +```bash +# This block creates the storage class for the Postgres deployment +echo "Create the storage class for the Postgres deployment" +if kubectl apply -f std-storageclass.yaml; then + echo ${RED} "Failed to create the storage class for the Postgres deployment" ${NC} +fi +``` + +### Create the Namespace and Secrets for the Postgres Deployment + +Next, create the namespace and secrets for the Postgres deployment. + +```bash +# This block creates the namespace for the Postgres deployment +echo ${GREEN} "Create namespace for Postgres deployment..." ${NC} +if kubectl create -f auth-prod.yaml; then + echo ${RED} "Failed to create the namespace for Postgres deployment" ${NC} +fi +``` + +Finally, create the Postgres cluster. + +```bash +# This block gets the storage account key, deploys the Postgres Cluster and inserts the storage account key into the cluster specification +echo ${GREEN} "Getting the storage account key..." ${NC} +STORAGE_ACCOUNT_KEY=$(az storage account keys list --account-name ${STORAGE_ACCOUNT_NAME} --resource-group ${RG_NAME} --query "[0].value" --output tsv) +echo ${GREEN} "Deploying the Postgres cluster..." ${NC} +cat <>:role/cnpg-on-eks-prod-irsa + postgresql: + parameters: + shared_buffers: 256MB + pg_stat_statements.max: '10000' + pg_stat_statements.track: all + auto_explain.log_min_duration: '10s' + pg_hba: + # - hostssl app all all cert + - host app app all password + logLevel: debug + # Choose the right storageclass for type of workload. + storage: + storageClass: storageclass-io2 + size: 1Gi + walStorage: + storageClass: storageclass-io2 + size: 1Gi + monitoring: + enablePodMonitor: true + bootstrap: + initdb: # Deploying a new cluster + database: WorldDB + owner: app + secret: + name: app-auth + backup: + barmanObjectStore: + # For backup, we use a blob container in an Azure Storage Account to store data. + # On this Blueprint, we get the account and container name from the environment variables. + # We retrieved the storage account key previously so we don't need to save secrets anywhere. + destinationPath: https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net/${BARMAN_CONTAINER_NAME}/ + azureCredentials: + storageAccount: + name: recovery-object-store-secret + key: ${STORAGE_ACCOUNT_NAME} + storageKey: + name: recovery-object-store-secret + key: ${STORAGE_ACCOUNT_KEY} + wal: + compression: gzip + maxParallel: 8 + retentionPolicy: "30d" + affinity: + enablePodAntiAffinity: true + topologyKey: kubernetes.io/hostname + pointAntiAffinityType: preferred + + nodeMaintenanceWindow: + inProgress: false + reusePVC: false +EOF +``` From 0db138e564091eef952ba9cd0cef566cc6ef4481 Mon Sep 17 00:00:00 2001 From: naman-msft <146123940+naman-msft@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:08:55 -0700 Subject: [PATCH 2/4] Update README.md --- scenarios/DeployHAPGSQLonAKS/README.md | 68 +++++++------------------- 1 file changed, 17 insertions(+), 51 deletions(-) diff --git a/scenarios/DeployHAPGSQLonAKS/README.md b/scenarios/DeployHAPGSQLonAKS/README.md index ec1586b6c..d4b2146da 100644 --- a/scenarios/DeployHAPGSQLonAKS/README.md +++ b/scenarios/DeployHAPGSQLonAKS/README.md @@ -15,8 +15,8 @@ ms.custom: innovation-engine, linux-related content The First step in this tutorial is to define environment variables. ```bash -export RED=$(tput setaf 1) -export GREEN=$(tput setaf 2) +export ERROR=$(tput setaf 1) +export OUTPUT=$(tput setaf 2) export NC=$(tput sgr0) export LOCAL_NAME="cnpg" export RGTAGS="owner=cnpg" @@ -38,19 +38,20 @@ In order to run commands against Azure using the CLI you need to login. This is ## Check for Prerequisites -Next, check for prerequisites. This process involves verifying the installation of several tools and features necessary for your project. This section checks for the following prerequisites: aks-preview extension, helm, and kubectl. It also checks if the NodeAutoProvisioningPreview feature is already enabled. If not, it registers the feature flag, waits for the feature registration to complete, and refreshes the registration of the Microsoft.ContainerService resource provider until the feature is registered. +Next, check for prerequisites. This section checks for the following prerequisites: aks-preview extension, helm, and kubectl. It also checks if the NodeAutoProvisioningPreview feature is already enabled. If not, it registers the feature flag, waits for the feature registration to complete, and refreshes the registration of the Microsoft.ContainerService resource provider until the feature is registered. + +### AKS-Preview Extension ```bash -# This block checks if aks-preview extension is installed -echo ${GREEN} "Checking if aks-preview extension is installed..." ${NC} +echo ${OUTPUT} "Checking if aks-preview extension is installed..." ${NC} if ! az extension show --name aks-preview &> /dev/null; then - echo "aks-preview extension is not installed. Please install it using the following command=" - az extension add --name aks-preview + az extension add --name aks-preview fi ``` +### NodeAutoProvisioningPreview Feature + ```bash -# This block checks if NodeAutoProvisioningPreview feature is already enabled. If not, then do the following: Register the NodeAutoProvisioningPreview feature flag, wait for the feature registration to complete, and refresh the registration of the Microsoft.ContainerService resource provider until the feature is registered. if ! az feature show --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" --subscription "$SUBSCRIPTION_ID" --query "properties.state" --output tsv | grep -wq "Registered"; then az feature register --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" status="" @@ -70,29 +71,25 @@ if ! az feature show --namespace "Microsoft.ContainerService" --name "NodeAutoPr fi done az feature register --namespace "Microsoft.ContainerService" --name "NodeAutoProvisioningPreview" -else - echo ${GREEN} "NodeAutoProvisioningPreview feature is already registered." fi ``` +### Helm + ```bash -# This block checks if helm is installed -echo ${GREEN} "Checking prerequisites... " ${NC} if ! command -v helm &> /dev/null; then - echo ${RED} "Helm is not installed. Please install it using the following command:" curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh fi ``` +### Kubectl + ```bash -# This block checks if kubectl is installed if ! command -v kubectl &> /dev/null; then - echo ${RED} "kubectl is not installed. Please install it using the following command:" - az aks install-cli --install-location ./kubectl + az aks install-cli fi -echo ${GREEN} "Prerequisites are met." ${NC} ``` ## Create a Resource Group @@ -100,12 +97,9 @@ echo ${GREEN} "Prerequisites are met." ${NC} A resource group is a container for related resources. All resources must be placed in a resource group. We will create one for this tutorial. The following command creates a resource group with the previously defined $RG_NAME and $LOCATION parameters. ```bash -# This block checks to see if resource group already exists. If not, it creates the resource group export RG_NAME="rg-${LOCAL_NAME}-${SUFFIX}" if ! az group show -n $RG_NAME &> /dev/null; then az group create -n $RG_NAME -l $LOCATION --tags $RGTAGS -else - echo ${RED} "Resource group $RG_NAME already exists." fi ``` @@ -137,11 +131,8 @@ If the storage account is created successfully, you'll see a message indicating This storage account will be used for backing up your Postgres database in this deployment. ```bash -# This block sets up the storage account used for the backing up Postgres in this deployment. Specifically, it checks for the existence of the storage account. If not, it creates an Azure Storage Account and container for the Postgres backups if ! az storage account show --name "${STORAGE_ACCOUNT_NAME}" --resource-group "${RG_NAME}" &> /dev/null; then az storage account create --name "${STORAGE_ACCOUNT_NAME}" --resource-group "${RG_NAME}" --location "${LOCATION}" --sku Standard_LRS -else - echo ${RED} "Storage account already exists." ${NC} fi ``` @@ -247,11 +238,8 @@ Results: Next, you'll be creating a container in your Azure Storage Account specifically for Postgres backups. This is done using the az storage container create command. You'll need to provide the name of the container and the name of the storage account it belongs to. ```bash -# This block creates a container for the Postgres backups if ! az storage container show --name "${BARMAN_CONTAINER_NAME}" --account-name "${STORAGE_ACCOUNT_NAME}" &> /dev/null; then az storage container create --name "${BARMAN_CONTAINER_NAME}" --account-name "${STORAGE_ACCOUNT_NAME}" -else - echo ${RED} "Container already exists." ${NC} fi ``` @@ -269,14 +257,11 @@ Results: The next step is to create an Azure Kubernetes Service (AKS) cluster. This is done using the az aks create command. In the first phase, you'll need to check if the user assigned managed identity for the AKS cluster exists. If not, you'll create the managed identity. Next, you'll create the AKS cluster. This is done using the az aks create command. You'll need to provide the name of the AKS cluster, the resource group it belongs to, the number of nodes in the cluster, and the name of the user assigned managed identity for the AKS cluster. ```bash -# This block stands up the AKS cluster. As the first step in that, it checks if the user assigned managed identity for the AKS cluster exists. If not, it creates the managed identity. managedIdentity=$(az identity create --name "${AKS_MANAGED_IDENTITY_NAME}" --resource-group "${RG_NAME}") managedIdentityObjectId=$(echo "${managedIdentity}" | jq -r '.principalId') managedIdentityResourceId=$(echo "${managedIdentity}" | jq -r '.id') if ! az aks show --name "${AKS_CLUSTER_NAME}" --resource-group "${RG_NAME}" &> /dev/null; then az aks create --tags "$RGTAGS" --name "${AKS_CLUSTER_NAME}" --resource-group "${RG_NAME}" --enable-keda --enable-managed-identity --assign-identity $managedIdentityResourceId --node-provisioning-mode Auto --network-plugin azure --network-plugin-mode overlay --network-dataplane cilium --nodepool-taints CriticalAddonsOnly=true:NoSchedule --node-count "$AKS_NODE_COUNT" --enable-oidc-issuer --generate-ssh-keys -else - echo ${RED} "Cluster already exists." fi ``` @@ -373,11 +358,7 @@ Results: By this point the cluster should be up and running. This step ensures that by getting access credentials for the cluster. ```bash -# By this point the cluster should be up and running. This block gets access credentials for the k8s cluster -echo ${GREEN} "Getting access credentials for the k8s cluster..." ${NC} -if ! az aks get-credentials --name ${AKS_CLUSTER_NAME} --resource-group ${RG_NAME}; then - echo ${RED} "Failed to retrieve credentials for cluster ${AKS_CLUSTER_NAME}" ${NC} -fi +az aks get-credentials --name ${AKS_CLUSTER_NAME} --resource-group ${RG_NAME} ``` ## Install the Postgres Cluster @@ -389,8 +370,6 @@ The next step is to install the Postgres Cluster. This is done using the CloudNa First, install the CloudNativePG operator on the AKS cluster. ```bash -# This block installs the CloudNativePG operator on the AKS cluster -sudo /usr/local/bin/kubectl kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-1.22.0.yaml ``` @@ -399,12 +378,10 @@ kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg Next, update the configuration of the CloudNativePG operator to enable expanding volumes for AKS. ```bash -# This block updates the configuration of the CloudNativePG operator to enable expanding volumes for AKS kubectl apply -f az-expanding-vols.yaml ``` ```bash -# This block restarts the CloudNativePG controller to apply the new configuration kubectl rollout restart deployment -n cnpg-system cnpg-controller-manager ``` @@ -413,11 +390,7 @@ kubectl rollout restart deployment -n cnpg-system cnpg-controller-manager Next, create the storage class for the Postgres deployment. ```bash -# This block creates the storage class for the Postgres deployment -echo "Create the storage class for the Postgres deployment" -if kubectl apply -f std-storageclass.yaml; then - echo ${RED} "Failed to create the storage class for the Postgres deployment" ${NC} -fi +kubectl apply -f std-storageclass.yaml ``` ### Create the Namespace and Secrets for the Postgres Deployment @@ -425,20 +398,13 @@ fi Next, create the namespace and secrets for the Postgres deployment. ```bash -# This block creates the namespace for the Postgres deployment -echo ${GREEN} "Create namespace for Postgres deployment..." ${NC} -if kubectl create -f auth-prod.yaml; then - echo ${RED} "Failed to create the namespace for Postgres deployment" ${NC} -fi +kubectl create -f auth-prod.yaml ``` Finally, create the Postgres cluster. ```bash -# This block gets the storage account key, deploys the Postgres Cluster and inserts the storage account key into the cluster specification -echo ${GREEN} "Getting the storage account key..." ${NC} STORAGE_ACCOUNT_KEY=$(az storage account keys list --account-name ${STORAGE_ACCOUNT_NAME} --resource-group ${RG_NAME} --query "[0].value" --output tsv) -echo ${GREEN} "Deploying the Postgres cluster..." ${NC} cat < Date: Wed, 20 Mar 2024 16:09:31 -0700 Subject: [PATCH 3/4] Add files via upload --- scenarios/DeployHAPGSQLonAKS/auth-prod.yaml | 17 +++++++++++++++++ .../DeployHAPGSQLonAKS/az-expanding-vols.yaml | 8 ++++++++ .../DeployHAPGSQLonAKS/std-storageclass.yaml | 15 +++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 scenarios/DeployHAPGSQLonAKS/auth-prod.yaml create mode 100644 scenarios/DeployHAPGSQLonAKS/az-expanding-vols.yaml create mode 100644 scenarios/DeployHAPGSQLonAKS/std-storageclass.yaml diff --git a/scenarios/DeployHAPGSQLonAKS/auth-prod.yaml b/scenarios/DeployHAPGSQLonAKS/auth-prod.yaml new file mode 100644 index 000000000..e81bb1b65 --- /dev/null +++ b/scenarios/DeployHAPGSQLonAKS/auth-prod.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: demo + labels: + name: demo +--- +apiVersion: v1 +kind: Secret +metadata: + name: app-auth + namespace: demo +type: kubernetes.io/basic-auth +stringData: + username: app # required field for kubernetes.io/basic-auth + password: testing # required field for kubernetes.io/basic-auth diff --git a/scenarios/DeployHAPGSQLonAKS/az-expanding-vols.yaml b/scenarios/DeployHAPGSQLonAKS/az-expanding-vols.yaml new file mode 100644 index 000000000..6608f5dc6 --- /dev/null +++ b/scenarios/DeployHAPGSQLonAKS/az-expanding-vols.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: cnpg-controller-manager-config + namespace: cnpg-system +type: Opaque +stringData: + ENABLE_AZURE_PVC_UPDATES: 'true' \ No newline at end of file diff --git a/scenarios/DeployHAPGSQLonAKS/std-storageclass.yaml b/scenarios/DeployHAPGSQLonAKS/std-storageclass.yaml new file mode 100644 index 000000000..33b1c60e9 --- /dev/null +++ b/scenarios/DeployHAPGSQLonAKS/std-storageclass.yaml @@ -0,0 +1,15 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: storageclass-io2 +provisioner: disk.csi.azure.com +reclaimPolicy: Retain +volumeBindingMode: WaitForFirstConsumer +allowVolumeExpansion: true +parameters: + skuName: Standard_LRS + fsType: xfs + DiskIOPSReadWrite: "100" + + + From 6ccd3d49987a3e4467dfb7c6d46bc4ad12581b99 Mon Sep 17 00:00:00 2001 From: naman-msft <146123940+naman-msft@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:42:37 -0700 Subject: [PATCH 4/4] Updated author names --- scenarios/DeployHAPGSQLonAKS/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scenarios/DeployHAPGSQLonAKS/README.md b/scenarios/DeployHAPGSQLonAKS/README.md index d4b2146da..bb54df2f6 100644 --- a/scenarios/DeployHAPGSQLonAKS/README.md +++ b/scenarios/DeployHAPGSQLonAKS/README.md @@ -1,8 +1,8 @@ --- title: Create a Highly Available PostgreSQL Cluster on Azure Kubernetes Service description: This tutorial shows how to create a Highly Available PostgreSQL cluster on Azure Kubernetes Service (AKS) using the CloudNativePG operator -author: russd2357, kenkilty -ms.author: rdepina, kkilty +author: russd2357 +ms.author: rdepina ms.topic: article ms.date: 03/19/2024 ms.custom: innovation-engine, linux-related content