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.1.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
ApprovedorDenied, you can not changespec.roleRefandspec.subjectsfield.