How to Install an Application Gateway Ingress Controller (AGIC) Using a New Application Gateway

The instructions below assume Application Gateway Ingress Controller (AGIC) will be installed in an environment with no pre-existing components.

Required Command Line Tools

We recommend the use of Azure Cloud Shell for all command-line operations below. Launch your shell from shell.azure.com or by clicking the link:

Embed launch

Alternatively, launch Cloud Shell from Azure portal using the following icon:

Portal launch

Your Azure Cloud Shell already has all necessary tools. If you choose to use another environment, ensure the following command-line tools are installed:

Create an Identity

Follow the steps below to create an Azure Active Directory (Azure AD) service principal object. Record the appId, password, and objectId values - these values will be used in the following steps.

  1. Create AD service principal (Read more about Azure RBAC):

    az ad sp create-for-rbac --role Contributor --scopes /subscriptions/mySubscriptionID -o json > auth.json
    appId=$(jq -r ".appId" auth.json)
    password=$(jq -r ".password" auth.json)
    

    The appId and password values from the JSON output will be used in the following steps

  2. Use the appId from the previous command's output to get the id of the new service principal:

    objectId=$(az ad sp show --id $appId --query "id" -o tsv)
    

    The output of this command is objectId, which will be used in the Azure Resource Manager template below

  3. Create the parameter file that will be used in the Azure Resource Manager template deployment later.

    cat <<EOF > parameters.json
    {
      "aksServicePrincipalAppId": { "value": "$appId" },
      "aksServicePrincipalClientSecret": { "value": "$password" },
      "aksServicePrincipalObjectId": { "value": "$objectId" },
      "aksEnableRBAC": { "value": false }
    }
    EOF
    

    To deploy an Kubernetes RBAC enabled cluster, set the aksEnableRBAC field to true

Deploy Components

This step will add the following components to your subscription:

  1. Download the Azure Resource Manager template and modify the template as needed.

    wget https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/deploy/azuredeploy.json -O template.json
    
  2. Deploy the Azure Resource Manager template using the Azure CLI. The deployment might take up to 5 minutes.

    resourceGroupName="MyResourceGroup"
    location="westus2"
    deploymentName="ingress-appgw"
    
    # create a resource group
    az group create -n $resourceGroupName -l $location
    
    # modify the template as needed
    az deployment group create \
            -g $resourceGroupName \
            -n $deploymentName \
            --template-file template.json \
            --parameters parameters.json
    
  3. Once the deployment finished, download the deployment output into a file named deployment-outputs.json.

    az deployment group show -g $resourceGroupName -n $deploymentName --query "properties.outputs" -o json > deployment-outputs.json
    

Set up Application Gateway Ingress Controller

With the instructions in the previous section, we created and configured a new AKS cluster and an Application Gateway. We're now ready to deploy a sample app and an ingress controller to our new Kubernetes infrastructure.

Setup Kubernetes Credentials

For the following steps, we need setup kubectl command, which we'll use to connect to our new Kubernetes cluster. Cloud Shell has kubectl already installed. We'll use az CLI to obtain credentials for Kubernetes.

Get credentials for your newly deployed AKS (read more):

# use the deployment-outputs.json created after deployment to get the cluster name and resource group name
aksClusterName=$(jq -r ".aksClusterName.value" deployment-outputs.json)
resourceGroupName=$(jq -r ".resourceGroupName.value" deployment-outputs.json)

az aks get-credentials --resource-group $resourceGroupName --name $aksClusterName

Install Azure AD Pod Identity

Azure Active Directory Pod Identity provides token-based access to Azure Resource Manager (ARM).

Azure AD Pod Identity will add the following components to your Kubernetes cluster:

To install Azure AD Pod Identity to your cluster:

  • Kubernetes RBAC enabled AKS cluster

    kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
    
  • Kubernetes RBAC disabled AKS cluster

    kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment.yaml
    

Install Helm

Helm is a package manager for Kubernetes. We'll use it to install the application-gateway-kubernetes-ingress package:

  1. Install Helm and run the following to add application-gateway-kubernetes-ingress helm package:

    • Kubernetes RBAC enabled AKS cluster

      kubectl create serviceaccount --namespace kube-system tiller-sa
      kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller-sa
      helm init --tiller-namespace kube-system --service-account tiller-sa
      
    • Kubernetes RBAC disabled AKS cluster

      helm init
      
  2. Add the AGIC Helm repository:

    helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
    helm repo update
    

Install Ingress Controller Helm Chart

  1. Use the deployment-outputs.json file created above and create the following variables.

    applicationGatewayName=$(jq -r ".applicationGatewayName.value" deployment-outputs.json)
    resourceGroupName=$(jq -r ".resourceGroupName.value" deployment-outputs.json)
    subscriptionId=$(jq -r ".subscriptionId.value" deployment-outputs.json)
    identityClientId=$(jq -r ".identityClientId.value" deployment-outputs.json)
    identityResourceId=$(jq -r ".identityResourceId.value" deployment-outputs.json)
    
  2. Download helm-config.yaml, which will configure AGIC:

    wget https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/sample-helm-config.yaml -O helm-config.yaml
    

    Or copy the YAML file below:

    # This file contains the essential configs for the ingress controller helm chart
    
    # Verbosity level of the App Gateway Ingress Controller
    verbosityLevel: 3
    
    ################################################################################
    # Specify which application gateway the ingress controller will manage
    #
    appgw:
        subscriptionId: <subscriptionId>
        resourceGroup: <resourceGroupName>
        name: <applicationGatewayName>
    
        # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD.
        # This prohibits AGIC from applying config for any host/path.
        # Use "kubectl get AzureIngressProhibitedTargets" to view and change this.
        shared: false
    
    ################################################################################
    # Specify which kubernetes namespace the ingress controller will watch
    # Default value is "default"
    # Leaving this variable out or setting it to blank or empty string would
    # result in Ingress Controller observing all acessible namespaces.
    #
    # kubernetes:
    #   watchNamespace: <namespace>
    
    ################################################################################
    # Specify the authentication with Azure Resource Manager
    #
    # Two authentication methods are available:
    # - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity)
    armAuth:
        type: aadPodIdentity
        identityResourceID: <identityResourceId>
        identityClientID:  <identityClientId>
    
    ## Alternatively you can use Service Principal credentials
    # armAuth:
    #    type: servicePrincipal
    #    secretJSON: <<Generate this value with: "az ad sp create-for-rbac --subscription <subscription-uuid> --role Contributor --sdk-auth | base64 -w0" >>
    
    ################################################################################
    # Specify if the cluster is Kubernetes RBAC enabled or not
    rbac:
        enabled: false # true/false
    
    # Specify aks cluster related information. THIS IS BEING DEPRECATED.
    aksClusterConfiguration:
        apiServerAddress: <aks-api-server-address>
    
  3. Edit the newly downloaded helm-config.yaml and fill out the sections appgw and armAuth.

    sed -i "s|<subscriptionId>|${subscriptionId}|g" helm-config.yaml
    sed -i "s|<resourceGroupName>|${resourceGroupName}|g" helm-config.yaml
    sed -i "s|<applicationGatewayName>|${applicationGatewayName}|g" helm-config.yaml
    sed -i "s|<identityResourceId>|${identityResourceId}|g" helm-config.yaml
    sed -i "s|<identityClientId>|${identityClientId}|g" helm-config.yaml
    
    # You can further modify the helm config to enable/disable features
    nano helm-config.yaml
    

    Note

    For deploying to Sovereign Clouds (e.g., Azure Government), the appgw.environment configuration parameter must be added and set to the appropriate value as documented below.

    Values:

    • verbosityLevel: Sets the verbosity level of the AGIC logging infrastructure. See Logging Levels for possible values.
    • appgw.environment: Sets cloud environment. Possbile values: AZURECHINACLOUD, AZUREGERMANCLOUD, AZUREPUBLICCLOUD, AZUREUSGOVERNMENTCLOUD
    • appgw.subscriptionId: The Azure Subscription ID in which Application Gateway resides. Example: a123b234-a3b4-557d-b2df-a0bc12de1234
    • appgw.resourceGroup: Name of the Azure Resource Group in which Application Gateway was created. Example: app-gw-resource-group
    • appgw.name: Name of the Application Gateway. Example: applicationgatewayd0f0
    • appgw.shared: This boolean flag should be defaulted to false. Set to true should you need a Shared Application Gateway.
    • kubernetes.watchNamespace: Specify the namespace that AGIC should watch. The namespace value can be a single string value, or a comma-separated list of namespaces.
    • armAuth.type: could be aadPodIdentity or servicePrincipal
    • armAuth.identityResourceID: Resource ID of the Azure Managed Identity
    • armAuth.identityClientID: The Client ID of the Identity. More information about identityClientID is provided below.
    • armAuth.secretJSON: Only needed when Service Principal Secret type is chosen (when armAuth.type has been set to servicePrincipal)

    Note

    The identityResourceID and identityClientID are values that were created during the Deploy Components steps, and could be obtained again using the following command:

    az identity show -g <resource-group> -n <identity-name>
    

    <resource-group> in the command above is the resource group of your Application Gateway. <identity-name> is the name of the created identity. All identities for a given subscription can be listed using: az identity list

  4. Install the Application Gateway ingress controller package:

    helm install -f helm-config.yaml --generate-name application-gateway-kubernetes-ingress/ingress-azure
    

Install a Sample App

Now that we have Application Gateway, AKS, and AGIC installed we can install a sample app via Azure Cloud Shell:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: aspnetapp
  labels:
    app: aspnetapp
spec:
  containers:
  - image: "mcr.microsoft.com/dotnet/samples:aspnetapp"
    name: aspnetapp-image
    ports:
    - containerPort: 80
      protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: aspnetapp
spec:
  selector:
    app: aspnetapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aspnetapp
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          service:
            name: aspnetapp
            port:
              number: 80
        pathType: Exact
EOF

Alternatively you can:

  • Download the YAML file above:
curl https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/aspnetapp.yaml -o aspnetapp.yaml
  • Apply the YAML file:
kubectl apply -f aspnetapp.yaml

Other Examples

This how-to guide contains more examples on how to expose an AKS service via HTTP or HTTPS, to the Internet with Application Gateway.