UID2 Private Operator for AKS Integration Guide
The UID2 Operator is the API server in the UID2 ecosystem. For details, see The UID2 Operator.
This guide provides information for setting up the UID2 Operator Service as a Private Operator in an Azure Kubernetes Service (AKS) cluster, running on virtual nodes on Azure Container Instances (ACI). Virtual nodes on Azure Container Instances enable us to take advantage of confidential containers, which run in a hardware-backed Trusted Execution Environment (TEE) that provides intrinsic capabilities such as data integrity, data confidentiality, and code integrity.
When the Docker container for the UID2 Operator confidential Azure Container instance starts up, it completes the attestation process that allows the UID2 Core Service to verify the authenticity of the Operator Service and of the enclave environment that the Operator Service is running in.
When the attestation is successful, the UID2 Core Service provides seed information such as salts and keys to bootstrap the UID2 Operator in the secure UID2 Operator confidential Azure Container Instance.
UID2 Private Operator for AKS is not supported in these areas: Europe, China.
Prerequisites
Before deploying the UID2 Private Operator for AKS, complete these prerequisite steps:
- Set Up the UID2 Operator Account
- Install the Azure CLI
- Get the Required Azure Permissions
- Install the kubectl CLI
- Install the Helm CLI
Set Up the UID2 Operator Account
Ask your UID2 contact to register your organization as a UID2 Operator. If you're not sure who to ask, see Contact Info.
When the registration process is complete, you'll receive an operator key, exclusive to you, that identifies you with the UID2 service as a Private Operator. During configuration, use this as the value for OPERATOR_KEY
. This value is both your unique identifier and a password; store it securely and do not share it.
You'll receive a separate operator key for each deployment environment.
Install the Azure CLI
Install the Azure command-line interface. For details, see How to install the Azure CLI in the Azure documentation.
Get the Required Azure Permissions
You'll need to have subscription owner permission so that you can create a resource group.
When that's done, you only need contributor permission on the resource group level for that resource.
For details, see Azure roles in the Azure documentation.
When all prerequisite steps are complete, you're ready to deploy the UID2 Private Operator. See Deployment.
Install the kubectl CLI
Install the Kubernetes kubectl
command-line interface. For details, see Install Tools in the Kubernetes documentation.
Install the Helm CLI
Install the helm
command-line interface. For details, see Installing Helm in the Helm documentation.
Deployment Environments
The following environments are available. As a best practice, we recommend that you test and verify your implementation in the integration environment before deploying in the production environment.
You'll receive separate {OPERATOR_KEY}
values for each environment. Be sure to use the correct key for the environment you're using. The deployment artifacts and the process flow are the same for both environments.
Environment | Details |
---|---|
Integration (integ ) | For testing only. Debug mode is available in the integration environment. |
Production (prod ) | For managing production traffic. |
Deployment
To deploy a new UID2 Private Operator for AKS, you'll need to complete the following high-level steps:
- Download ZIP File and Extract Files
- Prepare Environment Variables
- Set Up AKS and Node Pool
- Set Up AKS Cluster
- Complete Key Vault and Managed Identity Setup
- Complete the UID2 Private Operator Setup
Download ZIP File and Extract Files
To get set up with the installation files, follow these steps:
-
Ask your UID2 contact for the ZIP file containing the deployment files.
-
Download and unzip the file.
Prepare Environment Variables
Run the following commands to prepare environment variables that you'll use later. Choose variable names to suit your needs.
export RESOURCE_GROUP="my-vn-aks"
export LOCATION="eastus"
export VNET_NAME="my-vnet"
export PUBLIC_IP_ADDRESS_NAME="my-public-ip"
export NAT_GATEWAY_NAME="my-nat-gateway"
export AKS_CLUSTER_NAME="myvncluster"
export KEYVAULT_NAME="my-vn-aks-vault"
export KEYVAULT_SECRET_NAME="my-vn-aks-opr-key-name"
export MANAGED_IDENTITY="my-vn-aks-opr-id"
export AKS_NODE_RESOURCE_GROUP="MC_${RESOURCE_GROUP}_${AKS_CLUSTER_NAME}_${LOCATION}"
export SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
export DEPLOYMENT_ENV="integ"
Set Up AKS and Node Pool
To set up AKS and the node pool, complete the following steps:
- Create Resource Group
- Create Virtual Network
- Create Subnets
- Create Public IP Address
- Create NAT Gateway
- Configure NAT Service for Source Subnet
- Get the AKS Subnet ID
- Create an AKS Service
- Get the Principal ID of the Managed Identity
- Create Contributor Role for the Two Resource Groups
Create Resource Group
In Azure, run the following command to create a resource group to run the UID2 Private Operator:
az group create --name "${RESOURCE_GROUP}" --location "${LOCATION}"
All the resources are provisioned later under the name you provide as the value for ${RESOURCE_GROUP}
.
There are some limitations with regard to location:
-
UID2 Private Operator for AKS is not supported in these areas: Europe, China.
-
For Azure virtual network deployment availability, confirm the availability of regional support for Confidential Containers: check Resource availability & quota limits for ACI in the Azure documentation.
-
To get the alias for the location, run the following command:
az account list-locations -o table
Create Virtual Network
To create the virtual network, run the following command, using your own values as needed:
az network vnet create \
--resource-group ${RESOURCE_GROUP} \
--name ${VNET_NAME} \
--location ${LOCATION} \
--address-prefixes 10.0.0.0/8
Create Subnets
To create the subnets, run the following command, using your own values as needed:
# Default Subnet (10.0.0.0/24)
az network vnet subnet create \
--resource-group ${RESOURCE_GROUP} \
--vnet-name ${VNET_NAME} \
--name default \
--address-prefixes 10.0.0.0/24
# AKS Subnet (CIDR /16)
az network vnet subnet create \
--resource-group ${RESOURCE_GROUP} \
--vnet-name ${VNET_NAME} \
--name aks \
--address-prefixes 10.1.0.0/16
# Container Groups Subnet (CIDR /16) with Delegation
az network vnet subnet create \
--resource-group ${RESOURCE_GROUP} \
--vnet-name ${VNET_NAME} \
--name cg \
--address-prefixes 10.2.0.0/16 \
--delegations Microsoft.ContainerInstance/containerGroups
Create Public IP Address
To create the public IP address, run the following command, using your own values as needed:
az network public-ip create --name ${PUBLIC_IP_ADDRESS_NAME} --resource-group ${RESOURCE_GROUP} --sku standard --allocation static
Create NAT Gateway
To create the Azure Network Address Translation (NAT) gateway, run the following command, using your own values as needed:
az network nat gateway create \
--resource-group ${RESOURCE_GROUP} \
--name ${NAT_GATEWAY_NAME} \
--public-ip-addresses ${PUBLIC_IP_ADDRESS_NAME} \
--idle-timeout 4
Configure NAT Service for Source Subnet
To configure the NAT service, run the following command, using your own values as needed:
az network vnet subnet update \
--resource-group ${RESOURCE_GROUP} \
--vnet-name ${VNET_NAME} \
--name cg \
--nat-gateway ${NAT_GATEWAY_NAME}
Get the AKS Subnet ID
To create the AKS subnet ID, run the following command, using your own values as needed:
export AKS_SUBNET_ID=$(az network vnet subnet show \
--resource-group ${RESOURCE_GROUP} \
--vnet-name ${VNET_NAME} \
--name aks \
--query id \
--output tsv)
Create an AKS Service
To create the AKS service, run the following command, using your own values as needed:
# Create the AKS cluster
az aks create \
--resource-group ${RESOURCE_GROUP} \
--name ${AKS_CLUSTER_NAME} \
--location ${LOCATION} \
--kubernetes-version 1.29.13 \
--network-plugin azure \
--network-policy calico \
--vnet-subnet-id ${AKS_SUBNET_ID} \
--service-cidr 10.4.0.0/16 \
--dns-service-ip 10.4.0.10 \
--node-vm-size Standard_D4d_v5 \
--node-count 2 \
--enable-cluster-autoscaler \
--min-count 2 \
--max-count 5 \
--auto-upgrade-channel patch \
--enable-managed-identity \
--nodepool-name oprnodepool \
--os-sku Ubuntu
Get the Principal ID of the Managed Identity
To get the Principal ID, run the following command, using your own values as needed:
export MANAGED_IDENTITY_PRINCIPAL_ID="$(az aks show --resource-group ${RESOURCE_GROUP} --name ${AKS_CLUSTER_NAME} --query "identityProfile.kubeletidentity.clientId" --output tsv)"
For details, see Get the principal ID of the system-assigned managed identity in the Microsoft Azure documentation.
Create Contributor Role for the Two Resource Groups
To create the contributor role for each group, run the following commands, using your own values as needed:
az role assignment create \
--assignee ${MANAGED_IDENTITY_PRINCIPAL_ID} \
--scope /subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${AKS_NODE_RESOURCE_GROUP} \
--role Contributor
az role assignment create \
--assignee ${MANAGED_IDENTITY_PRINCIPAL_ID} \
--scope /subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP} \
--role Contributor
Additional reference information in external documentation:
- Tutorial: Deploy virtual nodes on Azure Container Instances in your Azure Kubernetes Service cluster
- Setting up a virtual node Environment
Set Up AKS Cluster
To set up the AKS cluster, run the following command, using your own values as needed:
az aks get-credentials --name ${AKS_CLUSTER_NAME} --resource-group ${RESOURCE_GROUP}
az provider register -n Microsoft.ContainerInstance
git clone git@github.com:microsoft/virtualnodesOnAzureContainerInstances.git
helm install virtualnode virtualnodesOnAzureContainerInstances/Helm/virtualnode
# Wait for ~1 minute for virtualnode-0 to appear.
kubectl get nodes
Complete Key Vault and Managed Identity Setup
The next step is to set up a key vault and save the operator key in it. When you've created the key vault, you can create a managed identity and grant it permission to access the key vault.
Later, when the AKS cluster launches, it uses this identity. For details, see Running pods with an Azure Managed Identity in the Microsoft Azure documentation.
Follow these steps:
az identity create --name "${MANAGED_IDENTITY}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}"
az keyvault create --name "${KEYVAULT_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --enable-purge-protection --enable-rbac-authorization
export KEYVAULT_RESOURCE_ID="$(az keyvault show --resource-group "${RESOURCE_GROUP}" --name "${KEYVAULT_NAME}" --query id --output tsv)"
az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value "<some value>"
export IDENTITY_PRINCIPAL_ID="$(az identity show --name "${MANAGED_IDENTITY}" --resource-group "${RESOURCE_GROUP}" --query principalId --output tsv)"
az role assignment create --assignee-object-id "${IDENTITY_PRINCIPAL_ID}" --role "Key Vault Secrets User" --scope "${KEYVAULT_RESOURCE_ID}" --assignee-principal-type ServicePrincipal
Complete the UID2 Private Operator Setup
To complete the Private Operator setup, follow these steps:
Update Placeholder Values
After completing the previous steps, follow these steps to update placeholder values:
-
Get the managed identity ID by running the following:
MANAGED_IDENTITY_ID=$("az identity show --name "${MANAGED_IDENTITY}" --resource-group "${RESOURCE_GROUP}" --query id --output tsv")
-
In the
operator.yaml
file, updatemicrosoft.containerinstance.virtualnode.identity
with the managed identity ID that was returned:sed -i "s#IDENTITY_PLACEHOLDER#$MANAGED_IDENTITY_ID#g" "operator.yaml"
-
Update the Vault Key and Secret names with the environment variables:
sed -i "s#VAULT_NAME_PLACEHOLDER#$KEYVAULT_NAME#g" "operator.yaml"
sed -i "s#OPERATOR_KEY_SECRET_NAME_PLACEHOLDER#$KEYVAULT_SECRET_NAME#g" "operator.yaml"
sed -i "s#DEPLOYMENT_ENVIRONMENT_PLACEHOLDER#$DEPLOYMENT_ENV#g" "operator.yaml"
Deploy Operator
Follow these steps to deploy the Private Operator:
-
Retrieve the Kubernetes configuration credentials for the AKS cluster you just created:
az aks get-credentials --name ${AKS_CLUSTER_NAME} --resource-group ${RESOURCE_GROUP}
-
When you've retrieved the Kubernetes configuration credentials, deploy the Private Operator by running the following:
kubectl apply -f operator.yaml
Running the Health Check
Call the health check endpoint to test the health of your implementation.
Running the health check is the same for the integration and production environments, except for the endpoints.
Follow these steps:
-
Get the public IP address for the service:
IP=$(az network public-ip list --resource-group ${AKS_NODE_RESOURCE_GROUP} --query "[?starts_with(name, 'kubernetes')].ipAddress" --output tsv)
-
To test operator status, in your browser, go to the health check endpoint:
http://${IP}/ops/healthcheck
.An HTTP 200 with a response body of
OK
indicates healthy status.
When a Private Operator fails to attest with the Core service, one of the following actions happens:
- HTTP 401 response. The Private Operator terminates itself immediately.
- Likely Causes: Operator key revoked or incorrect.
- Any other non-200 response code. The Private Operator continues to function for 12 hours. If the issue is not resolved in this time frame, it terminates itself.
- Likely Causes: Core service issues, network issues.
Private Operator hosts must have infrastructure in place to handle alerting and restarting operators in the case of an error.
Upgrading
When a new version of UID2 Private Operator for AKS is released, participants hosting their own Private Operator receive an email notification of the update, with a new release link or instructions to get the installation file. There is a window of time for upgrade, after which the older version is deactivated and is no longer supported.
To upgrade, complete the following steps:
-
Follow the instructions in Download ZIP File and Extract Files to download the deployment file for the new version and then unzip it.
-
Follow the instructions in Complete the UID2 Private Operator Setup, using the new files, to deploy your AKS implementation with the new versions.
-
Check the health of the new AKS deployment and make sure the status is healthy.
-
Double-check that the old AKS pods are shut down properly:
kubectl get pods