|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Using template from: https://github.com/Azure/EasyAuthForK8s/blob/master/docs/deploy-to-existing-cluster.md |
| 4 | +# Docs ref: https://learn.microsoft.com/en-us/azure/aks/ingress-tls?tabs=azure-cli |
| 5 | + |
| 6 | + |
| 7 | +# Check if jq for json manipulation is installed, if not attempt to install it |
| 8 | +if ! command -v jq &> /dev/null; then |
| 9 | + echo "'jq' could not be found. Attempting to install..." |
| 10 | + if command -v apt &> /dev/null; then |
| 11 | + sudo apt update && sudo apt install -y jq |
| 12 | + elif command -v yum &> /dev/null; then |
| 13 | + sudo yum update && sudo yum install -y jq |
| 14 | + else |
| 15 | + echo "Package manager not recognized. Please install 'jq' manually." |
| 16 | + exit 1 |
| 17 | + fi |
| 18 | +fi |
| 19 | + |
| 20 | +# Getting environment variables |
| 21 | +output=$(azd env get-values) |
| 22 | + |
| 23 | +# Loop through each line in the output |
| 24 | +while IFS= read -r line; do |
| 25 | + if [[ ! $line == *"="* ]]; then |
| 26 | + continue |
| 27 | + fi |
| 28 | + |
| 29 | + name=$(echo "$line" | cut -d '=' -f 1) |
| 30 | + value=$(echo "$line" | cut -d '=' -f 2 | sed 's/^"//;s/"$//') |
| 31 | + export "$name"="$value" |
| 32 | +done <<< "$output" |
| 33 | + |
| 34 | +if [ "$AZURE_USE_EASY_AUTH" = "true" ]; then |
| 35 | + echo "Enabling EasyAuth for the AKS Cluster" |
| 36 | + echo "If you want to disable EasyAuth, please set the AZURE_USE_EASY_AUTH environment variable to false" |
| 37 | +else |
| 38 | + echo "EasyAuth is not enabled for the AKS Cluster" |
| 39 | + echo "If you want to enable EasyAuth, please set the AZURE_USE_EASY_AUTH environment variable to true" |
| 40 | + exit 1 |
| 41 | +fi |
| 42 | + |
| 43 | +location=$AZURE_LOCATION |
| 44 | + |
| 45 | +adAppName="$AZURE_ENV_NAME" |
| 46 | + |
| 47 | + |
| 48 | +appHostName="$adAppName.$location.cloudapp.azure.com" |
| 49 | + |
| 50 | +# Set these variables |
| 51 | +homePage="https://$appHostName" |
| 52 | +replyUrls="https://$appHostName/easyauth/signin-oidc" |
| 53 | +tlsSecretName="$appHostName-tls" |
| 54 | + |
| 55 | +clusterName=$AZURE_AKS_CLUSTER_NAME |
| 56 | +clusterRG=$AZURE_RESOURCE_GROUP |
| 57 | + |
| 58 | +echo "Configure DNS for cluster Public IP using $appHostName" |
| 59 | + |
| 60 | +# Get the AKS MC_ resource group name |
| 61 | +nodeRG=$(az aks show -n $clusterName -g $clusterRG -o json | jq -r '.nodeResourceGroup') |
| 62 | +echo "AKS Cluster is in resource group: $nodeRG" |
| 63 | + |
| 64 | +ingressIP=$(kubectl get ingress ingress-api -n azure-open-ai -o jsonpath="{.status.loadBalancer.ingress[0].ip}") |
| 65 | + |
| 66 | +if [ -z "$ingressIP" ]; then |
| 67 | + echo "Please retry once Ingress Address is assigned to the AKS Cluster" |
| 68 | + exit 1 |
| 69 | +fi |
| 70 | + |
| 71 | +echo "Found Ingress IP: $ingressIP" |
| 72 | + |
| 73 | +# List public IP resources in the specified resource group |
| 74 | +ipName=$(az network public-ip list -g $nodeRG -o json | jq -c ".[] | select(.ipAddress | contains(\"$ingressIP\"))" | jq '.name' -r) |
| 75 | +echo "Public-ip IP Name within RG is: $ipName" |
| 76 | + |
| 77 | +# Add a DNS name ($adAppName) to the public IP address |
| 78 | +echo "Adding DNS name to public IP address" |
| 79 | +az network public-ip update -g $nodeRG -n $ipName --dns-name $adAppName |
| 80 | + |
| 81 | +# Get the FQDN assigned to the public IP address |
| 82 | +ingressHost=$(az network public-ip show -g $nodeRG -n $ipName -o json | jq -r '.dnsSettings.fqdn') |
| 83 | +echo "FQDN assigned to the public IP address: $ingressHost" |
| 84 | +if [ "$ingressHost" != "$appHostName" ]; then |
| 85 | + echo "FQDN assigned to the public IP address does not match the expected value: $appHostName" |
| 86 | + exit 1 |
| 87 | +fi |
| 88 | +# --------------------- |
| 89 | +# Register AAD Application |
| 90 | +echo "Creating Azure AD Application" |
| 91 | +appCreationResult=$(az ad app create --display-name $adAppName --web-home-page-url "$homePage" --web-redirect-uris "$replyUrls" --required-resource-accesses '@easyauth/manifest.json' -o json) |
| 92 | +appId=$(echo $appCreationResult | jq -r '.appId') |
| 93 | +echo "Created Azure AD application with appId: $appId" |
| 94 | + |
| 95 | +# Reset credentials for the Azure AD application to generate a new password |
| 96 | +echo "Resetting credentials for the Azure AD application" |
| 97 | +credentialResetResult=$(az ad app credential reset --id $appId -o json) |
| 98 | +clientSecret=$(echo $credentialResetResult | jq -r '.password') |
| 99 | +echo "Generated new client secret: $clientSecret" |
| 100 | + |
| 101 | +# Retrieve and output the Azure AD tenant ID |
| 102 | +tenantInfo=$(az account show -o json) |
| 103 | +azureTenantId=$(echo $tenantInfo | jq -r '.tenantId') |
| 104 | +echo "Retrieved Azure AD tenant ID: $azureTenantId" |
| 105 | + |
| 106 | +# --------------------- |
| 107 | +# Install Cert Manager |
| 108 | +# Create the namespace |
| 109 | +kubectl create namespace cert-manager |
| 110 | + |
| 111 | +# Add the Jetstack Helm repository |
| 112 | +helm repo add jetstack https://charts.jetstack.io |
| 113 | + |
| 114 | +# Update your local Helm chart repository cache |
| 115 | +helm repo update |
| 116 | + |
| 117 | +# Label the namespace |
| 118 | +kubectl label namespace cert-manager cert-manager.io/disable-validation=true |
| 119 | + |
| 120 | +# Install the cert manager |
| 121 | +helm install cert-manager jetstack/cert-manager \ |
| 122 | + --namespace cert-manager \ |
| 123 | + --version v1.14.2 \ |
| 124 | + --set installCRDs=true \ |
| 125 | + --set ingressShim.defaultIssuerName=letsencrypt \ |
| 126 | + --set ingressShim.defaultIssuerKind=ClusterIssuer |
| 127 | + |
| 128 | +# Check the installed pods in cert-manager namespace |
| 129 | +kubectl get pods -n cert-manager |
| 130 | + |
| 131 | +# Deploy the issuer config to the cluster |
| 132 | +kubectl apply -f ./easyauth/cluster-issuer.yaml |
| 133 | + |
| 134 | +# --------------------- |
| 135 | +# Deploy Easy Auth Proxy |
| 136 | +helm install --set azureAd.tenantId="$azureTenantId" --set azureAd.clientId="$appId" --set secret.name="easyauth-proxy-$adAppName-secret" --set secret.azureclientsecret="$clientSecret" --set appHostName="$appHostName" --set tlsSecretName="$tlsSecretName" easyauth-proxy ./easyauth/easyauth-proxy |
| 137 | + |
| 138 | +# --------------------- |
| 139 | +# Apply proxy ingress rules |
| 140 | + |
| 141 | +# Creating the easyauth-ingress.yaml content |
| 142 | +cat << EOF > ./easyauth/easyauth-ingress.yaml |
| 143 | +apiVersion: networking.k8s.io/v1 |
| 144 | +kind: Ingress |
| 145 | +metadata: |
| 146 | + name: easyauth-ingress-router |
| 147 | + annotations: |
| 148 | + nginx.ingress.kubernetes.io/auth-url: "https://\$host/easyauth/auth" |
| 149 | + nginx.ingress.kubernetes.io/auth-signin: "https://\$host/easyauth/login" |
| 150 | + nginx.ingress.kubernetes.io/auth-response-headers: "x-injected-userinfo,x-injected-name,x-injected-oid,x-injected-preferred-username,x-injected-sub,x-injected-tid,x-injected-email,x-injected-groups,x-injected-scp,x-injected-roles,x-injected-graph" |
| 151 | + cert-manager.io/cluster-issuer: letsencrypt |
| 152 | +spec: |
| 153 | + ingressClassName: webapprouting.kubernetes.azure.com |
| 154 | + tls: |
| 155 | + - hosts: |
| 156 | + - \${appHostName} |
| 157 | + secretName: \${tlsSecretName} |
| 158 | + rules: |
| 159 | + - host: \${appHostName} |
| 160 | + http: |
| 161 | + paths: |
| 162 | + - path: /api |
| 163 | + pathType: Prefix |
| 164 | + backend: |
| 165 | + service: |
| 166 | + name: backend-service |
| 167 | + port: |
| 168 | + number: 80 |
| 169 | + - path: / |
| 170 | + pathType: Prefix |
| 171 | + backend: |
| 172 | + service: |
| 173 | + name: frontend-service |
| 174 | + port: |
| 175 | + number: 80 |
| 176 | +EOF |
| 177 | + |
| 178 | +# Deploy the ingress configuration to the cluster |
| 179 | +kubectl apply -f ./easyauth/easyauth-ingress.yaml |
| 180 | + |
| 181 | +# Remove old ingress without auth |
| 182 | +kubectl delete ingress ingress-api -n 'azure-open-ai' |
| 183 | + |
| 184 | +# Update environment variables (This part needs to be adapted based on how you manage env vars in your setup) |
| 185 | +# For a simple script, you could just export them, but they'd be session-specific. |
| 186 | +export AZURE_AD_APP_NAME="$adAppName" |
| 187 | +export AZURE_AD_APP_ID="$appId" |
| 188 | + |
| 189 | +# Print Easy Auth Config Information |
| 190 | +echo "EasyAuth for AKS has been configured successfully. |
| 191 | +
|
| 192 | +The application is now available at: ${homePage} |
| 193 | +
|
| 194 | +Configuration AD details: |
| 195 | +- App Host Name: $appHostName |
| 196 | +- Azure AD Application: $adAppName |
| 197 | +- Azure AD Application ID / Client ID: $appId |
| 198 | +- Azure AD Tenant ID: $azureTenantId |
| 199 | +- Client Secret: $clientSecret |
| 200 | +
|
| 201 | +Configuration AKS details: |
| 202 | +- AKS Cluster: $clusterName |
| 203 | +- Ingress IP: $ingressIP |
| 204 | +- Public IP Name: $ipName |
| 205 | +- Public AKS Resource Group: $nodeRG |
| 206 | +" |
0 commit comments