DEV Community

suin
suin

Posted on

Sync Kubernetes Secrets to AWS Secrets Manager Using external-secrets PushSecret

When managing sensitive information in Kubernetes, you can use an operator called external-secrets to integrate with external secret providers like AWS Secrets Manager.

While the common usage pattern is to synchronize sensitive information stored in AWS Secrets Manager as Kubernetes Secrets, this article introduces PushSecret, which enables reverse synchronization - pushing Kubernetes Secrets to AWS Secrets Manager.

Let's explore the basic usage of PushSecret.

Prerequisites

Installing external-secrets

First, install external-secrets using Helm:

helm repo add external-secrets https://charts.external-secrets.io

helm install external-secrets \
   external-secrets/external-secrets \
    -n external-secrets \
    --create-namespace
Enter fullscreen mode Exit fullscreen mode

Setting Up AWS Credentials

Set AWS credentials as environment variables and verify they are configured correctly:

export AWS_ACCESS_KEY_ID=xxxx
export AWS_SECRET_ACCESS_KEY=xxxx
export AWS_REGION=ap-northeast-1

# Verify credentials
aws sts get-caller-identity
Enter fullscreen mode Exit fullscreen mode

Next, store these credentials as a Kubernetes Secret:

kubectl create secret generic aws-credentials \
  --from-literal=access-key-id=${AWS_ACCESS_KEY_ID} \
  --from-literal=secret-access-key=${AWS_SECRET_ACCESS_KEY}
Enter fullscreen mode Exit fullscreen mode

Configuring SecretStore

Create a SecretStore to connect to AWS Secrets Manager:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secretsmanager
  namespace: default
spec:
  provider:
    aws:
      service: SecretsManager
      region: ap-northeast-1
      auth:
        secretRef:
          accessKeyIDSecretRef:
            name: aws-credentials
            key: access-key-id
          secretAccessKeySecretRef:
            name: aws-credentials
            key: secret-access-key
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f secret-store.yaml
Enter fullscreen mode Exit fullscreen mode

Configuring PushSecret

Create a PushSecret to synchronize Kubernetes Secrets to AWS Secrets Manager:

apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: pushsecret-example
  namespace: default
spec:
  # Overwrite existing secrets in provider during sync
  updatePolicy: Replace
  # Delete provider secrets when PushSecret is deleted
  deletionPolicy: Delete
  # Resync interval
  refreshInterval: 10s
  # SecretStore to push secrets to
  secretStoreRefs:
    - name: aws-secretsmanager
      kind: SecretStore
  # Target Secret for synchronization
  selector:
    secret:
      name: my-secret
  # Key configuration for synchronization
  data:
    - match:
        secretKey: foo  # Secret key
        remoteRef:
          remoteKey: my-secret-foo  # AWS Secrets Manager secret name
      metadata:
        secretPushFormat: string
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f push-secret.yaml
Enter fullscreen mode Exit fullscreen mode

Verification

1. Creating a Secret

First, create the target Secret:

kubectl create secret generic my-secret \
  --from-literal=foo=bar
Enter fullscreen mode Exit fullscreen mode

Verify that it has been synchronized to AWS Secrets Manager:

aws secretsmanager get-secret-value \
  --secret-id my-secret-foo
Enter fullscreen mode Exit fullscreen mode

If successful, you should see a response like this:

{
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:000000000000:secret:my-secret-foo-rUBCkr",
    "Name": "my-secret-foo",
    "VersionId": "00000000-0000-0000-0000-000000000001",
    "SecretString": "bar",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": "2024-11-14T09:50:34.787000+09:00"
}
Enter fullscreen mode Exit fullscreen mode

2. Updating the Secret

Let's update the Secret value:

kubectl create secret generic my-secret \
  --from-literal=foo=baz \
  --dry-run=client -o yaml | kubectl apply -f -
Enter fullscreen mode Exit fullscreen mode

Verify that the value has been updated in AWS Secrets Manager:

aws secretsmanager get-secret-value \
  --secret-id my-secret-foo
Enter fullscreen mode Exit fullscreen mode

You can confirm that SecretString has changed from bar to baz:

{
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:000000000000:secret:my-secret-foo-rUBCkr",
    "Name": "my-secret-foo",
    "VersionId": "00000000-0000-0000-0000-000000000002",
    "SecretString": "baz",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": "2024-11-14T10:03:41.913000+09:00"
}
Enter fullscreen mode Exit fullscreen mode

3. Verifying Deletion Behavior

Delete the Secret:

kubectl delete secret my-secret
Enter fullscreen mode Exit fullscreen mode

At this point, the secret in AWS Secrets Manager is not deleted.

Next, delete the PushSecret:

kubectl delete pushsecret pushsecret-example
Enter fullscreen mode Exit fullscreen mode

This operation will also delete the secret from AWS Secrets Manager:

aws secretsmanager list-secrets
Enter fullscreen mode Exit fullscreen mode
{
    "SecretList": []
}
Enter fullscreen mode Exit fullscreen mode

Cleanup

When you delete the external-secrets PushSecret, my-secret-foo remains in AWS Secrets Manager as "scheduled for deletion". To immediately delete the secret from AWS Secrets Manager:

aws secretsmanager delete-secret \
  --secret-id my-secret-foo \
  --force-delete-without-recovery
Enter fullscreen mode Exit fullscreen mode

Delete external-secrets:

helm uninstall external-secrets -n external-secrets
Enter fullscreen mode Exit fullscreen mode

Delete AWS credentials:

kubectl delete secret aws-credentials
Enter fullscreen mode Exit fullscreen mode

Summary

We've seen how external-secrets' PushSecret can synchronize Kubernetes Secrets to AWS Secrets Manager. This feature can be useful in several scenarios:

  • Sharing sensitive information managed in Kubernetes with other AWS services
  • Sharing Secrets between Kubernetes clusters via AWS Secrets Manager
  • Backing up Kubernetes Secrets to AWS Secrets Manager

While this example used external-secrets with AWS Secrets Manager, there are various other providers available for SecretStore. One particularly interesting provider is Kubernetes itself. I'm personally interested in trying out direct Secret synchronization between Kubernetes clusters and plan to write about that experience in a future article.

Reference Links

Top comments (0)