Configure external secrets for Kubernetes deployments
This guide explains how to integrate Plane with external secret management solutions, enabling secure and centralized management of sensitive configuration data. The examples provided cover AWS Secrets Manager and HashiCorp Vault integrations, but you can adapt these patterns to your preferred secret management solution.
AWS Secrets Manager
Create a dedicated IAM user (e.g.,
external-secret-access-user). You can uncheck Console Access Required.Generate
ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYand keep them handy.Note the user's ARN for later use (format:
arn:aws:iam::<account-id>:user/<user-name>).Create IAM policy (e.g.,
external-secret-access-policy) with the following JSON:json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds" ], "Resource": [ "arn:aws:secretsmanager:<REGION>:<ACCOUNT-ID>:secret:*" ] } ] }Replace
<REGION>and<ACCOUNT-ID>with your AWS region and account ID.Create IAM role (e.g., external-secret-access-role) with the following trust relationship:
json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "<IAM-USER-ARN>" }, "Action": "sts:AssumeRole" } ] }Replace
<IAM-USER-ARN>with the ARN of the user created in step 1.Attach the AWS IAM policy created in step 4 to the IAM role.
Create secrets in AWS Secrets Manager with your Plane configuration values. For example, store RabbitMQ credentials with a name like
prod/secrets/rabbitmq.Key Value RABBITMQ_DEFAULT_USER plane RABBITMQ_DEFAULT_PASS plane123 Follow this pattern to manage all the environment variables in AWS Secrets Manager.
Create a Kubernetes secret containing AWS credentials in your application namespace:
shkubectl create secret generic aws-creds-secret \ --from-literal=access-key=<AWS_ACCESS_KEY_ID> \ --from-literal=secret-access-key=<AWS_SECRET_ACCESS_KEY> \ -n <application_namespace>Apply the following YAML to create a ClusterSecretStore resource:
yamlapiVersion: external-secrets.io/v1 kind: ClusterSecretStore metadata: name: cluster-aws-secretsmanager namespace: <application_namespace> spec: provider: aws: service: SecretsManager role: arn:aws:iam::<ACCOUNT-ID>:role/<IAM ROLE> region: eu-west-1 auth: accessKeyIDSecretRef: name: aws-creds-secret key: access-key secretAccessKeySecretRef: name: aws-creds-secret key: secret-access-keyReplace
<ACCOUNT-ID>and<IAM ROLE>with your AWS account ID and the role name created in Step 5.Create an ExternalSecret resource to fetch secrets from AWS and create a corresponding Kubernetes secret:
yamlapiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: rabbitmq-external-secrets namespace: <application_namespace> spec: refreshInterval: 1m secretStoreRef: name: cluster-aws-secretsmanager # ClusterSecretStore name kind: ClusterSecretStore target: name: rabbitmq-secret # Target Kubernetes secret name creationPolicy: Owner data: - secretKey: RABBITMQ_DEFAULT_USER remoteRef: key: prod/secrets/rabbitmq property: RABBITMQ_DEFAULT_USER - secretKey: RABBITMQ_DEFAULT_PASS remoteRef: key: prod/secrets/rabbitmq
Make sure to set all environment variables in the AWS Secrets Manager, and then access them via ExternalSecret resources in your Kubernetes cluster.
HashiCorp Vault
Access the Vault UI at
https://<vault-domain>/.Set up a KV secrets engine if not already configured.
Create a secret with your Plane configuration values (e.g.,
secrets/rabbitmq_secrets). For this example, we're setting up RabbitMQ credentials:Key Value RABBITMQ_DEFAULT_USER plane RABBITMQ_DEFAULT_PASS plane123 Follow this pattern to manage all the other environment variables in the Vault.
Create a Kubernetes secret containing your Vault token in your application namespace:
shkubectl create secret generic vault-token -n <application_namespace> --from-literal=token=<VAULT-TOKEN>Apply the following YAML to create a ClusterSecretStore resource:
yamlapiVersion: external-secrets.io/v1 kind: ClusterSecretStore metadata: name: vault-backend namespace: <application_namespace> spec: provider: vault: server: "https://<vault-domain>" # the address of your vault instance path: "secrets" # path for accessing the secrets version: "v2" # Vault API version auth: tokenSecretRef: name: "vault-token" # Use a k8s secret called vault-token key: "token" # Use this key to access the vault tokenReplace
<vault-domain>with your Vault server address.Create an ExternalSecret resource to fetch secrets from Vault and create a corresponding Kubernetes secret:
yamlapiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: rabbitmq-external-secrets namespace: <application_namespace> # application-namespace spec: refreshInterval: "1m" secretStoreRef: name: vault-backend # ClusterSecretStore name kind: ClusterSecretStore target: name: rabbitmq-secret # Target Kubernetes secret name creationPolicy: Owner data: - secretKey: RABBITMQ_DEFAULT_USER remoteRef: key: secrets/data/rabbitmq_secrets property: RABBITMQ_DEFAULT_USER - secretKey: RABBITMQ_DEFAULT_PASS remoteRef: key: secrets/data/rabbitmq_secrets
Follow this pattern to manage all the environment variables in the Vault, then access them via ExternalSecret resources in your Kubernetes cluster.

