page_type | languages | products | name | description | urlFragment | |||||
---|---|---|---|---|---|---|---|---|---|---|
sample |
|
|
Secrets Store CSI with Azure Kubernetes and Azure KeyVault |
Using Secrets Store CSI with Azure Kubernetes and Azure KeyVault |
secrets-store-csi-with-aks-akv |
This repo is a walkthrough of using the Kubernetes Secrets Store CSI Driver as a mechanism to get secret contents stored in Azure Key Vault instance and use the Secret Store CSI driver interface to mount them into Kubernetes pods.
In this repo you can find a containerized Go sample app (deployed with Helm) running in an AKS cluster (provisioned with ARM templates), all setup with a Github Actions workflow. The workflow includes steps to:
- Provision an AKS Cluster and an Azure KeyVault
- Install the Secrets Store CSI Driver and the Azure Keyvault Provider using Helm
- Deploy a SecretProviderClass Object using Helm
- Sets the Key vault policy
- Adds a secret named
test-secret
and set it's value totest-secret-value
- Deploy a containerized sample Go app to the AKS cluster using Helm. The deployment yaml is configured to use the Secrets Store CSI driver and reference the SecretProviderClass resource.
The Azure Key Vault provider of the CSI driver offers 4 modes for accessing a KeyVault instance (Service Principal, Pod Identity, User-assigned Managed Identity, and System-assigned Managed Identity), this sample focused on using the User-assigned Managed Identity
.
Here is the folder structure:
.github\workflows
devops-workflow.yml
- Github Actions Pipelines yaml file
Application
charts
sampleapp
- Helm chart for sample appsecret-provider-class
- Helm chart for Secrets Store Provider Class
app.go
- Go sample appDockerfile
- Dockerfile for the sample app
ArmTemplates
- Arm Templates for provisioning aks, acr and application insights
Azure Key vault provider for Secrets Store CSI driver allows you to access secrets stored in an Azure Key vault instance. The Secrets Store CSI driver secrets-store.csi.k8s.io
allows the cluster to mount secrets stored in Azure Key vault into the pods as a volume.
A SecretProviderClass
custom resource is created in the defined namespace to provide Azure-specific parameters for the Secrets Store CSI driver.
To ensure the sample app is able to access the secrets stored in the provisioned Azure Key vault, the deployment.yaml
is updated to use secrets-store.csi.k8s.io
driver and the SecretProviderClass
created is referenced as shown in the snippet below.
spec:
volumes:
- name: secrets-mount
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "azure-keyvault"
While the infrastructure deployments and using Secrets Store CSI with Azure Kubernetes and Azure KeyVault
steps are all automated in the devops-workflow.yml
, here is an Azure documentation Secrets Store CSI with Azure Kubernetes and Azure KeyVault that describes a manual walkthrough.
- Azure CLI: Create and manage Azure resources.
- Kubectl: Kubernetes command-line tool which allows you to run commands against Kubernetes clusters.
- GitHub account
-
Fork the repo to your github account and git clone.
-
Create a resource group that will hold all the provisioned resources and a service principal to manage and access those resources
# Set your variables RESOURCEGROUPNAME="MyResourceGroup" LOCATION="MyLocation" SUBSCRIPTIONID="MySubscriptionId" SERVICEPRINCIPALNAME="MyServicePrincipalName" # Create resource group az group create --name $RESOURCEGROUPNAME --location $LOCATION # Create a service principal with Contributor role to the resource group az ad sp create-for-rbac --name $SERVICEPRINCIPALNAME --role Contributor --scopes /subscriptions/$SUBSCRIPTIONID/resourceGroups/$RESOURCEGROUPNAME --sdk-auth
-
Use the json output of the last command as a secret named
AZURE_CREDENTIALS
in the repository settings (Settings -> Secrets -> Add New Secret).Also add a secret named
AZURE_SUBSCRIPTIONID
for the subscription id and a secret namedAZURE_TENANTID
for the tenant id.For more details on generating the deployment credentials please see this guide.
-
Github Actions will be used to automate the workflow and deploy all the necessary resources to Azure. Open the .github\workflows\devops-workflow.yml and change the environment variables accordingly. Update the
RESOURCEGROUPNAME
variable and set the value that you created above. -
Commit your changes. The commit will trigger the build and deploy jobs within the workflow and will provision all the resources to run the sample application.
To validate that the secrets are mounted to the sampleapp pod in the AKS cluster from Azure KeyVault as specified in the deployment yaml.
- mountPath: "mnt/secrets-store"
name: secrets-mount
readOnly: true
Note: The expected secrets should be test-secret-value
.
# Define variables
RESOURCEGROUPNAME="<insert-resource-group-name-here>"
CLUSTERNAME="<insert-cluster-name-here>"
NAMESPACE="<insert-sampleapp-namespace-name-here>"
# Connect to Cluster
az aks get-credentials --resource-group $RESOURCEGROUPNAME --name $CLUSTERNAME
# Get a pod name the app is running on
PODNAME=$(kubectl get pod -l app=sampleapp -o jsonpath="{.items[0].metadata.name}" -n $NAMESPACE)
# Exec into the pod
kubectl exec -it $PODNAME -n $NAMESPACE -- bash
# Verify the secrets
cd /mnt/secrets-store/
cat test-secret; echo