Using Secrets Manager
Install the ASCP
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --set grpcSupportedProviders="aws" --set syncSecret.enabled="true"
helm repo add aws-secrets-manager https://aws.github.io/secrets-store-csi-driver-provider-aws
helm install -n kube-system secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws
Create IAM policy for accessing Secrets Manager
POLICY_NAME="<policy name>"
PROJECT_NAME="<project name>"
REGION="<region>"
SECRET_ARN="<secret arn>"
curl -LO https://raw.githubusercontent.com/marcus16-kang/aws-resources-example/main/scripts/eks/secrets-manager-policy.json
sed -i "s|SECRET_ARN|$SECRET_ARN|" secrets-manager-policy.json
POLICY_ARN=$(aws iam create-policy \
--policy-name $POLICY_NAME \
--policy-document file://aws-load-balancer-controller-iam-policy.json \
--query 'Policy.Arn' \
--output text \
# --tags Key=project,Value=$PROJECT_NAME \ # AWS CLI v2
)
$POLICY_NAME="<policy name>"
$PROJECT_NAME="<project name>"
$REGION="<region>"
$SECRET_ARN="<secret arn>"
curl.exe -LO https://raw.githubusercontent.com/marcus16-kang/aws-resources-example/main/scripts/eks/secrets-manager-policy.json
(Get-Content secrets-manager-policy.json) | Foreach-Object { $_ -replace "SECRET_ARN", "$SECRET_ARN" } | Set-Content secrets-manager-policy.json
$POLICY_ARN = aws iam create-policy `
--policy-name $POLICY_NAME `
--policy-document secrets-manager-policy.json `
--query 'Policy.Arn' `
--output text `
--tags Key=project,Value=$PROJECT_NAME
Create Service Account
CLUSTER_NAME="<cluster name>"
SERVICE_ACCOUNT_NAME="<service account name>"
NAMESPACE_NAME="<namespace name>"
ROLE_NAME="<role name>"
PROJECT_NAME="<project name>"
REGION="<region>"
eksctl create iamserviceaccount \
--cluster $CLUSTER_NAME \
--name $SERVICE_ACCOUNT_NAME \
--namespace $NAMESPACE_NAME \
--attach-policy-arn $POLICY_ARN \
--role-name $ROLE_NAME \
--tags project=$PROJECT_NAME \
--region $REGION \
--override-existing-serviceaccounts \
--approve
$CLUSTER_NAME="<cluster name>"
$SERVICE_ACCOUNT_NAME="<service account name>"
$NAMESPACE_NAME="<namespace name>"
$ROLE_NAME="<role name>"
$PROJECT_NAME="<project name>"
$REGION="<region>"
eksctl create iamserviceaccount `
--cluster $CLUSTER_NAME `
--name $SERVICE_ACCOUNT_NAME `
--namespace $NAMESPACE_NAME `
--attach-policy-arn $POLICY_ARN `
--role-name $ROLE_NAME `
--tags project=$PROJECT_NAME `
--region $REGION `
--override-existing-serviceaccounts `
--approve
Use Secrets Manager's Secret Values
secret-provider-class.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: <secretproviderclass name>
namespace: <namespace name>
spec:
provider: aws
secretObjects:
- data:
- key: DB_USERNAME
objectName: username
- key: DB_PASSWORD
objectName: password
- key: DB_ENGINE
objectName: engine
- key: DB_HOST
objectName: host
- key: DB_PORT
objectName: port
- key: DB_CLUSTER_IDENTIFIER
objectName: dbClusterIdentifier
secretName: <secret name>
type: Opaque
parameters:
objects: |
- objectName: "<secret arn>"
objectType: "secretsmanager"
jmesPath:
- path: username
objectAlias: username
- path: password
objectAlias: password
- path: engine
objectAlias: engine
- path: host
objectAlias: host
- path: to_string(port)
objectAlias: port
- path: dbClusterIdentifier
objectAlias: dbClusterIdentifier
Note
You can check JMESPath in HERE.
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: <pod name>
namespace: <namespace name>
labels:
app: <pod name>
spec:
serviceAccountName: <serviceaccount name>
containers:
- name: busybox
image: busybox
command: # override Dockerfile `ENTRYPOINT`
- "sleep"
- "3600"
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: <secret name>
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: <secret name>
key: DB_PASSWORD
- name: DB_ENGINE
valueFrom:
secretKeyRef:
name: <secret name>
key: DB_ENGINE
- name: DB_HOST
valueFrom:
secretKeyRef:
name: <secret name>
key: DB_HOST
- name: DB_PORT
valueFrom:
secretKeyRef:
name: <secret name>
key: DB_PORT
- name: DB_CLUSTER_IDENTIFIER
valueFrom:
secretKeyRef:
name: <secret name>
key: DB_CLUSTER_IDENTIFIER
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "<secret name>"