This Terraform module is designed to efficiently manage secrets within an Azure Kubernetes Service (AKS) cluster through the use of External Secrets Operator (ESO). The module ensures secrets in the AKS cluster are continuously synced with Azure KeyVault, providing a centralized access point for your secret backend.

Key features:

  • Deploys External Secrets Operator and cluster-level ClusterSecretStore custom resource
  • Configures workload identity and corresponding credentials to make ESO work with KeyVault and its secrets
  • Creates a Kubernetes Custom Resource Definition (CRD) for KeyVault management

NOTE: This module is meant to be used with an already created Resource Group.

NOTE: After deploying the module, create a Kubernetes ExternalSecret to point at the KeyVault secret to be synchronized.

If reloader.namespace_selector parameter is set, Namespace manifests are required to have specific labels configured to match Reloader namespace selector.
If reloader.resource_label_selector parameter is set, Secrets/Config manifests are required to have specific labels configured to match Reloader resource selector.

For example, to match documentation, the Secret's labels must contain: app-secret: "yes"

Deployment resources that reference a secret in their configuration must have an annotation set: as mostly suitable, reloader.stakater.com/auto: "true"

More options can be found in Reloader documentation.

The configuration above will result in the following behavior of Reloader:

  • Reloader watches all resources inside a Namespace;
  • Reloader watches all secrets with specific labels;
  • Reloader is allowed to reload pod configuration once these secrets are updated.

Kubernetes ESO for Azure KV

External Secrets Operator integration with Azure KeyVault in AKS
$400
Dependencies included: $250
BUY
35
Log in to Corewide IaC registry

Once you have a Corewide Solutions Portal account, this one-time action will use your browser session to retrieve credentials:

 shellterraform login solutions.corewide.com
Provision instructions

Initialize mandatory providers:

Copy and paste into your Terraform configuration and insert the variables:

 hclmodule "tf_k8s_eso_azure" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-eso-azure/azurerm"
  version = "~> 1.0.0"

  # specify module inputs here or try one of the examples below
  ...
}

Initialize the setup:

 shellterraform init
Define update strategy

Corewide DevOps team strictly follows Semantic Versioning Specification to provide our clients with products that have predictable upgrades between versions. We recommend pinning patch versions of our modules using pessimistic constraint operator (~>) to prevent breaking changes during upgrades.

To get new features during the upgrades (without breaking compatibility), use ~> 1.0 and run terraform init -upgrade

For the safest setup, use strict pinning with version = "1.0.0"

v1.0.0 released 9 months, 1 week ago
New version approx. every 5 weeks

Deploy module with required parameters only:

 hclmodule "eso_azure" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-eso-azure/azurerm"
  version = "~> 1.0"

  name_prefix     = "foo"
  resource_group  = azurerm_resource_group.foo
  oidc_issuer_url = azurerm_kubernetes_cluster.foo.oidc_issuer_url

  key_vault = {
    id  = azurerm_key_vault.baz.id
    uri = azurerm_key_vault.baz.vault_uri
  }
}

Deploy module with custom Reloader parameters - set resource and namespace selectors:

 hclmodule "eso_azure" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-eso-azure/azurerm"
  version = "~> 1.0"

  name_prefix     = "foo"
  resource_group  = azurerm_resource_group.foo
  oidc_issuer_url = azurerm_kubernetes_cluster.foo.oidc_issuer_url

  key_vault = {
    id  = azurerm_key_vault.baz.id
    uri = azurerm_key_vault.baz.vault_uri
  }

  reloader = {
    namespace_selector = ["secrets-store"]
    resource_selector  = ["app-secret"]
  }
}

Deploy module with full custom configuration:

 hclmodule "eso_azure" {
  source  = "solutions.corewide.com/kubernetes/tf-k8s-eso-azure/azurerm"
  version = "~> 1.0"

  name_prefix          = "foo"
  resource_group       = azurerm_resource_group.foo
  oidc_issuer_url      = azurerm_kubernetes_cluster.foo.oidc_issuer_url
  service_account_name = "super-secrets-store"

  key_vault = {
    id  = azurerm_key_vault.baz.id
    uri = azurerm_key_vault.baz.vault_uri
  }

  node_selector = {
    "kubernetes\\.azure\\.com/agentpool" = "service"
  }

  eso = {
    chart_version = "yyyy"
    app_version   = "xxxx"

    custom_values = {
      foo = "bar"
    }
  }

  reloader = {
    chart_version      = "yyyy"
    app_version        = "xxxx"
    namespace_selector = ["secrets-store"]
    resource_selector  = ["app-secret"]
  }
}
Variable Description Type Default Required Sensitive
key_vault KeyVault parameters to be associated with the AKS cluster object yes no
name_prefix Name prefix for the created resources string yes no
oidc_issuer_url The OIDC issuer URL that is associated with the AKS cluster string yes no
resource_group The object with attributes of Resource Group in which resources should be created. Keys name and location are required any yes no
create_namespace Indicates creation of dedicated namespace for the stack deployment bool true no no
eso External Secrets Operator parameters. This parameter is passed to tf-k8s-eso module's eso parameter. eso.service_account parameter is ignored as it is managed by tf-k8s-eso-azure module itself any {} no no
key_vault.id The ID of the KeyVault string yes no
key_vault.uri The URI of the KeyVault, used for performing operations on keys and secrets string yes no
namespace The namespace to install the External Secrets Operator and Reloader into string external-secrets-operator no no
node_selector Node selector for the stack components map(string) {} no no
reloader Reloader parameters. This parameter is passed to tf-k8s-eso module's reloader parameter any {} no no
service_account_name Kubernetes ServiceAccount name string external-secrets-operator no no
Output Description Type Sensitive
cluster_secret_store_name Name of Kubernetes ClusterSecretStore resource to be used in creation of ExternalSecret resources attribute no
namespace The namespace name where External Secrets Operator and Reloader were installed resource no
user_assigned_identity Attributes of Azure User Assigned Identity resource resource no
Dependency Version Kind
terraform >= 1.3 CLI
hashicorp/azurerm ~> 4.0 provider
hashicorp/kubernetes ~> 2.9 provider
tf-k8s-crd ~> 2.0 module
tf-k8s-eso ~> 1.0 module

Not sure where to start?
Let's find your perfect match.