Secure your cluster with Azure Policy
To improve the security of your Azure Kubernetes Service (AKS) cluster, you can apply and enforce built-in security policies on your cluster using Azure Policy. Azure Policy helps to enforce organizational standards and to assess compliance at-scale. After installing the Azure Policy Add-on for AKS, you can apply individual policy definitions or groups of policy definitions called initiatives (sometimes called policysets) to your cluster. See Azure Policy built-in definitions for AKS for a complete list of AKS policy and initiative definitions.
This article shows you how to apply policy definitions to your cluster and verify those assignments are being enforced.
Prerequisites
- This article assumes that you have an existing AKS cluster. If you need an AKS cluster, see the AKS quickstart using the Azure CLI, using Azure PowerShell, or using the Azure portal.
- The Azure Policy Add-on for AKS installed on an AKS cluster. Follow these steps to install the Azure Policy Add-on.
Assign a built-in policy definition or initiative
To apply a policy definition or initiative, use the Azure portal.
- Navigate to the Azure Policy service in Azure portal.
- In the left pane of the Azure Policy page, select Definitions.
- Under Categories select
Kubernetes
. - Choose the policy definition or initiative you want to apply. For this example, select the
Kubernetes cluster pod security baseline standards for Linux-based workloads
initiative. - Select Assign.
- Set the Scope to the resource group of the AKS cluster with the Azure Policy Add-on enabled.
- Select the Parameters page and update the Effect from
audit
todeny
to block new deployments violating the baseline initiative. You can also add additional namespaces to exclude from evaluation. For this example, keep the default values. - Select Review + create then Create to submit the policy assignment.
Create and assign a custom policy definition
Custom policies allow you to define rules for using Azure. For example, you can enforce:
- Security practices
- Cost management
- Organization-specific rules (like naming or locations)
Before creating a custom policy, check the list of common patterns and samples to see if your case is already covered.
Custom policy definitions are written in JSON. To learn more about creating a custom policy, see Azure Policy definition structure and Create a custom policy definition.
Note
Azure Policy now utilizes a new property known as templateInfo that allows users to define the source type for the constraint template. By defining templateInfo in policy definitions, users don’t have to define constraintTemplate or constraint properties. Users still need to define apiGroups and kinds. For more information on this, see Understanding Azure Policy effects.
Once your custom policy definition has been created, see Assign a policy definition for a step-by-step walkthrough of assigning the policy to your Kubernetes cluster.
Validate a Azure Policy is running
Confirm the policy assignments are applied to your cluster by running the following:
kubectl get constrainttemplates
Note
Policy assignments can take up to 20 minutes to sync into each cluster.
The output should be similar to:
$ kubectl get constrainttemplate
NAME AGE
k8sazureallowedcapabilities 23m
k8sazureallowedusersgroups 23m
k8sazureblockhostnamespace 23m
k8sazurecontainerallowedimages 23m
k8sazurecontainerallowedports 23m
k8sazurecontainerlimits 23m
k8sazurecontainernoprivilege 23m
k8sazurecontainernoprivilegeescalation 23m
k8sazureenforceapparmor 23m
k8sazurehostfilesystem 23m
k8sazurehostnetworkingports 23m
k8sazurereadonlyrootfilesystem 23m
k8sazureserviceallowedports 23m
Validate rejection of a privileged pod
Let's first test what happens when you schedule a pod with the security context of privileged: true
. This security context escalates the pod's privileges. The initiative disallows privileged pods, so the request will be denied resulting in the deployment being rejected.
Create a file named nginx-privileged.yaml
and paste the following YAML manifest:
apiVersion: v1
kind: Pod
metadata:
name: nginx-privileged
spec:
containers:
- name: nginx-privileged
image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
securityContext:
privileged: true
Create the pod with kubectl apply command and specify the name of your YAML manifest:
kubectl apply -f nginx-privileged.yaml
As expected the pod fails to be scheduled, as shown in the following example output:
$ kubectl apply -f nginx-privileged.yaml
Error from server ([denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}): error when creating "privileged.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}
The pod doesn't reach the scheduling stage, so there are no resources to delete before you move on.
Test creation of an unprivileged pod
In the previous example, the container image automatically tried to use root to bind NGINX to port 80. This request was denied by the policy initiative, so the pod fails to start. Let's try now running that same NGINX pod without privileged access.
Create a file named nginx-unprivileged.yaml
and paste the following YAML manifest:
apiVersion: v1
kind: Pod
metadata:
name: nginx-unprivileged
spec:
containers:
- name: nginx-unprivileged
image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
Create the pod using the kubectl apply command and specify the name of your YAML manifest:
kubectl apply -f nginx-unprivileged.yaml
The pod is successfully scheduled. When you check the status of the pod using the kubectl get pods command, the pod is Running:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-unprivileged 1/1 Running 0 18s
This example shows the baseline initiative affecting only deployments which violate policies in the collection. Allowed deployments continue to function.
Delete the NGINX unprivileged pod using the kubectl delete command and specify the name of your YAML manifest:
kubectl delete -f nginx-unprivileged.yaml
Disable a policy or initiative
To remove the baseline initiative:
- Navigate to the Policy pane on the Azure portal.
- Select Assignments from the left pane.
- Click the ... button next to the
Kubernetes cluster pod security baseline standards for Linux-based workloads
initiative. - Select Delete assignment.
Next steps
For more information about how Azure Policy works:
Feedback
Submit and view feedback for