Managing database users within complex CICD pipelines and GitOps workflows has long been a challenge for MongoDB deployments. With Percona Operator for MongoDB 1.17, we introduce a new feature, currently in technical preview, that streamlines this process. Now, you can create the database users you need directly within the operator, eliminating the need to wait for cluster deployment and manual intervention. This enhancement simplifies your workflows, improves the declarative nature of your infrastructure, and paves the way for smoother user management.
How to use
In this blog post, we will demonstrate how to use this feature, what capabilities it provides, and what use cases it should be used for. We will start by deploying the Operator, proceed with cluster creation with the users defined, and then move on to updates. You can find all the YAML manifests in this GitHub repository.
Make sure that you use the Operator from 1.17 and above. Deploy the Operator:
1 |
kubectl apply -f https://raw.githubusercontent.com/percona/percona-server-mongodb-operator/v1.17.0/deploy/bundle.yaml |
To create the user my-user with built-in MongoDB roles, you need to add spec.users section in the custom resource manifest:
1 2 3 4 5 6 7 8 9 10 11 |
users: - name: my-user db: admin roles: - name: clusterAdmin db: admin - name: userAdminAnyDatabase db: admin passwordSecretRef: name: my-custom-user-secret key: password |
All the fields are self-explanatory. In the roles section, you define the roles and the database to which the user should have access.
passwordSecretRef – References a Secret resource with a password key defining the user password. My Secret resource looks like this:
1 2 3 4 5 6 7 |
apiVersion: v1 kind: Secret metadata: name: my-custom-user-secret type: Opaque data: password: BASE64_ENCODED_STRING |
Create the Secret first (this Secret is for demonstration purposes only, for security reasons, never store your secret resources in GitHub):
1 |
kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/mongo-k8s-user-mgmt/00-user-secret-yaml |
Deploy the cluster:
1 |
kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/mongo-k8s-user-mgmt/01-cr-user.yaml |
Verify
Verify that the user is created by connecting to the cluster. You can follow our documentation.
1 |
kubectl run -i --rm --tty percona-client --image=percona/percona-server-mongodb:7.0 --restart=Never -- bash -il |
Connect to the cluster with the user and password that you defined before:
1 |
mongosh "mongodb://<USER>:<PASSWORD>@my-cluster-name-mongos.default.svc.cluster.local/admin?ssl=false" |
Get info about the user:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[direct: mongos] admin> db.getUsers() ... { _id: 'admin.my-user', userId: UUID('584fa9fa-d6bf-42fc-8f68-dcfd3050cc13'), user: 'my-user', db: 'admin', roles: [ { role: 'userAdminAnyDatabase', db: 'admin' }, { role: 'clusterAdmin', db: 'admin' } ], mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ] }, ... |
Modify
You can change the user’s password in the Secret resource. The Operator will automatically change it.
1 |
kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/mongo-k8s-user-mgmt/03-user-secret.yaml |
If you change the user’s name in spec.users.name, the Operator will just create another user. Read below for more information about user deletion.
In the tech preview, we do not support altering the user roles. We will add this functionality in the following versions. For now, you can do it manually in the database.
The Operator prioritizes the user configuration defined in the custom resource. Any direct changes made to the database will be overwritten to maintain consistency with the custom resource. Always update the custom resource first to ensure your user configurations persist. This is valid only for the users originally created through a custom resource. You can still create new users in the database manually with their own permissions; the Operator will not perform any changes to those.
Delete
Operator will not delete the user from the database, even if you delete it from the custom resource manifest. We don’t do it for security reasons and to minimize the possible impact on the applications.
To delete a user from the database, first delete it from the custom resource manifest and then manually delete it from the database.
1 |
kubectl apply -f kubectl apply -f https://raw.githubusercontent.com/spron-in/blog-data/master/mongo-k8s-user-mgmt/04-cr-user.yaml |
Login into MongoDB with another user (for example, you can use the userAdmin user that Operator creates by default) and delete the user:
1 2 3 4 5 6 7 8 9 10 11 12 |
[direct: mongos] admin> db.dropUser("my-user"); { ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1725631591, i: 5 }), signature: { hash: Binary.createFromBase64('VNs4RYQJU2yj3uNXr7FLk8yKdSY=', 0), keyId: Long('7411526566775095318') } }, operationTime: Timestamp({ t: 1725631591, i: 5 }) } |
What’s next
In the following releases, we are going to improve user management:
- Enable users to create custom roles through Custom Resource for more granular permissions control. JIRA.
- Allow users to alter the existing roles assigned to the user. That is a limitation in a tech preview; it is possible to perform these changes manually.
Conclusion
The ability to create database users directly within the Percona Operator for MongoDB is a significant step forward in streamlining MongoDB deployments and enhancing your CICD and GitOps workflows. By eliminating manual steps and promoting a declarative approach, this new feature simplifies user management and empowers you to focus on building and scaling your applications.