|
| 1 | +# Example AKS cluster |
| 2 | + |
| 3 | + |
| 4 | +# Example AKS cluster after deploying EasyAuthForK8s |
| 5 | + |
| 6 | + |
| 7 | +## Set Variables |
| 8 | + |
| 9 | +Review these very carefully and modify. |
| 10 | + |
| 11 | + # Set your backend service variables |
| 12 | + SERVICE=<insert name of K8s service you want to redirect to after login> |
| 13 | + SERVICE_PORT=<insert service port of the K8s service you want to redirect to after login> |
| 14 | + |
| 15 | + # Important! Set the name for your Azure AD App Registration |
| 16 | + AD_APP_NAME="$USER-easy-auth-proxy" |
| 17 | + |
| 18 | + # Set the email address for the cluster certificate issuer (**SKIP** this step if you've already deployed a cert-manager) |
| 19 | + |
| 20 | + |
| 21 | + # Region your resources are located in |
| 22 | + LOCATION=<insert existing cluster location> |
| 23 | + |
| 24 | + # Set APP_HOSTNAME to your existing cluster's hostname |
| 25 | + APP_HOSTNAME="<insert existing hostname>" # Note: Keep the quotation marks "" |
| 26 | + |
| 27 | + # Note: If you don't have an existing hostname, use the one below |
| 28 | + APP_HOSTNAME="$AD_APP_NAME.$LOCATION.cloudapp.azure.com" |
| 29 | + |
| 30 | + # Set these variables |
| 31 | + HOMEPAGE=https://$APP_HOSTNAME |
| 32 | + REPLY_URLS=https://$APP_HOSTNAME/easyauth/signin-oidc |
| 33 | + |
| 34 | + # Set the secret name |
| 35 | + TLS_SECRET_NAME=<insert your existing secret-tls name> |
| 36 | + |
| 37 | + # To get the secret name of an existing cert, run the following command |
| 38 | + kubectl get certificates |
| 39 | + |
| 40 | + # If you do not have a secret, set it below |
| 41 | + TLS_SECRET_NAME=$APP_HOSTNAME-tls |
| 42 | + |
| 43 | +## Configure DNS for the cluster public IP (*SKIP* this step if you've already used a FQDN with HTTPS in your cluster) |
| 44 | +To use AAD authentication for your application, you must use a FQDN with HTTPS. For this tutorial, we will add a DNS record to the Ingress Public IP address. |
| 45 | + |
| 46 | +``` |
| 47 | +# Get the AKS MC_ resource group name |
| 48 | +NODE_RG=$(az aks show -n $CLUSTER_NAME -g $CLUSTER_RG -o json | jq -r '.nodeResourceGroup') |
| 49 | +echo $NODE_RG |
| 50 | +
|
| 51 | +INGRESS_IP=$(kubectl get services/nginx-ingress-ingress-nginx-controller -n ingress-controllers -o jsonpath="{.status.loadBalancer.ingress[0].ip}") |
| 52 | +echo $INGRESS_IP |
| 53 | +
|
| 54 | +IP_NAME=$(az network public-ip list -g $NODE_RG -o json | jq -c ".[] | select(.ipAddress | contains(\"$INGRESS_IP\"))" | jq '.name' -r) |
| 55 | +echo $IP_NAME |
| 56 | +
|
| 57 | +# Add a DNS name ($AD_APP_NAME) to the public IP address |
| 58 | +az network public-ip update -g $NODE_RG -n $IP_NAME --dns-name $AD_APP_NAME |
| 59 | +
|
| 60 | +# Get the FQDN assigned to the public IP address |
| 61 | +INGRESS_HOST=$(az network public-ip show -g $NODE_RG -n $IP_NAME -o json | jq -r '.dnsSettings.fqdn') |
| 62 | +echo $INGRESS_HOST |
| 63 | +# This should be the same as the $APP_HOSTNAME |
| 64 | +``` |
| 65 | + |
| 66 | +## Register AAD Application |
| 67 | + |
| 68 | +``` |
| 69 | +# The default app created has permissions we don't need and can cause problem if you are in a more restricted tenant environment |
| 70 | +# Copy/paste the entire snippet BELOW (and then press ENTER) to create the manifest.json file |
| 71 | +cat << EOF > manifest.json |
| 72 | +[ |
| 73 | + { |
| 74 | + "resourceAccess" : [ |
| 75 | + { |
| 76 | + "id" : "e1fe6dd8-ba31-4d61-89e7-88639da4683d", |
| 77 | + "type" : "Scope" |
| 78 | + } |
| 79 | + ], |
| 80 | + "resourceAppId" : "00000003-0000-0000-c000-000000000000" |
| 81 | + } |
| 82 | +] |
| 83 | +EOF |
| 84 | +# End of snippet to copy/paste |
| 85 | +
|
| 86 | +# Important! Review the file and check the values. |
| 87 | +cat manifest.json |
| 88 | +
|
| 89 | +# Create the Azure AD SP for our application and save the Client ID to a variable |
| 90 | +CLIENT_ID=$(az ad app create --display-name $AD_APP_NAME --homepage $HOMEPAGE --reply-urls $REPLY_URLS --required-resource-accesses @manifest.json -o json | jq -r '.appId') |
| 91 | +echo $CLIENT_ID |
| 92 | +
|
| 93 | +OBJECT_ID=$(az ad app show --id $CLIENT_ID -o json | jq '.objectId' -r) |
| 94 | +echo $OBJECT_ID |
| 95 | +
|
| 96 | +az ad app update --id $OBJECT_ID --set oauth2Permissions[0].isEnabled=false |
| 97 | +az ad app update --id $OBJECT_ID --set oauth2Permissions=[] |
| 98 | +
|
| 99 | +# The newly registered app does not have a password. Use "az ad app credential reset" to add password and save to a variable. |
| 100 | +CLIENT_SECRET=$(az ad app credential reset --id $CLIENT_ID -o json | jq '.password' -r) |
| 101 | +echo $CLIENT_SECRET |
| 102 | +
|
| 103 | +# Get your Azure AD tenant ID and save to variable |
| 104 | +AZURE_TENANT_ID=$(az account show -o json | jq '.tenantId' -r) |
| 105 | +echo $AZURE_TENANT_ID |
| 106 | +``` |
| 107 | + |
| 108 | +## Install Cert Manager (**SKIP** this step if you've already deployed a cert-manager) |
| 109 | + |
| 110 | +We will use Cert-Manager to create and install SSL Certs from Let'sEncrypt onto our K8S Cluster. This is because AAD requires all endpoints be either [localhost](http://localhost) or HTTPS. |
| 111 | + |
| 112 | +Inspired by [https://docs.microsoft.com/en-us/azure/aks/ingress-tls](https://docs.microsoft.com/en-us/azure/aks/ingress-tls). |
| 113 | + |
| 114 | +### Deploy Production Cert Manager |
| 115 | + |
| 116 | +``` |
| 117 | +# Create the namespace |
| 118 | +kubectl create namespace cert-manager |
| 119 | +
|
| 120 | +# Add the Jetstack Helm repository |
| 121 | +helm repo add jetstack https://charts.jetstack.io |
| 122 | +
|
| 123 | +# Update your local Helm chart repository cache |
| 124 | +helm repo update |
| 125 | +
|
| 126 | +# Install the cert manager |
| 127 | +helm install \ |
| 128 | + cert-manager jetstack/cert-manager \ |
| 129 | + --namespace cert-manager \ |
| 130 | + --version v1.3.1 \ |
| 131 | + --set installCRDs=true \ |
| 132 | + --set ingressShim.defaultIssuerName=letsencrypt-prod \ |
| 133 | + --set ingressShim.defaultIssuerKind=ClusterIssuer |
| 134 | +
|
| 135 | +# Make sure the cert-manager pods have started BEFORE proceeding. It can take 2-3 min for the cert-manager-webhook container to start up |
| 136 | +kubectl get pods -n cert-manager |
| 137 | +
|
| 138 | +# Copy/paste the entire snippet BELOW (and then press ENTER) to create the cluster-issuer-prod.yaml file |
| 139 | +cat << EOF > ./cluster-issuer-prod.yaml |
| 140 | +apiVersion: cert-manager.io/v1 |
| 141 | +kind: ClusterIssuer |
| 142 | +metadata: |
| 143 | + name: letsencrypt-prod |
| 144 | + namespace: cert-manager |
| 145 | +spec: |
| 146 | + acme: |
| 147 | + server: https://acme-v02.api.letsencrypt.org/directory |
| 148 | + email: $EMAIL |
| 149 | + privateKeySecretRef: |
| 150 | + name: letsencrypt-prod |
| 151 | + # Add a single challenge solver, HTTP01 using nginx |
| 152 | + solvers: |
| 153 | + - http01: |
| 154 | + ingress: |
| 155 | + class: nginx |
| 156 | + podTemplate: |
| 157 | + spec: |
| 158 | + nodeSelector: |
| 159 | + "kubernetes.io/os": linux |
| 160 | +EOF |
| 161 | +# End of snippet to copy/paste |
| 162 | +
|
| 163 | +# Important! Review the file and check the values. |
| 164 | +cat ./cluster-issuer-prod.yaml |
| 165 | +
|
| 166 | +# Deploy the issuer config to the cluster |
| 167 | +kubectl apply -f ./cluster-issuer-prod.yaml |
| 168 | +``` |
| 169 | + |
| 170 | +## Deploy Easy Auth Proxy |
| 171 | + |
| 172 | +``` |
| 173 | +# Go to the root of the repo before running this command |
| 174 | +helm install --set azureAd.tenantId=$AZURE_TENANT_ID --set azureAd.clientId=$CLIENT_ID --set secret.name=easyauth-proxy-$AD_APP_NAME-secret --set secret.azureclientsecret=$CLIENT_SECRET --set appHostName=$APP_HOSTNAME --set tlsSecretName=$TLS_SECRET_NAME easyauth-proxy-$AD_APP_NAME ./charts/easyauth-proxy |
| 175 | +
|
| 176 | +# Confirm everything was deployed. |
| 177 | +kubectl get svc,deploy,pod |
| 178 | +``` |
| 179 | + |
| 180 | +## Apply proxy ingress rules |
| 181 | + |
| 182 | +In this last step, we will apply an ingress rule that redirects all traffic to our Easy Auth proxy. This rule will require all your users to login before being able to access the application. For more examples, please see sample-ingress.yaml in root > sample > templates > sample-ingress.yaml |
| 183 | + |
| 184 | +Note: You may need to remove a previous ingress rule that contains the same path and pathType. |
| 185 | + |
| 186 | +``` |
| 187 | +cat << EOF > ./easyauth-ingress.yaml |
| 188 | +apiVersion: networking.k8s.io/v1 |
| 189 | +kind: Ingress |
| 190 | +metadata: |
| 191 | + name: easyauth-ingress-default |
| 192 | + annotations: |
| 193 | + nginx.ingress.kubernetes.io/auth-url: "https://\$host/easyauth/auth" |
| 194 | + nginx.ingress.kubernetes.io/auth-signin: "https://\$host/easyauth/login" |
| 195 | + 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" |
| 196 | + cert-manager.io/cluster-issuer: letsencrypt-prod |
| 197 | + #nginx.ingress.kubernetes.io/rewrite-target: /\$1 |
| 198 | +spec: |
| 199 | + ingressClassName: nginx |
| 200 | + tls: |
| 201 | + - hosts: |
| 202 | + - $APP_HOSTNAME |
| 203 | + secretName: $TLS_SECRET_NAME |
| 204 | + rules: |
| 205 | + - host: $APP_HOSTNAME |
| 206 | + http: |
| 207 | + paths: |
| 208 | + - path: / |
| 209 | + pathType: Prefix |
| 210 | + backend: |
| 211 | + service: |
| 212 | + name: $SERVICE |
| 213 | + port: |
| 214 | + number: $SERVICE_PORT |
| 215 | +EOF |
| 216 | +
|
| 217 | +# Important! Review the file and check the values. |
| 218 | +cat ./easyauth-ingress.yaml |
| 219 | +
|
| 220 | +# Deploy the issuer config to the cluster |
| 221 | +kubectl apply -f ./easyauth-ingress.yaml |
| 222 | +``` |
| 223 | + |
| 224 | +## Verify application works in browser |
| 225 | +NOTE: Wait 5 minutes for the easy auth proxy and Azure AD to get up and running. |
| 226 | + |
| 227 | +Open your homepage in the browser. You now have Easy Auth applied to your application! |
| 228 | + |
| 229 | +To apply more advanced scenarios to your existing cluster (RBAC, Graph Query, Anonymous, etc), please see sample-ingress.yaml in root > sample > templates > sample-ingress.yaml for examples |
0 commit comments