$ oc get authentication.config.openshift.io cluster -o json \
| jq .spec.serviceAccountIssuer
The AWS Secrets and Configuration Provider (ASCP) provides a way to expose AWS Secrets as Kubernetes storage volumes. With the ASCP, you can store and manage your secrets in Secrets Manager and then retrieve them through your workloads running on ROSA.
This is made even easier and more secure through the use of AWS STS and Kubernetes PodIdentity.
Validate that your cluster has STS:
$ oc get authentication.config.openshift.io cluster -o json \
| jq .spec.serviceAccountIssuer
You should see something like the following, if not you should not proceed, instead look to the Red Hat documentation on creating an STS cluster.
"https://xxxxx.cloudfront.net/xxxxx"
Set SecurityContextConstraints to allow the CSI driver to run:
$ oc new-project csi-secrets-store
$ oc adm policy add-scc-to-user privileged \
system:serviceaccount:csi-secrets-store:secrets-store-csi-driver
$ oc adm policy add-scc-to-user privileged \
system:serviceaccount:csi-secrets-store:csi-secrets-store-provider-aws
Create some environment variables to refer to later:
$ export REGION=$(oc get infrastructure cluster -o=jsonpath="{.status.platformStatus.aws.region}")
$ export OIDC_ENDPOINT=$(oc get authentication.config.openshift.io cluster \
-o jsonpath='{.spec.serviceAccountIssuer}' | sed 's|^https://||')
$ export AWS_ACCOUNT_ID=`aws sts get-caller-identity --query Account --output text`
$ export AWS_PAGER=""
Use Helm to register the secrets store CSI driver:
$ helm repo add secrets-store-csi-driver \
https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
Update your Helm repositories:
$ helm repo update
Install the secrets store CSI driver:
$ helm upgrade --install -n csi-secrets-store \
csi-secrets-store-driver secrets-store-csi-driver/secrets-store-csi-driver
Deploy the AWS provider:
$ oc -n csi-secrets-store apply -f \
https://raw.githubusercontent.com/rh-mobb/documentation/main/content/misc/secrets-store-csi/aws-provider-installer.yaml
Check that both Daemonsets are running:
$ oc -n csi-secrets-store get ds \
csi-secrets-store-provider-aws \
csi-secrets-store-driver-secrets-store-csi-driver
Label the Secrets Store CSI Driver to allow use with the restricted pod security profile:
$ oc label csidriver.storage.k8s.io/secrets-store.csi.k8s.io security.openshift.io/csi-ephemeral-volume-profile=restricted
Create a secret in Secrets Manager:
$ SECRET_ARN=$(aws --region "$REGION" secretsmanager create-secret \
--name MySecret --secret-string \
'{"username":"shadowman", "password":"hunter2"}' \
--query ARN --output text)
$ echo $SECRET_ARN
Create an IAM Access Policy document:
$ cat << EOF > policy.json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": ["$SECRET_ARN"]
}]
}
EOF
Create an IAM Access Policy:
$ POLICY_ARN=$(aws --region "$REGION" --query Policy.Arn \
--output text iam create-policy \
--policy-name openshift-access-to-mysecret-policy \
--policy-document file://policy.json)
$ echo $POLICY_ARN
Create an IAM Role trust policy document:
The trust policy is locked down to the default service account of a namespace you will create later. |
$ cat <<EOF > trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Condition": {
"StringEquals" : {
"${OIDC_ENDPOINT}:sub": ["system:serviceaccount:my-application:default"]
}
},
"Principal": {
"Federated": "arn:aws:iam::$AWS_ACCOUNT_ID:oidc-provider/${OIDC_ENDPOINT}"
},
"Action": "sts:AssumeRoleWithWebIdentity"
}
]
}
EOF
Create an IAM role:
$ ROLE_ARN=$(aws iam create-role --role-name openshift-access-to-mysecret \
--assume-role-policy-document file://trust-policy.json \
--query Role.Arn --output text)
$ echo $ROLE_ARN
Attach the role to the policy:
$ aws iam attach-role-policy --role-name openshift-access-to-mysecret \
--policy-arn $POLICY_ARN
Create an OpenShift project:
$ oc new-project my-application
Annotate the default service account to use the STS Role:
$ oc annotate -n my-application serviceaccount default \
eks.amazonaws.com/role-arn=$ROLE_ARN
Create a secret provider class to access our secret:
$ cat << EOF | oc apply -f -
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: my-application-aws-secrets
spec:
provider: aws
parameters:
objects: |
- objectName: "MySecret"
objectType: "secretsmanager"
EOF
Create a Deployment using our secret:
$ cat << EOF | oc apply -f -
apiVersion: v1
kind: Pod
metadata:
name: my-application
labels:
app: my-application
spec:
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "my-application-aws-secrets"
containers:
- name: my-application-deployment
image: k8s.gcr.io/e2e-test-images/busybox:1.29
command:
- "/bin/sleep"
- "10000"
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
EOF
Verify the Pod has the secret mounted:
$ oc exec -it my-application -- cat /mnt/secrets-store/MySecret
Delete the application:
$ oc delete project my-application
Delete the secrets store csi driver:
$ helm delete -n csi-secrets-store csi-secrets-store-driver
Delete Security Context Constraints:
$ oc adm policy remove-scc-from-user privileged \
system:serviceaccount:csi-secrets-store:secrets-store-csi-driver
$ oc adm policy remove-scc-from-user privileged \
system:serviceaccount:csi-secrets-store:csi-secrets-store-provider-aws
Delete the AWS provider:
$ oc -n csi-secrets-store delete -f \
https://raw.githubusercontent.com/rh-mobb/documentation/main/content/misc/secrets-store-csi/aws-provider-installer.yaml
Delete AWS Roles and Policies:
$ aws iam detach-role-policy --role-name openshift-access-to-mysecret \
--policy-arn $POLICY_ARN
$ aws iam delete-role --role-name openshift-access-to-mysecret
$ aws iam delete-policy --policy-arn $POLICY_ARN
Delete the Secrets Manager secret:
$ aws secretsmanager --region $REGION delete-secret --secret-id $SECRET_ARN