From fe056fd9f9bb08efe3ac2f13ce3f892ab7ebb7f6 Mon Sep 17 00:00:00 2001 From: Ian Keane Date: Wed, 19 Aug 2026 09:25:43 -0400 Subject: [PATCH] Add external secrets operator --- charts/external-secrets/Chart.yaml | 5 ++ .../templates/cluster-secret-store.yaml | 12 +++++ charts/external-secrets/values.yaml | 4 ++ manifests/cluster/external-secrets.yaml | 54 +++++++++++++++++++ terraform/argocd.tf | 16 ++++++ terraform/iam.tf | 18 +++++++ 6 files changed, 109 insertions(+) create mode 100644 charts/external-secrets/Chart.yaml create mode 100644 charts/external-secrets/templates/cluster-secret-store.yaml create mode 100644 charts/external-secrets/values.yaml create mode 100644 manifests/cluster/external-secrets.yaml diff --git a/charts/external-secrets/Chart.yaml b/charts/external-secrets/Chart.yaml new file mode 100644 index 0000000..e1fd94e --- /dev/null +++ b/charts/external-secrets/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: external-secrets-config +description: ClusterSecretStore for AWS Secrets Manager via EC2 instance role +type: application +version: 0.1.0 diff --git a/charts/external-secrets/templates/cluster-secret-store.yaml b/charts/external-secrets/templates/cluster-secret-store.yaml new file mode 100644 index 0000000..0838c2e --- /dev/null +++ b/charts/external-secrets/templates/cluster-secret-store.yaml @@ -0,0 +1,12 @@ +apiVersion: external-secrets.io/v1 +kind: ClusterSecretStore +metadata: + name: aws-secrets-manager +spec: + provider: + aws: + service: SecretsManager + region: {{ .Values.awsRegion }} + auth: + # Uses EC2 instance role via IMDS (instance metadata service) + # No credentials needed - the node role has secretsmanager:GetSecretValue diff --git a/charts/external-secrets/values.yaml b/charts/external-secrets/values.yaml new file mode 100644 index 0000000..a76df3c --- /dev/null +++ b/charts/external-secrets/values.yaml @@ -0,0 +1,4 @@ +# External Secrets Operator helm values +# https://external-secrets.io/latest/introduction/getting-started/ +# Uses EC2 instance role for AWS auth - no credentials needed +installCRDs: true diff --git a/manifests/cluster/external-secrets.yaml b/manifests/cluster/external-secrets.yaml new file mode 100644 index 0000000..29578c2 --- /dev/null +++ b/manifests/cluster/external-secrets.yaml @@ -0,0 +1,54 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: external-secrets + namespace: argocd +spec: + project: default + sources: + - repoURL: https://forge.keane.sh/ian/dumpnet-argo.git + targetRevision: HEAD + ref: values + - repoURL: https://charts.external-secrets.io + chart: external-secrets + targetRevision: "*" + helm: + valueFiles: + - $values/charts/external-secrets/values.yaml + destination: + server: https://kubernetes.default.svc + namespace: external-secrets + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: external-secrets-config + namespace: argocd +spec: + project: default + sources: + - repoURL: https://forge.keane.sh/ian/dumpnet-argo.git + targetRevision: HEAD + ref: values + - repoURL: https://forge.keane.sh/ian/dumpnet-argo.git + targetRevision: HEAD + path: charts/external-secrets + helm: + valueFiles: + - $values/values.yaml + releaseName: external-secrets-config + destination: + server: https://kubernetes.default.svc + namespace: external-secrets + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/terraform/argocd.tf b/terraform/argocd.tf index 0d6d3c1..e59a3cf 100644 --- a/terraform/argocd.tf +++ b/terraform/argocd.tf @@ -5,6 +5,16 @@ resource "random_password" "argocd_admin" { override_special = "!#$%&*()-_=+[]{}?" } +resource "random_password" "postgres" { + length = 32 + special = false +} + +resource "random_password" "kan_auth" { + length = 32 + special = false +} + # Single secrets manager secret for all cluster secrets resource "aws_secretsmanager_secret" "dumpnet" { name = var.cluster_name @@ -19,6 +29,12 @@ resource "aws_secretsmanager_secret_version" "dumpnet" { talosconfig = data.talos_client_configuration.this.talos_config kubeconfig = talos_cluster_kubeconfig.this.kubeconfig_raw } + postgres = { + password = random_password.postgres.result + } + kan = { + better_auth_secret = random_password.kan_auth.result + } }) } diff --git a/terraform/iam.tf b/terraform/iam.tf index 55bd744..822377c 100644 --- a/terraform/iam.tf +++ b/terraform/iam.tf @@ -39,3 +39,21 @@ resource "aws_iam_role_policy" "node_s3_logs" { ] }) } + +# Secrets Manager access for External Secrets Operator +resource "aws_iam_role_policy" "node_secrets_manager" { + name = "secrets-manager-read" + role = aws_iam_role.node.id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"] + Resource = aws_secretsmanager_secret.dumpnet.arn + } + ] + }) +} +