AKS cluster setup
Overview
This section provides instructions for setting up the Azure Kubernetes Service (AKS) for use with the CAST Imaging helm charts installation scripts described in Installation on Microsoft Azure via AKS.
Create cluster
As an administrator, connect to your Azure Portal and open a Cloud Shell. Update the variable section of the script and execute it step by step inside the Cloud Shell: copy/paste and execute one or a few commands at a time to better control the execution.
################################################################################
### Variables
################################################################################
END_USER_EMAILS="user@company.com" # Space separated emails of the desired cluster users
# Will be added to the Cloud security group
SUBSCRIPTION="aaaaa-aaaa-aaa-aaa-aaaaaaaa" # Enter your Azure subscription ID
LOCATION="eastus" # Enter your Azure location
RESOURCE_GROUP_NAME="resource-group-name" # Choose a name for the resource-group to be created
SECURITY_GROUP_NAME="security-group-name" # Choose a name for the security-group to be created
CLUSTER_NAME="aks-cluster-name" # Choose a name for the cluster to be created
KEYVAULT_NAME="keyvault-name" # Choose a name for the keyvault to be created
NODES_POOL_SIZE="standard_d8s_v3" # Instance type used for the nodes of the cluster
################################################################################
### Environment preparation
################################################################################
# Ensure you are on the correct subscription
az account set --subscription $SUBSCRIPTION
sleep 5
# Create the Cloud security group
az ad group create \
--display-name $SECURITY_GROUP_NAME \
--mail-nickname $SECURITY_GROUP_NAME
sleep 5
# Create the RG
az group create \
--name $RESOURCE_GROUP_NAME \
--location $LOCATION \
--subscription $SUBSCRIPTION \
--tags creation_date=$(date +"%Y%m%d")
sleep 5
# Create the key vault (will be used to store the SSL certificate for CAST frontend)
az keyvault create --resource-group $RESOURCE_GROUP_NAME --location $LOCATION --name $KEYVAULT_NAME --enable-rbac-authorization true
sleep 10
# Set the Cloud security group members
for email in $END_USER_EMAILS; do
# Get the user's object ID
USER_OBJECT_ID=$(az ad user show --id "$email" --query id -o tsv)
# Add the user to the security group
az ad group member add \
--group $SECURITY_GROUP_NAME \
--member-id $USER_OBJECT_ID
echo "Added $email to $SECURITY_GROUP_NAME"
done
sleep 10
################################################################################
### Permissions assignment
################################################################################
SECURITY_GROUP_ID=$(az ad group show --group $SECURITY_GROUP_NAME --query "id" --output tsv)
# These custom roles have the RG as assignable scope
# It means they can only be applied to this specific RG
# And that the roles will be deleted when the RG is deleted
az role definition create --role-definition '
{
"Name": "Custom role disk deletion '$RESOURCE_GROUP_NAME'",
"IsCustom": true,
"Description": "",
"Actions": [
"Microsoft.Compute/disks/delete"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/'$SUBSCRIPTION'/resourceGroups/'$RESOURCE_GROUP_NAME'"
]
}
'
sleep 1
az role definition create --role-definition '
{
"Name": "Custom role application gateway full access '$RESOURCE_GROUP_NAME'",
"IsCustom": true,
"Description": "",
"Actions": [
"Microsoft.Network/applicationGateways/write",
"Microsoft.Network/applicationGateways/read",
"Microsoft.Network/applicationGateways/delete"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/'$SUBSCRIPTION'/resourceGroups/'$RESOURCE_GROUP_NAME'"
]
}
'
sleep 1
az role definition create --role-definition '
{
"Name": "Custom role resources health and diagnostics '$RESOURCE_GROUP_NAME'",
"IsCustom": true,
"Description": "",
"Actions": [
"Microsoft.ResourceHealth/availabilityStatuses/*",
"Microsoft.Insights/diagnosticSettings/*"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/'$SUBSCRIPTION'/resourceGroups/'$RESOURCE_GROUP_NAME'"
]
}
'
sleep 5
# Set permissions using the existing builtin roles
az role assignment create --assignee $SECURITY_GROUP_ID --role "Azure Kubernetes Service Contributor Role" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Data Operator for Managed Disks" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Key Vault Administrator" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Managed Identity Contributor" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Network Contributor" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Storage Account Contributor" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
sleep 5
# Set permissions using the roles we just created
az role assignment create --assignee $SECURITY_GROUP_ID --role "Custom role disk deletion $RESOURCE_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Custom role application gateway full access $RESOURCE_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Custom role resources health and diagnostics $RESOURCE_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME
sleep 5
################################################################################
### AKS cluster creation (takes a few minutes)
################################################################################
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--location $LOCATION \
--node-vm-size $NODES_POOL_SIZE \
--node-count 1 \
--min-count 1 \
--max-count 2 \
--enable-cluster-autoscaler \
--network-plugin kubenet \
--network-policy calico \
--generate-ssh-keys \
--max-pods 250 \
--subscription $SUBSCRIPTION
# Wait a bit for the cluster to be fully ready
sleep 120
################################################################################
### Additional permissions on MC RG
################################################################################
SECURITY_GROUP_ID=$(az ad group show --group $SECURITY_GROUP_NAME --query "id" --output tsv)
MC_GROUP_NAME=$(az group list --query "[?starts_with(name,'MC_$RESOURCE_GROUP_NAME')].name" -o tsv)
sleep 5
# Ensure you are on the correct subscription
az account set --subscription $SUBSCRIPTION
# These custom roles have the RG as assignable scope
# It means they can only be applied to this specific RG
# And that the roles will be deleted when the RG is deleted
az role definition create --role-definition '
{
"Name": "Custom role disk deletion '$MC_GROUP_NAME'",
"IsCustom": true,
"Description": "",
"Actions": [
"Microsoft.Compute/disks/delete"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/'$SUBSCRIPTION'/resourceGroups/'$MC_GROUP_NAME'"
]
}
'
sleep 5
# Set permissions using the existing builtin roles
az role assignment create --assignee $SECURITY_GROUP_ID --role "Network Contributor" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$MC_GROUP_NAME
az role assignment create --assignee $SECURITY_GROUP_ID --role "Reader" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$MC_GROUP_NAME
# Set permissions using the roles we just created
az role assignment create --assignee $SECURITY_GROUP_ID --role "Custom role disk deletion $MC_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$MC_GROUP_NAME
################################################################################
### Enable required add-ons on the cluster
################################################################################
sleep 5
# Enable the Application Routing add-on
az aks approuting enable --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME
sleep 20
# Enable the Secret Store CSI Driver add-on
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME
sleep 20
################################################################################
### Set additional permissions for the KV
################################################################################
# Get the key vault ID
KEYVAULTID=$(az keyvault show --name $KEYVAULT_NAME --query "id" --output tsv)
# Enable key vault integration with the application routing add-on
az aks approuting update --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME --enable-kv --attach-kv ${KEYVAULTID}
sleep 10
az role definition create --role-definition '{
"Name": "Custom KeyVault Write '"$RESOURCE_GROUP_NAME"'",
"IsCustom": true,
"Description": "Custom role to allow Key Vault write permissions for Application Routing",
"Actions": [
"Microsoft.KeyVault/vaults/write",
"Microsoft.KeyVault/vaults/accessPolicies/write"
],
"NotActions": [],
"AssignableScopes": [
"/subscriptions/'"$SUBSCRIPTION"'/resourceGroups/'"$RESOURCE_GROUP_NAME"'"
]
}'
sleep 5
SECRETS_PROVIDER_ID=$(az aks show -g $RESOURCE_GROUP_NAME -n $CLUSTER_NAME \
--query "addonProfiles.azureKeyvaultSecretsProvider.identity.objectId" -o tsv)
sleep 5
az role assignment create --assignee $SECRETS_PROVIDER_ID --role "Custom KeyVault Write $RESOURCE_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME
sleep 5
az role assignment create --assignee $SECURITY_GROUP_ID --role "Custom KeyVault Write $RESOURCE_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME
sleep 5
WEB_APP_ROUTING_ID=$(az identity list -g MC_${RESOURCE_GROUP_NAME}_${CLUSTER_NAME}_$(az aks show -g $RESOURCE_GROUP_NAME -n $CLUSTER_NAME --query location -o tsv) --query "[?contains(name, 'webapprouting')].principalId" -o tsv)
az role assignment create --assignee $WEB_APP_ROUTING_ID --role "Custom KeyVault Write $RESOURCE_GROUP_NAME" --scope /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME
sleep 5