Set up a custom domain name and SSL certificate with the application routing add-on
An Ingress is an API object that defines rules, which allow external access to services in an Azure Kubernetes Service (AKS) cluster. When you create an Ingress object that uses the application routing add-on nginx Ingress classes, the add-on creates, configures, and manages one or more Ingress controllers in your AKS cluster.
This article shows you how to set up an advanced Ingress configuration to encrypt the traffic with SSL/TLS certificates stored in an Azure Key Vault, and use Azure DNS to manage DNS zones.
Application routing add-on with nginx features
The application routing add-on with nginx delivers the following:
- Easy configuration of managed nginx Ingress controllers.
- Integration with an external DNS such as Azure DNS for global and private zone management
- SSL termination with certificates stored in a key vault, such as Azure Key Vault.
Prerequisites
- An AKS cluster with the application routing add-on.
- Azure Key Vault if you want to configure SSL termination and store certificates in the vault hosted in Azure.
- Azure DNS if you want to configure global and private zone management and host them in Azure.
- To attach an Azure Key Vault or Azure DNS Zone, you need the Owner, Azure account administrator, or Azure co-administrator role on your Azure subscription.
- All public DNS Zones must be in the same subscription and Resource Group.
Connect to your AKS cluster
To connect to the Kubernetes cluster from your local computer, you use kubectl
, the Kubernetes command-line client. You can install it locally using the az aks install-cli command.
Configure kubectl to connect to your Kubernetes cluster using the az aks get-credentials
command.
az aks get-credentials --resource-group <ResourceGroupName> --name <ClusterName>
Terminate HTTPS traffic with certificates from Azure Key Vault
To enable support for HTTPS traffic, see the following prerequisites:
- An SSL certificate. If you don't have one, you can create a certificate.
Create an Azure Key Vault to store the certificate
Note
If you already have an Azure Key Vault, you can skip this step.
Create an Azure Key Vault using the az keyvault create
command.
az keyvault create --resource-group <ResourceGroupName> --location <Location> --name <KeyVaultName> --enable-rbac-authorization true
Create and export a self-signed SSL certificate
Note
If you already have a certificate, you can skip this step.
Create a self-signed SSL certificate to use with the Ingress using the
openssl req
command. Make sure you replace<Hostname>
with the DNS name you're using.openssl req -new -x509 -nodes -out aks-ingress-tls.crt -keyout aks-ingress-tls.key -subj "/CN=<Hostname>" -addext "subjectAltName=DNS:<Hostname>"
Export the SSL certificate and skip the password prompt using the
openssl pkcs12 -export
command.openssl pkcs12 -export -in aks-ingress-tls.crt -inkey aks-ingress-tls.key -out aks-ingress-tls.pfx
Import certificate into Azure Key Vault
Import the SSL certificate into Azure Key Vault using the az keyvault certificate import
command. If your certificate is password protected, you can pass the password through the --password
flag.
az keyvault certificate import --vault-name <KeyVaultName> --name <KeyVaultCertificateName> --file aks-ingress-tls.pfx [--password <certificate password if specified>]
Important
To enable the add-on to reload certificates from Azure Key Vault when they change, you should to enable the secret autorotation feature of the Secret Store CSI driver with the --enable-secret-rotation
argument. When autorotation is enabled, the driver updates the pod mount and the Kubernetes secret by polling for changes periodically, based on the rotation poll interval you define. The default rotation poll interval is two minutes.
Enable Azure Key Vault integration
On a cluster with the application routing add-on enabled, use the az aks approuting update
command using the --enable-kv
and --attach-kv
arguments to enable the Azure Key Vault provider for Secrets Store CSI Driver and apply the required role assignments.
Azure Key Vault offers two authorization systems: Azure role-based access control (Azure RBAC), which operates on the management plane, and the access policy model, which operates on both the management plane and the data plane. The --attach-kv
operation will choose the appropriate access model to use.
Note
The az aks approuting update --attach-kv
command uses the permissions of the user running the command to create the Azure Key Vault role assignment. This role is assigned to the add-on's managed identity. For more information on AKS managed identities, see Summary of managed identities.
Retrieve the Azure Key Vault resource ID.
KEYVAULTID=$(az keyvault show --name <KeyVaultName> --query "id" --output tsv)
Then update the app routing add-on to enable the Azure Key Vault secret store CSI driver and apply the role assignment.
az aks approuting update --resource-group <ResourceGroupName> --name <ClusterName> --enable-kv --attach-kv ${KEYVAULTID}
Enable Azure DNS integration
To enable support for DNS zones, review the following prerequisite:
- The app routing add-on can be configured to automatically create records on one or more Azure global and private DNS zones for hosts defined on Ingress resources. All global Azure DNS zones need to be in the same resource group, and all private Azure DNS zones need to be in the same resource group. If you don't have an Azure DNS zone, you can create one.
Create a public Azure DNS zone
Note
If you already have an Azure DNS Zone, you can skip this step.
Create an Azure DNS zone using the
az network dns zone create
command.az network dns zone create --resource-group <ResourceGroupName> --name <ZoneName>
Attach Azure DNS zone to the application routing add-on
Note
The az aks approuting zone add
command uses the permissions of the user running the command to create the Azure DNS Zone role assignment. This role is assigned to the add-on's managed identity. For more information on AKS managed identities, see Summary of managed identities.
Retrieve the resource ID for the DNS zone using the
az network dns zone show
command and set the output to a variable named ZONEID.ZONEID=$(az network dns zone show --resource-group <ResourceGroupName> --name <ZoneName> --query "id" --output tsv)
Update the add-on to enable the integration with Azure DNS using the
az aks approuting zone
command. You can pass a comma-separated list of DNS zone resource IDs.az aks approuting zone add --resource-group <ResourceGroupName> --name <ClusterName> --ids=${ZONEID} --attach-zones
Create the Ingress that uses a host name and a certificate from Azure Key Vault
The application routing add-on creates an Ingress class on the cluster named webapprouting.kubernetes.azure.com. When you create an Ingress object with this class, it activates the add-on.
Get the certificate URI to use in the Ingress from Azure Key Vault using the
az keyvault certificate show
command.az keyvault certificate show --vault-name <KeyVaultName> --name <KeyVaultCertificateName> --query "id" --output tsv
The following example output shows the certificate URI returned from the command:
https://KeyVaultName.vault.azure.cn/certificates/KeyVaultCertificateName/ea62e42260f04f17a9309d6b87aceb44
Copy the following YAML manifest into a new file named ingress.yaml and save the file to your local computer.
Update
<Hostname>
with the name of your DNS host and<KeyVaultCertificateUri>
with the URI returned from the command to query Azure Key Vault in step 1 above. The string value for*<KeyVaultCertificateUri>*
should only includehttps://yourkeyvault.vault.azure.cn/certificates/certname
. The Certificate Version at the end of the URI string should be omitted in order to get the current version.The
secretName
key in thetls
section defines the name of the secret that contains the certificate for this Ingress resource. This certificate is presented in the browser when a client browses to the URL specified in the<Hostname>
key. Make sure that the value ofsecretName
is equal tokeyvault-
followed by the value of the Ingress resource name (frommetadata.name
). In the example YAML,secretName
needs to be equal tokeyvault-<your Ingress name>
.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.azure.com/tls-cert-keyvault-uri: <KeyVaultCertificateUri> name: aks-helloworld namespace: hello-web-app-routing spec: ingressClassName: webapprouting.kubernetes.azure.com rules: - host: <Hostname> http: paths: - backend: service: name: aks-helloworld port: number: 80 path: / pathType: Prefix tls: - hosts: - <Hostname> secretName: keyvault-<your ingress name>
Create the cluster resources using the
kubectl apply
command.kubectl apply -f ingress.yaml -n hello-web-app-routing
The following example output shows the created resource:
Ingress.networking.k8s.io/aks-helloworld created
Verify the managed Ingress was created
You can verify the managed Ingress was created using the kubectl get ingress
command.
kubectl get ingress -n hello-web-app-routing
The following example output shows the created managed Ingress:
NAME CLASS HOSTS ADDRESS PORTS AGE
aks-helloworld webapprouting.kubernetes.azure.com myapp.contoso.com 20.51.92.19 80, 443 4m