New to KubeVault? Please start here.
Manage MariaDB credentials using the KubeVault operator
MariaDB is one of the supported plugins for the database secrets engine. This plugin generates database credentials dynamically based on configured roles for the MariaDB database. You can easily manage MariaDB secret engine using the KubeVault operator.
You need to be familiar with the following CRDs:
Before you begin
- Install KubeVault operator in your cluster from here.
To keep things isolated, we are going to use a separate namespace called demo
throughout this tutorial.
$ kubectl create ns demo
namespace/demo created
In this tutorial, we are going to create a role using MariaDB and issue credential using SecretAccessRequest.
Vault Server
If you don’t have a Vault Server, you can deploy it by using the KubeVault operator.
The KubeVault operator can manage policies and secret engines of Vault servers which are not provisioned by the KubeVault operator. You need to configure both the Vault server and the cluster so that the KubeVault operator can communicate with your Vault server.
Now, we have the AppBinding that contains connection and authentication information about the Vault server.
$ kubectl get appbinding -n demo
NAME AGE
vault 50m
$ kubectl get appbinding -n demo vault -o yaml
apiVersion: appcatalog.appscode.com/v1alpha1
kind: AppBinding
metadata:
creationTimestamp: "2021-08-16T08:23:38Z"
generation: 1
labels:
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: kubevault.com
app.kubernetes.io/name: vaultservers.kubevault.com
name: vault
namespace: demo
ownerReferences:
- apiVersion: kubevault.com/v1alpha1
blockOwnerDeletion: true
controller: true
kind: VaultServer
name: vault
uid: 6b405147-93da-41ff-aad3-29ae9f415d0a
resourceVersion: "602898"
uid: b54873fd-0f34-42f7-bdf3-4e667edb4659
spec:
clientConfig:
service:
name: vault
port: 8200
scheme: http
parameters:
apiVersion: config.kubevault.com/v1alpha1
kind: VaultServerConfiguration
kubernetes:
serviceAccountName: vault
tokenReviewerServiceAccountName: vault-k8s-token-reviewer
usePodServiceAccountForCSIDriver: true
path: kubernetes
vaultRole: vault-policy-controller
Enable and Configure MariaDB Secret Engine
When a SecretEngine crd object is created, the KubeVault operator will enable a secret engine on specified path and configure the secret engine with given configurations.
A sample SecretEngine object for the MariaDB secret engine:
apiVersion: engine.kubevault.com/v1alpha1
kind: SecretEngine
metadata:
name: mariadb-engine
namespace: demo
spec:
vaultRef:
name: vault
mariadb:
databaseRef:
name: mariadb
namespace: demo
pluginName: "mysql-database-plugin"
Let’s deploy SecretEngine:
$ kubectl apply -f docs/examples/guides/secret-engines/mariadb/secretengine.yaml
secretengine.engine.kubevault.com/mariadb-engine created
Wait till the status become Success
:
$ kubectl get secretengines -n demo
NAME STATUS AGE
mariadb-engine Success 10s
Since the status is Success
, the MariaDB secret engine is enabled and successfully configured. You can use kubectl describe secretengine -n <namepsace> <name>
to check for error events, if any.
Create MariaDB Role
By using MariaDBRole, you can create a role on the Vault server in Kubernetes native way.
A sample MariaDBRole object is given below:
apiVersion: engine.kubevault.com/v1alpha1
kind: MariaDBRole
metadata:
name: mariadb-superuser-role
namespace: demo
spec:
secretEngineRef:
name: sql-secrt-engine
creationStatements:
- "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';"
- "GRANT SELECT ON *.* TO '{{name}}'@'%';"
defaultTTL: 1h
maxTTL: 24h
Let’s deploy MariaDBRole:
$ kubectl apply -f docs/examples/guides/secret-engines/mariadb/secretenginerole.yaml
mariadbrole.engine.kubevault.com/mariadb-superuser-role created
$ kubectl get mariadbrole -n demo
NAME STATUS AGE
mariadb-superuser-role Success 34m
You can also check from Vault that the role is created.
To resolve the naming conflict, name of the role in Vault will follow this format: k8s.{clusterName}.{metadata.namespace}.{metadata.name}
.
Don’t have Vault CLI? Download and configure it as described here
$ vault list your-database-path/roles
Keys
----
k8s.-.demo.mariadb-superuser-role
$ vault read your-database-path/roles/k8s.-.demo.mariadb-superuser-role
Key Value
--- -----
creation_statements [CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT ON *.* TO '{{name}}'@'%';]
db_name k8s.-.demo.mariadb
default_ttl 1h
max_ttl 24h
renew_statements []
revocation_statements []
rollback_statements []
If we delete the MariaDB, then the respective role will be deleted from the Vault.
$ kubectl delete mariadbrole -n demo mariadb-superuser-role
mariadbrole.engine.kubevault.com "mariadb-superuser-role" deleted
Check from Vault whether the role exists:
$ vault read your-database-path/roles/k8s.-.demo.mariadb-superuser-role
No value found at your-database-path/roles/k8s.-.demo.mariadb-superuser-role
$ vault list your-database-path/roles
No value found at your-database-path/roles/
Generate MariaDB credentials
Here, we are going to make a request to Vault for MariaDB credentials by creating mariadb-cred-rqst
SecretAccessRequest in demo
namespace.
apiVersion: engine.kubevault.com/v1alpha1
kind: SecretAccessRequest
metadata:
name: mariadb-cred-rqst
namespace: demo
spec:
roleRef:
kind: MariaDBRole
name: mariadb-superuser-role
subjects:
- kind: ServiceAccount
name: demo-sa
namespace: demo
Here, spec.roleRef
is the reference of MariaDB against which credentials will be issued. spec.subjects
is the reference to the object or user identities a role binding applies to it will have read access of the credential secret.
Now, we are going to create SecretAccessRequest.
$ kubectl apply -f docs/examples/guides/secret-engines/mariadb/mariadbaccessrequest.yaml
secretaccessrequest.engine.kubevault.com/mariadb-cred-rqst created
$ kubectl get secretaccessrequest -n demo
NAME AGE
mariadb-cred-rqst 72m
Database credentials will not be issued until it is approved. The KubeVault operator will watch for the approval in the status.conditions[].type
field of the request object. You can use KubeVault CLI, a kubectl plugin, to approve or deny SecretAccessRequest.
# using KubeVault CLI as kubectl plugin to approve request
$ kubectl vault approve secretaccessrequest mariadb-cred-rqst -n demo
approved
$ kubectl get secretaccessrequest -n demo mariadb-cred-rqst -o yaml
apiVersion: engine.kubevault.com/v1alpha1
kind: SecretAccessRequest
metadata:
name: mariadb-cred-rqst
namespace: demo
spec:
roleRef:
kind: MariaDBRole
name: mariadb-superuser-role
namespace: demo
subjects:
- kind: ServiceAccount
name: demo-sa
namespace: demo
status:
conditions:
- lastUpdateTime: "2020-11-18T06:41:57Z"
message: This was approved by kubectl vault approve secretaccessrequest
reason: KubectlApprove
type: Approved
lease:
duration: 1h0m0s
id: your-database-path/creds/k8s.-.demo.mariadb-superuser-role/ni3TCo2HkSwCUb8kmQuvIDdx
renewable: true
secret:
name: mariadb-cred-rqst-gy66wq
Once SecretAccessRequest is approved, the KubeVault operator will issue credentials from Vault and create a secret containing the credential. It will also create a role and rolebinding so that spec.subjects
can access secret. You can view the information in the status
field.
$ kubectl get secretaccessrequest mariadb-cred-rqst -n demo -o json | jq '.status'
{
"conditions": [
{
"lastUpdateTime": "2019-11-18T06:41:57Z",
"message": "This was approved by kubectl vault approve secretaccessrequest",
"reason": "KubectlApprove",
"type": "Approved"
}
],
"lease": {
"duration": "1h0m0s",
"id": "your-database-path/creds/k8s.-.demo.mariadb-superuser-role/ni3TCo2HkSwCUb8kmQuvIDdx",
"renewable": true
},
"secret": {
"name": "mariadb-cred-rqst-gy66wq"
}
}
$ kubectl get secret -n demo mariadb-cred-rqst-gy66wq -o yaml
apiVersion: v1
data:
password: QTFhLVBkZGlsZFFxa0o1cnlvR20=
username: di1rdWJlcm5ldGVzLWRlbW8TE1NzQwNTkzMTc=
kind: Secret
metadata:
name: mariadb-cred-rqst-gy66wq
namespace: demo
ownerReferences:
- apiVersion: engine.kubevault.com/v1alpha1
controller: true
kind: SecretAccessRequest
name: mariadb-cred-rqst
uid: 54ce63ca-d0e7-4b97-9085-b52eb3cb334f
type: Opaque
If SecretAccessRequest is deleted, then credential lease (if any) will be revoked.
$ kubectl delete secretaccessrequest -n demo mariadb-cred-rqst
secretaccessrequest.engine.kubevault.com "mariadb-cred-rqst" deleted
If SecretAccessRequest is Denied
, then the KubeVault operator will not issue any credential.
$ kubectl vault deny secretaccessrequest mariadb-cred-rqst -n demo
Denied
Note: Once SecretAccessRequest is
Approved
, you cannot changespec.roleRef
andspec.subjects
field.