Configure external secrets for Kubernetes deployments
This guide explains how to integrate Plane with external secret management solutions for secure, centralized management of sensitive configuration data. Examples cover AWS Secrets Manager and HashiCorp Vault, but you can adapt these patterns to your preferred solution.
AWS Secrets Manager
-
Create a dedicated IAM user (e.g.,
external-secret-access-user
). You can uncheck Console Access Required. -
Generate
ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
and keep them handy. -
Note the user's ARN for later use (format:
arn:aws:iam::<account-id>:user/<user-name>
). -
Create an IAM policy (e.g.,
external-secret-access-policy
) with the following 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 an IAM role (e.g.,
external-secret-access-role
) with the following trust relationship:{
"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 IAM policy from step 4 to the IAM role.
-
Create secrets in AWS Secrets Manager with your Plane configuration values (e.g., store RabbitMQ credentials as
prod/secrets/rabbitmq
).Key Value RABBITMQ_DEFAULT_USER
plane RABBITMQ_DEFAULT_PASS
plane123 Repeat for all environment variables you want to manage in AWS Secrets Manager.
-
Create a Kubernetes secret containing AWS credentials in your application namespace:
kubectl 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:
apiVersion: 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:
apiVersion: 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
property: RABBITMQ_DEFAULT_PASSSet all environment variables in AWS Secrets Manager, 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 Repeat for all environment variables you want to manage in Vault.
-
Create a Kubernetes secret containing your Vault token in your application namespace:
kubectl create secret generic vault-token -n <application_namespace> --from-literal=token=<VAULT-TOKEN>
-
Apply the following YAML to create a ClusterSecretStore resource:
apiVersion: 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:
apiVersion: 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
property: RABBITMQ_DEFAULT_PASSRepeat for all environment variables you want to manage in Vault, then access them via ExternalSecret resources in your Kubernetes cluster.