New to KubeVault? Please start here.
You can easily manage AWS secret engine using Vault operator.
You should be familiar with the following CRD:
Before you begin:
Install Vault operator in your cluster following the steps here.
Deploy Vault. It could be in the Kubernetes cluster or external.
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 will create role using AWSRole and issue credential using AWSAccessKeyRequest. For this tutorial, we are going to deploy Vault using Vault operator.
$ cat examples/guides/secret-engins/aws/vault.yaml
apiVersion: kubevault.com/v1alpha1
kind: VaultServer
metadata:
name: vault
namespace: demo
spec:
nodes: 1
version: "1.0.0"
backend:
inmem: {}
unsealer:
secretShares: 4
secretThreshold: 2
mode:
kubernetesSecret:
secretName: vault-keys
$ kubectl get vaultserverversions/1.0.0 -o yaml
apiVersion: catalog.kubevault.com/v1alpha1
kind: VaultServerVersion
metadata:
name: 1.0.0
spec:
exporter:
image: kubevault/vault-exporter:0.1.0
unsealer:
image: kubevault/vault-unsealer:0.2.0
vault:
image: vault:1.0.0
version: 1.0.0
$ kubectl apply -f examples/guides/secret-engins/aws/vault.yaml
vaultserver.kubevault.com/vault created
$ kubectl get vaultserver/vault -n demo
NAME NODES VERSION STATUS AGE
vault 1 1.0.0 Running 1h
Using AWSRole, you can configure root IAM credentials and create role. In this tutorial, we are going to create demo-role
in demo
namespace.
apiVersion: engine.kubevault.com/v1alpha1
kind: AWSRole
metadata:
name: demo-role
namespace: demo
spec:
credentialType: iam_user
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
authManagerRef:
name: vault-app
namespace: demo
config:
credentialSecret: aws-cred
region: us-east-1
leaseConfig:
lease: 1h
leaseMax: 1h
Here, spec.config.credentialSecret
will be used to configure root iam credentials.
$ cat examples/guides/secret-engins/aws/aws-cred.yaml
apiVersion: v1
data:
access_key: QUAAAAA=
secret_key: LKUHGHGJAAAAAAAAAAAAAAAAA==
kind: Secret
metadata:
name: aws-cred
namespace: demo
type: Opaque
$ kubectl apply -f examples/guides/secret-engins/aws/aws-cred.yaml
spec.authManagerRef
is the reference of AppBinding containing Vault connection and credential information. See here for Vault authentication using AppBinding in Vault operator.
$ cat examples/guides/secret-engins/aws/vault-app.yaml
apiVersion: appcatalog.appscode.com/v1alpha1
kind: AppBinding
metadata:
name: vault-app
namespace: demo
spec:
clientConfig:
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1RENDQWFDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFOTVFzd0NRWURWUVFERXdKallUQWUKRncweE9ERXlNamN3TkRVNU1qVmFGdzB5T0RFeU1qUXdORFU1TWpWYU1BMHhDekFKQmdOVkJBTVRBbU5oTUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBMVhid2wyQ1NNc2VQTU5RRzhMd3dUVWVOCkI1T05oSTlDNzFtdUoyZEZjTTlUc1VDQnlRRk1weUc5dWFvV3J1ZDhtSWpwMVl3MmVIUW5udmoybXRmWGcrWFcKSThCYkJUaUFKMWxMMFE5MlV0a1BLczlXWEt6dTN0SjJUR1hRRDhhbHZhZ0JrR1ViOFJYaUNqK2pnc1p6TDRvQQpNRWszSU9jS0xnMm9ldFZNQ0hwNktpWTBnQkZiUWdJZ1A1TnFwbksrbU02ZTc1ZW5hWEdBK2V1d09FT0YwV0Z2CmxGQmgzSEY5QlBGdTJKbkZQUlpHVDJKajBRR1FNeUxodEY5Tk1pZTdkQnhiTWhRVitvUXp2d1EvaXk1Q2pndXQKeDc3d29HQ2JtM0o4cXRybUg2Tjl6Tlc3WlR0YTdLd05PTmFoSUFEMSsrQm5rc3JvYi9BYWRKT0tMN2dLYndJRApBUUFCb3lNd0lUQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHCjl3MEJBUXNGQUFPQ0FRRUFXeWFsdUt3Wk1COWtZOEU5WkdJcHJkZFQyZnFTd0lEOUQzVjN5anBlaDVCOUZHN1UKSS8wNmpuRVcyaWpESXNHNkFDZzJKOXdyaSttZ2VIa2Y2WFFNWjFwZHRWeDZLVWplWTVnZStzcGdCRTEyR2NPdwpxMUhJb0NrekVBMk5HOGRNRGM4dkQ5WHBQWGwxdW5veWN4Y0VMeFVRSC9PRlc4eHJxNU9vcXVYUkxMMnlKcXNGCmlvM2lJV3EvU09Yajc4MVp6MW5BV1JSNCtSYW1KWjlOcUNjb1Z3b3R6VzI1UWJKWWJ3QzJOSkNENEFwOUtXUjUKU2w2blk3NVMybEdSRENsQkNnN2VRdzcwU25seW5mb3RaTUpKdmFzbStrOWR3U0xtSDh2RDNMMGNGOW5SOENTSgpiTjBiZzczeVlWRHgyY3JRYk0zcko4dUJnY3BsWlRpUy91SXJ2QT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
service:
name: vault
port: 8200
scheme: HTTPS
parameters:
serviceAccountName: demo-sa
policyControllerRole: aws-role
authPath: kubernetes
$ kubectl apply -f examples/guides/secret-engins/aws/vault-app.yaml
appbinding.appcatalog.appscode.com/vault-app create
You need to create demo-sa
serviceaccount by running following command:
$ kubectl create serviceaccount -n demo demo-sa
serviceaccount/demo-sa created
demo-sa
serviceaccount in the above AppBinding need to have the policy with following capabilities in Vault.
path "sys/mounts" {
capabilities = ["read", "list"]
}
path "sys/mounts/*" {
capabilities = ["create", "read", "update", "delete"]
}
path "aws/config/root" {
capabilities = ["create", "read", "update", "delete"]
}
path "aws/config/lease" {
capabilities = ["create", "read", "update", "delete"]
}
path "aws/roles/*" {
capabilities = ["create", "update", "read", "delete"]
}
path "aws/creds/*" {
capabilities = ["read"]
}
path "sys/leases/revoke/*" {
capabilities = ["update"]
}
You can manage policy in Vault using Vault operator, see here.
To create policy with above capabilities run following command
$ kubectl apply -f examples/guides/secret-engins/aws/policy.yaml
vaultpolicy.policy.kubevault.com/aws-role-policy created
vaultpolicybinding.policy.kubevault.com/aws-role created
Now, we are going to create demo-role
.
$ cat examples/guides/secret-engins/aws/demo-role.yaml
apiVersion: engine.kubevault.com/v1alpha1
kind: AWSRole
metadata:
name: demo-role
namespace: demo
spec:
credentialType: iam_user
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
authManagerRef:
name: vault-app
namespace: demo
config:
credentialSecret: aws-cred
region: us-east-1
leaseConfig:
lease: 1h
leaseMax: 1h
$ kubectl apply -f examples/guides/secret-engins/aws/demo-role.yaml
awsrole.engine.kubevault.com/demo-role created
Check whether AWSRole is successful.
$ kubectl get awsroles/demo-role -n demo -o json | jq '.status'
{
"observedGeneration": "1$6208915667192219204",
"phase": "Success"
}
To resolve the naming conflict, name of the role in Vault will follow this format: k8s.{spec.clusterName or -}.{spec.namespace}.{spec.name}
.
$ vault list aws/roles
Keys
----
k8s.-.demo.demo-role
$ vault read aws/roles/k8s.-.demo.demo-role
Key Value
--- -----
credential_types [iam_user]
default_sts_ttl 0s
max_sts_ttl 0s
policy_arns <nil>
policy_document {"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"ec2:*","Resource":"*"}]}
role_arns <nil>
If we delete AWSRole, then respective role will be deleted from Vault.
$ kubectl delete -f examples/guides/secret-engins/aws/demo-role.yaml
awsrole.engine.kubevault.com "demo-role" deleted
# check in vault whether role exists
$ vault read aws/roles/k8s.-.demo.demo-role
Error reading aws/roles/k8s.-.demo.demo-role: Error making API request.
URL: GET https://127.0.0.1:8200/v1/aws/roles/k8s.-.demo.demo-role
Code: 400. Errors:
* Role 'k8s.-.demo.demo-role' not found
$ vault list aws/roles
No value found at aws/roles/
Using AWSAccessKeyRequest, you can issue AWS credential from Vault. In this tutorial, we are going to issue AWS credential by creating demo-cred
AWSAccessKeyRequest in demo
namespace.
apiVersion: engine.kubevault.com/v1alpha1
kind: AWSAccessKeyRequest
metadata:
name: demo-cred
namespace: demo
spec:
roleRef:
name: demo-role
namespace: demo
subjects:
- kind: User
name: nahid
apiGroup: rbac.authorization.k8s.io
Here, spec.roleRef
is the reference of AWSRole against which credential will be issued. spec.subjects
is the reference to the object or user identities a role binding applies to and it will have read access of the credential secret. Also, Vault operator will use AppBinding reference from AWSRole which is specified in spec.roleRef
.
Now, we are going to create demo-cred
AWSAccessKeyRequest.
$ kubectl apply -f examples/guides/secret-engins/aws/demo-cred.yaml
awsaccesskeyrequest.engine.kubevault.com/demo-cred created
$ kubectl get awsaccesskeyrequests -n demo
NAME AGE
demo-cred 3s
AWS credential will not be issued until it is approved. To approve it, you have to add Approved
in status.conditions[].type
field. You can use KubeVault CLI as kubectl plugin to approve or deny DatabaseAccessRequest.
# using KubeVault cli as kubectl plugin to approve request
$ kubectl vault approve awsaccesskeyrequest demo-cred -n demo
approved
$ kubectl get awsaccesskeyrequest demo-cred -n demo -o yaml
apiVersion: engine.kubevault.com/v1alpha1
kind: AWSAccessKeyRequest
metadata:
finalizers:
- awsaccesskeyrequest.engine.kubevault.com
name: demo-cred
namespace: demo
spec:
roleRef:
name: demo-role
namespace: demo
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: nahid
status:
conditions:
- type: Approved
Once AWSAccessKeyRequest is approved, Vault operator will issue credential from Vault and create a secret containing the credential. Also it will create rbac role and rolebinding so that spec.subjects
can access secret. You can view the information in status
field.
$ kubectl get awsaccesskeyrequest/demo-cred -n demo -o json | jq '.status'
{
"conditions": [
{
"type": "Approved"
}
],
"lease": {
"duration": "1h0m0s",
"id": "aws/creds/k8s.-.demo.demo-role/1KljT3F5ZrYMC66JsPIgOgXr",
"renewable": true
},
"secret": {
"name": "demo-cred-wttlrm"
}
}
$ kubectl get secrets/demo-cred-wttlrm -n demo -o yaml
apiVersion: v1
data:
access_key: QUtJQUo3TVVIyVFE=
secret_key: ZFdrNG04Rk05ZkhDbjBlZWNkMk5KUkFBaXB5TkUybw==
security_token: null
kind: Secret
metadata:
name: demo-cred-wttlrm
namespace: demo
type: Opaque
If AWSAccessKeyRequest is deleted, then credential lease (if have any) will be revoked.
$ kubectl delete awsaccesskeyrequest/demo-cred -n demo
awsaccesskeyrequest.engine.kubevault.com "demo-cred" deleted
If AWSAccessKeyRequest is Denied
, then Vault operator will not issue any credential.
Note: Once AWSAccessKeyRequest is
Approved
orDenied
, you can not changespec.roleRef
andspec.subjects
field.