Skip to content

Commit 49496dc

Browse files
authored
CLOUDP-200138: Add secret management sample snippets (#1147)
1 parent 98c0d02 commit 49496dc

File tree

10 files changed

+265
-0
lines changed

10 files changed

+265
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Automated secret provisioning with External Secrets
2+
3+
The Atlas Kubernetes Operator consumes credentials from Kubernetes Secrets, continuously waiting for changes in them.
4+
5+
With this, the Operator is ready to support both manually or automatically deployed secrets. Among the automated secrets, one popular solution is to provision the secrets directly off the company's or team's Vault service of choice. One Open Source tool allowing for this automation is [External Secrets](https://external-secrets.io/latest/).
6+
7+
In this directory we have a couple of examples on how you would integrate the Operator Atlas credentials and DB User Password with a Hashicorp Vault.
8+
9+
For more details, please check out the documentation at [External Secrets](https://external-secrets.io/latest/) directly.
10+
11+
Here are some pointers to popular External Secrets providers:
12+
13+
- [Hashicorp Vault](https://external-secrets.io/latest/provider/hashicorp-vault/).
14+
- [AWS Secrets Manager](https://external-secrets.io/latest/provider/aws-secrets-manager/) or [Parameters Store](https://external-secrets.io/latest/provider/aws-parameter-store/).
15+
- [Azure Key Vault](https://external-secrets.io/latest/provider/azure-key-vault/).
16+
- [Google Cloud Secret Manager](https://external-secrets.io/latest/provider/google-secrets-manager/).
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# atlas External Secret CRD specifies a reference to the Atlas account
2+
# credentials to be fetched from the Vault for the atlas system namespace
3+
apiVersion: external-secrets.io/v1beta1
4+
kind: ExternalSecret
5+
metadata:
6+
name: atlas
7+
namespace: mongodb-atlas-system
8+
spec:
9+
refreshInterval: "15s"
10+
secretStoreRef:
11+
name: vault-store # defined at vault-system.yaml
12+
kind: SecretStore
13+
target:
14+
name: mongodb-atlas-operator-api-key
15+
template:
16+
metadata:
17+
labels:
18+
atlas.mongodb.com/type: credentials
19+
data:
20+
- secretKey: orgId
21+
remoteRef:
22+
key: secret/data/kube01/external-secrets/atlas-account
23+
property: orgId
24+
- secretKey: publicApiKey
25+
remoteRef:
26+
key: secret/data/kube01/external-secrets/atlas-account
27+
property: publicApiKey
28+
- secretKey: privateApiKey
29+
remoteRef:
30+
key: secret/data/kube01/external-secrets/atlas-account
31+
property: privateApiKey
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# dbuser External Secret CRD specifies a reference to the db user password
2+
# to be fetched from the Vault for the default namespace
3+
apiVersion: external-secrets.io/v1beta1
4+
kind: ExternalSecret
5+
metadata:
6+
name: dbuser
7+
namespace: default
8+
spec:
9+
refreshInterval: "15s"
10+
secretStoreRef:
11+
name: vault-store # defined at vault-default.yaml
12+
kind: SecretStore
13+
target:
14+
name: dbuser-password
15+
template:
16+
metadata:
17+
labels:
18+
atlas.mongodb.com/type: credentials
19+
data:
20+
- secretKey: password
21+
remoteRef:
22+
key: secret/data/kube01/external-secrets/db-user
23+
property: password
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# vault-store Secrets Store CRD specifies a Vault access to be used
2+
# to fetch secrets for the atlas default namespace
3+
#
4+
# Example parameters:
5+
# - This is the config for cluster "kube01" out of possibly many others.
6+
# - Hashicorp Vault: https://vault.internal.io
7+
# - Vault OIDC Auth mount point for kube01: jwt-kube01
8+
# - Service Account mapped to the Vault Role: {name: default, ns: default}
9+
# - Vault Role mapped to the Service Account: jwt-kube01-default
10+
# - OIDC audience "aud" at the JWT token: vault
11+
apiVersion: external-secrets.io/v1beta1
12+
kind: SecretStore
13+
metadata:
14+
name: vault-store
15+
namespace: default
16+
spec:
17+
provider:
18+
vault:
19+
server: "https://vault.internal.io"
20+
path: "secret"
21+
version: "v2"
22+
auth:
23+
jwt:
24+
path: "jwt-kube01"
25+
role: "jwt-kube01-default"
26+
kubernetesServiceAccountToken:
27+
expirationSeconds: 600
28+
serviceAccountRef:
29+
name: "default"
30+
audiences:
31+
- vault
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# vault-store Secrets Store CRD specifies a Vault access to be used
2+
# to fetch secrets for the atlas system namespace
3+
#
4+
# Example parameters:
5+
# - This is the config for cluster "kube01" out of possibly many others.
6+
# - Hashicorp Vault: https://vault.internal.io
7+
# - Vault OIDC Auth mount point for kube01: jwt-kube01
8+
# - Service Account mapped to the Vault Role: {name: default, ns: mongodb-atlas-system}
9+
# - Vault Role mapped to the Service Account: jwt-kube01-system
10+
# - OIDC audience "aud" at the JWT token: vault
11+
apiVersion: external-secrets.io/v1beta1
12+
kind: SecretStore
13+
metadata:
14+
name: vault-store
15+
namespace: mongodb-atlas-system
16+
spec:
17+
provider:
18+
vault:
19+
server: "https://vault.internal.io"
20+
path: "secret"
21+
version: "v2"
22+
auth:
23+
jwt:
24+
path: "jwt-kube01"
25+
role: "jwt-kube01-system"
26+
kubernetesServiceAccountToken:
27+
expirationSeconds: 600
28+
serviceAccountRef:
29+
name: "default"
30+
audiences:
31+
- vault
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Automated secret provisioning with Secrets Store CSI Driver
2+
3+
The Atlas Kubernetes Operator consumes credentials from Kubernetes Secrets, continuously waiting for changes in them.
4+
5+
With this, the Operator is ready to support both manually or automatically deployed secrets. Among the automated secrets, one popular solution is to provision the secrets directly off the company's or team's Vault service of choice. One Open Source tool allowing for this automation is [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/). Note, however, [the main usage of the CSI driver is to mount secrets as local files in pods, but it also supports the option to expose Kubernetes Secrets our of those mounts so long as some pod is mounting them](https://secrets-store-csi-driver.sigs.k8s.io/topics/sync-as-kubernetes-secret).
6+
7+
In this directory we have a couple of examples on how you would integrate the Operator Atlas credentials and DB User Password with a Hashicorp Vault.
8+
9+
For more details, please check out the documentation at [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/) directly.
10+
11+
Here are the pointers to the Secrets Store provider plugins:
12+
13+
- [Hashicorp Vault](https://github.com/hashicorp/vault-csi-provider).
14+
- [AWS plugin provider](https://github.com/aws/secrets-store-csi-driver-provider-aws) Secrets Manager or Parameters Store.
15+
- [Azure Key Vault](https://azure.github.io/secrets-store-csi-driver-provider-azure/docs/).
16+
- [Google Cloud Secret Manager](https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp).
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# ako-patch adds a container to the AKO pod to fetch the Atlas credentials
2+
# using the Secret Store CSI driver's "atlas" Secret Provider Class
3+
spec:
4+
template:
5+
spec:
6+
containers:
7+
- name: system-secret-placeholder
8+
image: mongodb/atlas
9+
command: ["sleep", "infinity"]
10+
volumeMounts:
11+
- name: secrets-store-mount
12+
mountPath: "/mnt/secrets-store"
13+
readOnly: true
14+
volumes:
15+
- name: secrets-store-mount
16+
csi:
17+
driver: secrets-store.csi.k8s.io
18+
readOnly: true
19+
volumeAttributes:
20+
secretProviderClass: atlas # defined at atlas.yaml
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# atlas Secret Provider Class CRD specifies a CSI Vault access
2+
# and the Atlas account credentials to be fetched for the atlas system namespace
3+
#
4+
# Example parameters:
5+
# - This is the config for cluster "kube01" out of possibly many others.
6+
# - Hashicorp Vault: https://vault.internal.io
7+
# - Vault Kubernetes Auth mount point for kube01: k8s-kube01
8+
# - Service Account mapped to the Vault Role: {name: default, ns: mongodb-atlas-system}
9+
# - Vault Role mapped to the Service Account: k8s-kube01-default
10+
apiVersion: secrets-store.csi.x-k8s.io/v1
11+
kind: SecretProviderClass
12+
metadata:
13+
name: atlas
14+
namespace: mongodb-atlas-system
15+
spec:
16+
provider: vault
17+
secretObjects:
18+
- data:
19+
- key: orgId
20+
objectName: atlas-org
21+
- key: publicApiKey
22+
objectName: atlas-pub-key
23+
- key: privateApiKey
24+
objectName: atlas-secret-key
25+
secretName: mongodb-atlas-operator-api-key
26+
type: Opaque
27+
labels:
28+
atlas.mongodb.com/type: credentials
29+
parameters:
30+
vaultAddress: https://vault.internal.io
31+
vaultKubernetesMountPath: k8s-kube01
32+
roleName: k8s-kube01-role
33+
objects: |
34+
- objectName: atlas-org
35+
secretPath: secret/data/kube01/secrets-store/atlas-account
36+
secretKey: orgId
37+
- objectName: atlas-pub-key
38+
secretPath: secret/data/kube01/secrets-store/atlas-account
39+
secretKey: publicApiKey
40+
- objectName: atlas-secret-key
41+
secretPath: secret/data/kube01/secrets-store/atlas-account
42+
secretKey: privateApiKey
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# vault Secret Provider Class CRD specifies a CSI Vault access
2+
# and secrets to be fetched to the default namespace
3+
#
4+
# Example parameters:
5+
# - This is the config for cluster "kube01" out of possibly many others.
6+
# - Hashicorp Vault: https://vault.internal.io
7+
# - Vault Kubernetes Auth mount point for kube01: k8s-kube01
8+
# - Service Account mapped to the Vault Role: {name: default, ns: default}
9+
# - Vault Role mapped to the Service Account: k8s-kube01-default
10+
apiVersion: secrets-store.csi.x-k8s.io/v1
11+
kind: SecretProviderClass
12+
metadata:
13+
name: dbuser
14+
namespace: default
15+
spec:
16+
provider: vault
17+
secretObjects:
18+
- data:
19+
- key: password
20+
objectName: dbuser
21+
secretName: dbuser-password
22+
type: Opaque
23+
labels:
24+
atlas.mongodb.com/type: credentials
25+
parameters:
26+
vaultAddress: https://vault.internal.io
27+
vaultKubernetesMountPath: k8s-kube01
28+
roleName: k8s-kube01-role
29+
objects: |
30+
- objectName: "dbuser"
31+
secretPath: "secret/data/kube01/secrets-store/db-user"
32+
secretKey: "password"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# secret-placeholder is a sentinel pod used just to ensure the CSI driver will
2+
# fetch the dbuser credentials and sync them as a Kubernetes Cluster for the
3+
# Atlas Database User CRD to use it and produce a connection string from it
4+
kind: Pod
5+
apiVersion: v1
6+
metadata:
7+
name: secret-placeholder
8+
spec:
9+
containers:
10+
- image: mongodb/atlas
11+
command: ["sleep", "infinity"]
12+
name: secret-placeholder
13+
volumeMounts:
14+
- name: secrets-store-mount
15+
mountPath: "/mnt/secrets-store"
16+
readOnly: true
17+
volumes:
18+
- name: secrets-store-mount
19+
csi:
20+
driver: secrets-store.csi.k8s.io
21+
readOnly: true
22+
volumeAttributes:
23+
secretProviderClass: dbuser # defined at dbuser.yaml

0 commit comments

Comments
 (0)