This operator reads information from a third party service like AWS Secrets Manager or AWS SSM and automatically injects the values as Kubernetes Secrets.
- Uncomment and update backend config to be used in
config/backend-config/kustomization.yaml
with valid valuess:
resources:
# - backend-config-gsm.yaml
- backend-config-asm.yaml
# - backend-config-dummy.yaml
# - backend-config-onepassword.yaml
%cat config/backend-config/backend-config-asm.yaml
...
operator-config.json: |-
{
"Type": "asm",
"Parameters": {
"accessKeyID": "AWS_ACCESS_KEY_ID",
"region": "AWS_DEFAULT_REGION",
"secretAccessKey": "AWS_SECRET_ACCESS_KEY"
}
}
Given a secret defined in AWS Secrets Manager:
% aws secretsmanager create-secret \
--name=example-externalsecret-key \
--secret-string='this string is a secret'
and an ExternalSecret
resource definition like this one:
% cat config/samples/secrets_v1alpha1_externalsecret.yaml
apiVersion: secrets.externalsecret-operator.container-solutions.com/v1alpha1
kind: ExternalSecret
metadata:
name: externalsecret-sample
namespace: system
spec:
key: example-externalsecret-key
backend: 36af4962.externalsecret-operator.container-solutions.com
version: latest
The operator fetches the secret from AWS Secrets Manager and injects it as a secret:
% make deploy
% kubectl get secret externalsecret-operator-externalsecret-sample -n externalsecret-operator-system \
-o jsonpath='{.data.example-externalsecret-key}' | base64 -d
this string is a secret
In this you can find more information about the architecture and design choices.
Here's a high-level diagram of how things are put together.
We would like to support as many backend as possible and it should be rather easy to write new ones. Currently supported or planned backends are:
- AWS Secrets Manager
- 1Password
- Keybase
- Git
- GCP/Google Secret Manager
- An existing 1Password team account.
- A 1Password account specifically for the operator. Tip: Setup an email with the
+
convention:john.doe+operator@example.org
- Store the secret key, master password, email and url of the operator account in your existing 1Password account. This screenshot shows which fields should be used to store this information.
- Our naming convention for the item account is 'External Secret Operator' concatenated with name of the Kubernetes cluster for instance 'External Secret Operator minikube'. This item name is also used for development.
The integration secrets/onepassword/backend_integration_test.go
test checks whether a secret stored in 1Password can be read via the operator.
Create a secret in 1Password as follow. Create a vault called test vault one
. Now add a new Login
item with name testkey
. Set its password
field to testvalue
. See the screenshot below.
To run the integration test do the following.
- Sign in to your existing 1password
$ eval $(op signin)
- Set the
ITEM_VAULT
andITEM_NAME
environment variables to select the right 1Password item that contains credentials fo your operator 1Password account.
$ export ITEM_NAME=External Secret Operator mykubernetescluster
$ export ITEM_VAULT=myvault
Now load the 1Password credentials of your operator account into the environment
$ . deployments/source-onepassword-secrets.sh
Run the tests including the integration test with
$ go test -v ./pkg/onepassword/
To deploy the operator do the following.
- Sign in to your existing 1password
$ eval $(op signin)
- Load the 1Password credentials of your operator account into the environment
$ source config/scripts/source-onepassword-secrets.sh
- Deploy the operator
$ make deploy-onepassword
- Enabled and configured secret manager API on your GCP project. Secret Manager Docs
- Uncomment and update backend config to be used in
config/backend-config/kustomization.yaml
:
resources:
- backend-config-gsm.yaml
# - backend-config-asm.yaml
# - backend-config-dummy.yaml
# - backend-config-onepassword.yaml
- Update the gsm backend config
config/backend-config/backend-config-gsm.yaml
with values from the service account key
%cat config/backend-config/backend-config-gsm.yaml
...
operator-config.json: |-
{
"Type": "gsm",
"Parameters": {
"projectID": "",
"type": "",
"privateKeyID": "",
"privateKey": "",
"clientEmail": "",
"clientID": "",
"authURI": "",
"tokenURI": "",
"authProviderX509CertURL": "",
"clientX509CertURL": ""
}
}
- Update the resource definition
config/samples/secrets_v1alpha1_externalsecret.yaml
% cat config/samples/secrets_v1alpha1_externalsecret.yaml
apiVersion: secrets.externalsecret-operator.container-solutions.com/v1alpha1
kind: ExternalSecret
metadata:
name: externalsecret-sample
namespace: system
spec:
key: your-secret-key
backend: 36af4962.externalsecret-operator.container-solutions.com
version: your-secret-version
- The operator fetches the secret from GCP Secret Manager and injects it as a secret:
% make deploy
% kubectl get secret externalsecret-operator-externalsecret-sample -n externalsecret-operator-system \
-o jsonpath='{.data.your-secret-key}' | base64 -d
Yay! We welcome and encourage contributions to this project!
See our contributing document and Issues for planned improvements and additions.