From afc9e5ba83a546b4f30b5cb95c40ae49fe67429f Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 11:41:28 +0530 Subject: [PATCH 01/11] feat(helm): external secrets operator deployment --- infrastructure/main.tf | 2 +- modules/helm/external_secrets.tf | 12 ++++++++++++ modules/helm/variables.tf | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 modules/helm/external_secrets.tf diff --git a/infrastructure/main.tf b/infrastructure/main.tf index 87fbaf1..1546daf 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -9,7 +9,7 @@ data "kubernetes_endpoints_v1" "kubernetes_api_endpoint" { # Deploy all required helm charts for deploying the infrastructure module "helm" { - source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=main" + source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=task/111/eso-deployment" server_node_selector = "cloud" } diff --git a/modules/helm/external_secrets.tf b/modules/helm/external_secrets.tf new file mode 100644 index 0000000..c558e9f --- /dev/null +++ b/modules/helm/external_secrets.tf @@ -0,0 +1,12 @@ +# External Secrets Operator Configuration +resource "helm_release" "external_secrets" { + name = var.external_secrets_configuration.name + namespace = var.external_secrets_configuration.namespace + repository = var.external_secrets_configuration.repository + chart = var.external_secrets_configuration.chart + version = var.external_secrets_configuration.version + create_namespace = var.external_secrets_configuration.create_namespace + + depends_on = [ helm_release.calico ] + timeout = 1800 +} diff --git a/modules/helm/variables.tf b/modules/helm/variables.tf index ba427d4..dbb9536 100644 --- a/modules/helm/variables.tf +++ b/modules/helm/variables.tf @@ -100,7 +100,7 @@ variable "calico_configuration" { } } -# --------------- CALICO OPERATOR VARIABLES --------------- # +# --------------- NETOBSERV VARIABLES --------------- # variable "netobserv_configuration" { description = "Dictionary filled with Netobserv Operator Configuration Details" type = map(string) @@ -114,6 +114,20 @@ variable "netobserv_configuration" { } } +# --------------- EXTERNAL SECRETS VARIABLES --------------- # +variable "external_secrets_configuration" { + description = "Dictionary filled with External Secrets Operator Configuration Details" + type = map(string) + default = { + "name" = "external-secrets" + "namespace" = "external-secrets" + "repository" = "https://charts.external-secrets.io" + "chart" = "external-secrets" + "version" = "2.1.0" + "create_namespace" = true + } +} + # --------------- NODE SELECTOR VARIABLE --------------- # variable "server_node_selector" { description = "Node Selector Label Value to be used for deploying required foundation components" From f8a2a807bd2ec86d21736dbbc13757c967a4d424 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 11:59:19 +0530 Subject: [PATCH 02/11] feat(openbao): cluster secret store as openbao --- infrastructure/main.tf | 2 +- modules/openbao/external-secrets.tf | 55 +++++++++++++++++++++++++++++ modules/openbao/networkpolicy.tf | 20 +++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 modules/openbao/external-secrets.tf diff --git a/infrastructure/main.tf b/infrastructure/main.tf index 1546daf..ce67587 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -35,7 +35,7 @@ module "observability" { # OpenBao Secrets Management Solution deployment module "secrets" { - source = "git::https://github.com/necro-cloud/modules//modules/openbao?ref=main" + source = "git::https://github.com/necro-cloud/modules//modules/openbao?ref=task/111/eso-deployment" // Certificates Details cluster_issuer_name = module.cluster-issuer.cluster-issuer-name diff --git a/modules/openbao/external-secrets.tf b/modules/openbao/external-secrets.tf new file mode 100644 index 0000000..e564f52 --- /dev/null +++ b/modules/openbao/external-secrets.tf @@ -0,0 +1,55 @@ +resource "kubernetes_manifest" "cluster_store" { + manifest = { + apiVersion = "external-secrets.io/v1beta1" + kind = "ClusterSecretStore" + metadata = { + name = "openbao" + } + spec = { + refreshInterval = 60 + provider = { + vault = { + // Internal HA Service Address + server = "https://openbao-internal.${kubernetes_namespace.namespace.metadata[0].name}.svc:8200" + path = "secret" + version = "v2" + + // Use TLS to sync secrets to and from the cluster + caProvider = { + type = "Secret" + name = kubernetes_manifest.internal_certificate.manifest.spec.secretName + key = "ca.crt" + namespace = kubernetes_namespace.namespace.metadata[0].name + } + + auth = { + kubernetes = { + mountPath = "kubernetes" + + // OpenBao Role to use to authenticate + role = "eso-role" + serviceAccountRef = { + + // Default External Secrets Service Account + // Also allowed to authenticate with OpenBao + name = "external-secrets" + namespace = "external-secrets" + } + } + } + } + } + } + } + + // Ensuring the OpenBao Cluster is ready to go + depends_on = [kubernetes_job.configurator] + + // Wait for the Store to be valid before proceeding + wait { + condition { + type = "Ready" + status = "True" + } + } +} diff --git a/modules/openbao/networkpolicy.tf b/modules/openbao/networkpolicy.tf index 466caa6..106bf8c 100644 --- a/modules/openbao/networkpolicy.tf +++ b/modules/openbao/networkpolicy.tf @@ -119,6 +119,26 @@ resource "kubernetes_network_policy" "openbao_network_access_policy" { } } + # Rule 6: Allow External Secrets Operator to interact with OpenBao + ingress { + from { + namespace_selector { + match_labels = { + "kubernetes.io/metadata.name" = "external-secrets" + } + } + pod_selector { + match_labels = { + "app.kubernetes.io/instance" = "external-secrets" + } + } + } + ports { + protocol = "TCP" + port = 8200 + } + } + # -------------- EGRESS RULES -------------- # # Rule 1: Allow egress to other OpenBao pods for Raft consensus egress { From e3a74bd1f693888d5bbdca037dcca318be76db7f Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 12:00:42 +0530 Subject: [PATCH 03/11] feat(openbao): cluster secret store as openbao --- modules/openbao/external-secrets.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openbao/external-secrets.tf b/modules/openbao/external-secrets.tf index e564f52..bb6da48 100644 --- a/modules/openbao/external-secrets.tf +++ b/modules/openbao/external-secrets.tf @@ -1,6 +1,6 @@ resource "kubernetes_manifest" "cluster_store" { manifest = { - apiVersion = "external-secrets.io/v1beta1" + apiVersion = "external-secrets.io/v1" kind = "ClusterSecretStore" metadata = { name = "openbao" From 05114fafa0885e628c37d534f16f6fab8061ce7f Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 12:11:46 +0530 Subject: [PATCH 04/11] feat(openbao): pushing the static unseal key to openbao --- modules/openbao/secrets.tf | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/modules/openbao/secrets.tf b/modules/openbao/secrets.tf index b1630c0..1684f62 100644 --- a/modules/openbao/secrets.tf +++ b/modules/openbao/secrets.tf @@ -17,3 +17,57 @@ resource "kubernetes_secret" "static_unseal_key" { "OPENBAO_STATIC_UNSEAL_KEY" = random_id.static_unseal_key.b64_std } } + +// Push the secret to OpenBao +resource "kubernetes_manifest" "static_unseal_key" { + manifest = { + apiVersion = "external-secrets.io/v1alpha1" + kind = "PushSecret" + metadata = { + name = "static-unseal-key" + namespace = kubernetes_namespace.namespace.metadata[0].name + } + spec = { + refreshInterval = "1h" + secretStoreRefs = [ + { + name = kubernetes_manifest.cluster_store.manifest.metadata.name + kind = "ClusterSecretStore" + } + ] + selector = { + secret = { + name = kubernetes_secret.static_unseal_key.metadata[0].name + } + } + data = [ + { + match = { + remoteRef = { + remoteKey = "${kubernetes_namespace.namespace.metadata[0].name}/infrastructure/${kubernetes_secret.static_unseal_key.metadata[0].name}" + } + } + } + ] + } + } + + // Wait for the sync to complete + wait { + condition { + type = "Ready" + status = "True" + } + } + + timeouts { + create = "5m" + update = "5m" + } + + // Waiting till the store and the source secret actually exist + depends_on = [ + kubernetes_manifest.cluster_store, + kubernetes_secret.static_unseal_key + ] +} From 53e7bab82c8d89a820e69af9a145ca2f0308d6af Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 12:22:09 +0530 Subject: [PATCH 05/11] fix(openbao): fixing permissions for eso --- modules/openbao/config/configurator.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/openbao/config/configurator.sh b/modules/openbao/config/configurator.sh index 307cd9f..f959bc4 100644 --- a/modules/openbao/config/configurator.sh +++ b/modules/openbao/config/configurator.sh @@ -60,8 +60,15 @@ if ! bao operator init -status > /dev/null 2>&1; then # Setup ESO Access bao secrets enable -path=secret kv-v2 bao policy write eso-policy - < Date: Thu, 12 Mar 2026 12:22:23 +0530 Subject: [PATCH 06/11] feat(openbao): pushing the internal certs to openbao --- modules/openbao/certificates.tf | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/modules/openbao/certificates.tf b/modules/openbao/certificates.tf index 92df5ac..78ea348 100644 --- a/modules/openbao/certificates.tf +++ b/modules/openbao/certificates.tf @@ -131,6 +131,59 @@ resource "kubernetes_manifest" "internal_certificate" { } } +// Push the certificates to OpenBao +resource "kubernetes_manifest" "push_internal_certificate" { + manifest = { + apiVersion = "external-secrets.io/v1alpha1" + kind = "PushSecret" + metadata = { + name = var.internal_certificate_name + namespace = kubernetes_namespace.namespace.metadata[0].name + } + spec = { + refreshInterval = "1h" + secretStoreRefs = [ + { + name = kubernetes_manifest.cluster_store.manifest.metadata.name + kind = "ClusterSecretStore" + } + ] + selector = { + secret = { + name = kubernetes_manifest.internal_certificate.manifest.spec.secretName + } + } + data = [ + { + match = { + remoteRef = { + remoteKey = "${kubernetes_namespace.namespace.metadata[0].name}/certificates/${kubernetes_manifest.internal_certificate.manifest.spec.secretName}" + } + } + } + ] + } + } + + // Wait for the sync to complete + wait { + condition { + type = "Ready" + status = "True" + } + } + + timeouts { + create = "5m" + update = "5m" + } + + // Waiting till the store is created + depends_on = [ + kubernetes_manifest.cluster_store, + ] +} + // Kubernetes Secret for Cloudflare Tokens resource "kubernetes_secret" "cloudflare_token" { metadata { From 67f2d1c0de7369e9b89e41d9244822ce4c5572bc Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 12:28:23 +0530 Subject: [PATCH 07/11] feat(openbao): output the store name for all services to use --- modules/openbao/outputs.tf | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 modules/openbao/outputs.tf diff --git a/modules/openbao/outputs.tf b/modules/openbao/outputs.tf new file mode 100644 index 0000000..8f3b7be --- /dev/null +++ b/modules/openbao/outputs.tf @@ -0,0 +1,4 @@ +output "cluster_secret_store_name" { + description = "Name of the cluster secret store to be used for pulling and pushing secrets to OpenBao" + value = kubernetes_manifest.cluster_store.manifest.metadata.name +} From 92fd12f02095bc3ed517eb3407f5f0ec01a65e1f Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 12:37:52 +0530 Subject: [PATCH 08/11] docs(helm): README update --- modules/helm/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/helm/README.md b/modules/helm/README.md index c27c3e2..6e4ebbd 100644 --- a/modules/helm/README.md +++ b/modules/helm/README.md @@ -22,6 +22,7 @@ OpenTofu Module to deploy the following required helm charts: | [helm_release.cert-manager](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.cnpg](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.cnpg_barman_plugin](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | +| [helm_release.external_secrets](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.minio](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.netobserv](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.nginx](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | @@ -36,6 +37,7 @@ OpenTofu Module to deploy the following required helm charts: | [cnpg\_barman\_configuration](#input\_cnpg\_barman\_configuration) | Dictionary filled with Cloud Native PG Barman Configuration Details | `map(string)` |
{
"chart": "plugin-barman-cloud",
"name": "cnpg-barman",
"namespace": "cnpg-system",
"repository": "https://cloudnative-pg.github.io/charts",
"version": "v0.2.0"
}
| no | | [cnpg\_configuration](#input\_cnpg\_configuration) | Dictionary filled with Cloud Native PG Operator Configuration Details | `map(string)` |
{
"chart": "cloudnative-pg",
"create_namespace": true,
"name": "cnpg",
"namespace": "cnpg-system",
"repository": "https://cloudnative-pg.github.io/charts",
"version": "v0.26.0"
}
| no | | [enable\_minio](#input\_enable\_minio) | To enable MinIO Deployment or not | `bool` | `false` | no | +| [external\_secrets\_configuration](#input\_external\_secrets\_configuration) | Dictionary filled with External Secrets Operator Configuration Details | `map(string)` |
{
"chart": "external-secrets",
"create_namespace": true,
"name": "external-secrets",
"namespace": "external-secrets",
"repository": "https://charts.external-secrets.io",
"version": "2.1.0"
}
| no | | [minio\_operator\_configuration](#input\_minio\_operator\_configuration) | Dictionary filled with MinIO Operator Configuration Details | `map(string)` |
{
"chart": "operator",
"create_namespace": true,
"name": "minio-operator",
"namespace": "minio-operator",
"repository": "https://operator.min.io",
"version": "7.0.0"
}
| no | | [netobserv\_configuration](#input\_netobserv\_configuration) | Dictionary filled with Netobserv Operator Configuration Details | `map(string)` |
{
"chart": "netobserv-operator",
"create_namespace": true,
"name": "netobserv",
"namespace": "netobserv",
"repository": "https://netobserv.io/static/helm",
"version": "1.11.0"
}
| no | | [nginx\_configuration](#input\_nginx\_configuration) | Dictionary filled with NGINX Controller Configuration Details | `map(string)` |
{
"chart": "ingress-nginx",
"create_namespace": true,
"name": "ingress-nginx",
"namespace": "ingress-nginx",
"repository": "https://kubernetes.github.io/ingress-nginx",
"version": "4.13.3"
}
| no | From 350ae1e445d6da14b5744f0adb8c96889c26c772 Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 12:37:59 +0530 Subject: [PATCH 09/11] docs(openbao): README update --- modules/openbao/README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/openbao/README.md b/modules/openbao/README.md index 7778a56..ffcb607 100644 --- a/modules/openbao/README.md +++ b/modules/openbao/README.md @@ -23,10 +23,13 @@ Required Modules to deploy OpenBao Secrets Manageemnt Solution: | [kubernetes_ingress_v1.ui_ingress](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/ingress_v1) | resource | | [kubernetes_job.configurator](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/job) | resource | | [kubernetes_manifest.certificate_authority](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [kubernetes_manifest.cluster_store](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.ingress_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.internal_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.issuer](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_manifest.public_issuer](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [kubernetes_manifest.push_internal_certificate](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [kubernetes_manifest.static_unseal_key](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | | [kubernetes_namespace.namespace](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | | [kubernetes_network_policy.openbao_network_access_policy](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/network_policy) | resource | | [kubernetes_role.configurator](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/role) | resource | @@ -40,11 +43,11 @@ Required Modules to deploy OpenBao Secrets Manageemnt Solution: | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [access\_namespaces](#input\_access\_namespaces) | Namespaces requiring accesses to the OpenBao Cluster in a comma seperated list | `string` | -| [acme\_server](#input\_acme\_server) | URL for the ACME Server to be used, defaults to production URL for LetsEncrypt | `string` | `"https://acme-v02 +| [access\_namespaces](#input\_access\_namespaces) | Namespaces requiring accesses to the OpenBao Cluster in a comma seperated list | `string` | n/a | yes | +| [acme\_server](#input\_acme\_server) | URL for the ACME Server to be used, defaults to production URL for LetsEncrypt | `string` | `"https://acme-v02.api.letsencrypt.org/directory"` | no | | [app\_name](#input\_app\_name) | App name for deploying OpenBao Secrets Management Solution | `string` | `"openbao"` | no | -| [certificate\_authority\_name](#input\_certificate\_authority\_name) | Name of the Certificate Authority to be associated with OpenBao -| [cloudflare\_email](#input\_cloudflare\_email) | Email for generating Ingress Certificates to be associated with OpenBao Secrets Management Solu +| [certificate\_authority\_name](#input\_certificate\_authority\_name) | Name of the Certificate Authority to be associated with OpenBao Secrets Management Solution | `string` | `"secrets-certificate-authority"` | no | +| [cloudflare\_email](#input\_cloudflare\_email) | Email for generating Ingress Certificates to be associated with OpenBao Secrets Management Solution | `string` | n/a | yes | | [cloudflare\_issuer\_name](#input\_cloudflare\_issuer\_name) | Name of the Cloudflare Issuer to be associated with OpenBao Secrets Management Solution | `string` | `"secrets-cloudflare-issuer"` | no | | [cloudflare\_token](#input\_cloudflare\_token) | Token for generating Ingress Certificates to be associated with OpenBao Secrets Management Solution | `string` | n/a | yes | | [cluster\_issuer\_name](#input\_cluster\_issuer\_name) | Name for the Cluster Issuer to be used to generate internal self signed certificates | `string` | n/a | yes | @@ -68,4 +71,6 @@ Required Modules to deploy OpenBao Secrets Manageemnt Solution: ## Outputs -No outputs. +| Name | Description | +|------|-------------| +| [cluster\_secret\_store\_name](#output\_cluster\_secret\_store\_name) | Name of the cluster secret store to be used for pulling and pushing secrets to OpenBao | From 510daa777fa63739e1fd64978d68d86f7595d4ea Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 13:23:27 +0530 Subject: [PATCH 10/11] [INF] All modules switch to main branch --- infrastructure/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/main.tf b/infrastructure/main.tf index ce67587..87fbaf1 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -9,7 +9,7 @@ data "kubernetes_endpoints_v1" "kubernetes_api_endpoint" { # Deploy all required helm charts for deploying the infrastructure module "helm" { - source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=task/111/eso-deployment" + source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=main" server_node_selector = "cloud" } @@ -35,7 +35,7 @@ module "observability" { # OpenBao Secrets Management Solution deployment module "secrets" { - source = "git::https://github.com/necro-cloud/modules//modules/openbao?ref=task/111/eso-deployment" + source = "git::https://github.com/necro-cloud/modules//modules/openbao?ref=main" // Certificates Details cluster_issuer_name = module.cluster-issuer.cluster-issuer-name From 6f7b0586a4d9f5ab4dc31a2d6541e7918117e31e Mon Sep 17 00:00:00 2001 From: khatrivarun Date: Thu, 12 Mar 2026 13:29:51 +0530 Subject: [PATCH 11/11] [INF] All modules switch to main branch --- infrastructure/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/main.tf b/infrastructure/main.tf index ce67587..87fbaf1 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -9,7 +9,7 @@ data "kubernetes_endpoints_v1" "kubernetes_api_endpoint" { # Deploy all required helm charts for deploying the infrastructure module "helm" { - source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=task/111/eso-deployment" + source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=main" server_node_selector = "cloud" } @@ -35,7 +35,7 @@ module "observability" { # OpenBao Secrets Management Solution deployment module "secrets" { - source = "git::https://github.com/necro-cloud/modules//modules/openbao?ref=task/111/eso-deployment" + source = "git::https://github.com/necro-cloud/modules//modules/openbao?ref=main" // Certificates Details cluster_issuer_name = module.cluster-issuer.cluster-issuer-name