Helm charts managed through Terraform to deploy an Azure SecretProviderClass on AKS

Helm charts managed through Terraform to deploy an Azure SecretProviderClass on AKS



In this article we will see how to benefit from the advantages of two infrastructure and template management solutions: Helm charts and Terraform.


In order to make the exercise challenging and to prove that the use of these two features works well, I deliberately chose to use the SecretProviderClass because it is a complex Kubernetes resource type to model.


For more details on the SecretProviderClass, please consult the following article that points out how to create a SecretProviderClass using user-assigned identity to access your key vault.






All the code used in this article is available here on GitHub: JamesDLD/terraform-azurerm_kubernetes-helm-chart-SecretProviderClass







Terraform providers & authentication


The trick here is to retrieve the Kubernetes certificate from the azurerm_kubernetes_cluster resource and pass it to the helm provider.





# - # - Providers # - provider "azurerm" { subscription_id = var.subscription_id features {} } provider "helm" { kubernetes { host = data.azurerm_kubernetes_cluster.aks.kube_admin_config.0.host client_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_admin_config.0.client_certificate) client_key = base64decode(data.azurerm_kubernetes_cluster.aks.kube_admin_config.0.client_key) cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.aks.kube_admin_config.0.cluster_ca_certificate) } } # - # - Azure Kubernetes Service cluster # - data "azurerm_kubernetes_cluster" "aks" { name = var.aks_cluster.name resource_group_name = var.aks_cluster.resource_group_name }







Terraform Helm release


In this section we highlight the following tips:

  1. Use Helm values files.
  2. Pass parameters from Terraform to the Helm chart through the “set” function.
  3. Dynamically retrieve the Azure Tenant ID from Terraform and pass it to the Helm chart.






variable "helm_release" { description = "A Release is an instance of a chart running in a Kubernetes cluster. https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release" default = { demo = { chart_path = "/charts/SecretProviderClass" values_paths = [ "/charts/SecretProviderClass/values.yaml", "/charts/SecretProviderClass/values-demo.yaml" ] set = [ { name = "tenantId" #Will calculated, see the below code }, { name = "userAssignedIdentityID" value = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" #Application ID of the managed identity "azurekeyvaultsecretsprovider-<AKS Cluster Name>" }, { name = "keyvaultName" value = "xxxxxxxxxxxx" } ] } } } data "azurerm_client_config" "current" {} # - # - Helm charts # - resource "helm_release" "helm_release" { for_each = var.helm_release name = lookup(each.value, "name", each.key) chart = "${path.module}${each.value.chart_path}" values = lookup(each.value, "values_paths", null) == null ? null : [for x in each.value.values_paths : file(format("%s%s", path.module, x))] recreate_pods = lookup(each.value, "recreate_pods", null) dynamic "set" { for_each = lookup(each.value, "set", []) content { name = set.value.name value = lookup(set.value, "name", null) == "tenantId" ? data.azurerm_client_config.current.tenant_id : set.value.value type = lookup(set.value, "type", null) } } }






Helm chart template


The following manifest file manages the Kubernetes SecretProviderClass object and was designed using the following requirements:

  1. Ability to create multiple SecretProviderClass Kubernetes objects using the range action.
  2. Use in order of preference the values ​​provided by the current “range” (file “value-demo.yaml”), then the default values ​​(file “value.yaml”) then those provided by Terraform (“set” function).





# Reference: Provide an identity to access the Azure Key Vault Provider for Secrets Store CSI Driver # Chapter: Use a user-assigned managed identity https://learn.microsoft.com/en-us/azure/aks/csi-secrets-store-identity-access?WT.mc_id=AZ-MVP-5003548#use-a-user-assigned-managed-identity {{- range $key, $value := .Values.secrets }} apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: {{ $value.name }} namespace: {{ $value.namespace }} spec: provider: azure parameters: {{ if $value.usePodIdentity }} usePodIdentity: "{{ $value.usePodIdentity }}" {{ else }} usePodIdentity: "{{ $.Values.usePodIdentity }}" {{ end }} {{ if $value.useVMManagedIdentity }} useVMManagedIdentity: "{{ $value.useVMManagedIdentity }}" {{ else }} useVMManagedIdentity: "{{ $.Values.useVMManagedIdentity }}" {{ end }} userAssignedIdentityID: {{ $.Values.userAssignedIdentityID }} {{ if $value.keyvaultName }} keyvaultName: {{ $value.keyvaultName }} {{ else }} keyvaultName: {{ $.Values.keyvaultName }} {{ end }} objects: | {{- $value.parameters.objects | nindent 6 }} tenantId: {{ $.Values.tenantId }} {{ if $value.secretObjects }} secretObjects: {{ $value.secretObjects | toYaml | nindent 2 -}} {{ end }} --- {{- end }}







Terraform plan


What’s interesting here with Terraform is that we can see the planned changes and we can pass Terraform known information like the Azure Tenant ID and core parameters like the target Azure Key Vault.








Using Terraform and Helm charts will help you reap the benefits of both worlds:

  • Make full use of your teams’ skills.
  • Pass calculated values from your cloud provider without writing them in your code.
  • Manage planned changes that new git commits plan to do before applying them in production.


See You in the Cloud


Published on:

Learn more
Azure Developer Community Blog articles
Azure Developer Community Blog articles

Azure Developer Community Blog articles

Share post:

Related posts

Announcing Azure Monitoring Agent support in Azure Landing Zones

Introduction   Hello and welcome to another blog post about Azure Landing Zones, the best practice framework for accelerating your cloud...

10 hours ago

Out-of-band updates to address Azure Synapse SQL issue caused by Windows updates

Microsoft has issued an out-of-band update to resolve an issue with Azure Synapse SQL Serverless Pool databases entering a "Recovery pending" ...

13 hours ago

[Mitigated] Azure Lab Services - Lab Plan Outage

Azure Lab Service is experiencing an outage that is affecting Lab Plans, but not Lab Accounts. This outage intermittently impacts all operatio...

22 hours ago

Azure Lab Services Tutorial Video

This is a complete tutorial about Azure Lab Services' features. It walks through the steps of setting up a Lab Account, creating a Lab, and ac...

22 hours ago

What's new in the Azure Lab Services

This is a presentation highlighting the new features introduced in the latest preview for Azure Lab Services.

22 hours ago

Update to Azure Lab Services

The product team has been busy working on fundamental improvements for the service to boost performance, reliability, and scalability. It has ...

23 hours ago

Build scalable cross-subscription applications with Azure Load Balancer

We are thrilled to announce that Azure cross-subscription Load Balancer is now available for public preview in all Azure public and national c...

1 day ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy