Skip to content

Commit b691a49

Browse files
authored
feat: Added support for external-secrets (#28)
* feat: Added support for external-secrets * fix: Update stripe setup to append secret to secrets manager instead of kubernetes * fix: change script modes to executable
1 parent 5f551b1 commit b691a49

File tree

15 files changed

+79
-88
lines changed

15 files changed

+79
-88
lines changed

scripts/check.sh

100644100755
File mode changed.

scripts/gha-setup.sh

100644100755
File mode changed.

scripts/required-bins.sh

100644100755
File mode changed.

scripts/setup-stripe-secrets.sh

100644100755
Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
#!/bin/bash
22

33
# This script runs only when billingEnabled = "yes", invoked from makefile
4-
# modify the kubernetes application secret and appends STRIPE_API_SECRET_KEY
5-
# the deployment by default will pick up all key-value pairs as env-vars from the secret
4+
# It will modify the application secret in Secrets Manager and append STRIPE_API_SECRET_KEY
5+
# This will be synced to k8s and the deployment will pick up all key-value pairs as env vars from the secret
66

7-
if [[ "$ENVIRONMENT" == "" ]]; then
8-
echo "Must specify \$ENVIRONMENT to create stripe secret ">&2; exit 1;
9-
elif [[ "$ENVIRONMENT" == "stage" ]]; then
10-
PUBLISHABLE_API_KEY=$stagingStripePublicApiKey
11-
SECRET_API_KEY=$stagingStripeSecretApiKey
7+
if [[ "$ENVIRONMENT" == "stage" ]]; then
8+
PUBLISHABLE_API_KEY=$stagingStripePublicApiKey
9+
SECRET_API_KEY=$stagingStripeSecretApiKey
1210
elif [[ "$ENVIRONMENT" == "prod" ]]; then
13-
PUBLISHABLE_API_KEY=$productionStripePublicApiKey
14-
SECRET_API_KEY=$productionStripeSecretApiKey
11+
PUBLISHABLE_API_KEY=$productionStripePublicApiKey
12+
SECRET_API_KEY=$productionStripeSecretApiKey
13+
else
14+
echo 'Must specify $ENVIRONMENT (stage/prod) to create stripe secret'>&2; exit 1;
1515
fi
1616

17-
CLUSTER_NAME=${PROJECT_NAME}-${ENVIRONMENT}-${REGION}
18-
NAMESPACE=${PROJECT_NAME}
19-
17+
SECRET_NAME=${PROJECT_NAME}/kubernetes/${ENVIRONMENT}/${PROJECT_NAME}
2018
BASE64_TOKEN=$(printf ${SECRET_API_KEY} | base64)
21-
## Modify existing application secret to have stripe api key
22-
kubectl --context $CLUSTER_NAME -n $NAMESPACE get secret ${PROJECT_NAME} -o json | \
23-
jq --arg STRIPE_API_SECRET_KEY $BASE64_TOKEN '.data["STRIPE_API_SECRET_KEY"]=$STRIPE_API_SECRET_KEY' \
24-
| kubectl apply -f -
19+
20+
# Modify existing application secret to add stripe api key
21+
UPDATED_SECRET=$(aws secretsmanager get-secret-value --region ${REGION} --secret=${SECRET_NAME} --query "SecretString" --output text | \
22+
jq --arg STRIPE_API_SECRET_KEY ${BASE64_TOKEN} '.STRIPE_API_SECRET_KEY=$STRIPE_API_SECRET_KEY')
23+
aws secretsmanager update-secret --secret-id=${SECRET_NAME} --secret-string="${UPDATED_SECRET}"
2524

2625
sh ${PROJECT_DIR}/scripts/stripe-example-setup.sh

templates/README.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ kubectl -n <% .Name %> get pods
1313
You can update the resource limits in the [kubernetes/base/deployment.yml][base-deployment], and control fine-grain customizations based on environment and specific deployments such as Scaling out your production replicas from the [overlays configurations][env-prod]
1414

1515
### Dev Environment
16-
This project is set up with a local/cloud hybrid dev environment. This means you can do fast local development of a single service, even if that service depends on other resources in your cluster.
16+
This project is set up with a local/cloud hybrid dev environment. This means you can do fast local development of a single service, even if that service depends on other resources in your cluster.
1717
Make a change to your service, run it, and you can immediately see the new service in action in a real environment. You can also use any tools like your local IDE, debugger, etc. to test/debug/edit/run your service.
1818

19-
Usually when developing you would run the service locally with a local database and any other dependencies running either locally or in containers using `docker-compose`, `minikube`, etc.
19+
Usually when developing you would run the service locally with a local database and any other dependencies running either locally or in containers using `docker-compose`, `minikube`, etc.
2020
Now your service will have access to any dependencies within a namespace running in the EKS cluster, with access to resources there.
21-
[Telepresence](https://telepresence.io) is used to provide this functionality.
21+
[Telepresence](https://telepresence.io) is used to provide this functionality.
2222

2323
Development workflow:
24-
24+
2525
1. Run `start-dev-env.sh` - You will be dropped into a shell that is the same as your local machine, but works as if it were running inside a pod in your k8s cluster
2626
2. Change code and run the server - As you run your local server, using local code, it will have access to remote dependencies, and will be sent traffic by the load balancer
2727
3. Test on your cloud environment with real dependencies - `https://<your name>-<% index .Params `stagingBackendSubdomain` %><% index .Params `stagingHostRoot` %>`
@@ -61,8 +61,21 @@ By default it requires `[lint, unit-test]` to be passing to allow Pull requests
6161
<% end %>
6262

6363
## Database credentials
64-
Your application is assumed[(ref)][base-deployment-secret] to rely on a database(RDS), In your Kubernetes
65-
application namespace, an application specific user has been created for you and hooked up to the application already.
64+
Your application is assumed to rely on a database. An application-specific user has been created for you by the `/scripts/create-db-user.sh` script in the infrastructure project.
65+
A Kubernetes secret will exist in your application namespace (<% .Name %>) that will provide these credentials to your application.
66+
67+
## Secrets
68+
Along with the database credentials, any other secrets that need to be provided to the application can be managed in AWS Secrets Manager.
69+
Secrets have been created for each environment called `<% .Name %>/kubernetes/<environment>/<% .Name %>` which contain a list of environment variables that will be synced with the kubernetes secret in your namespace via a tool called [external-secrets](https://github.com/external-secrets/kubernetes-external-secrets)
70+
Any secrets managed by `external-secrets` will be synced to kubernetes every 15 seconds. Keep in mind that any changes must be made in Secrets Manager, as any that are made to the secret on the kubernetes side will be overwritten.
71+
You can see the `external-secrets` configuration in [kubernetes/overlays/staging/external-secret.yml](./kubernetes/overlays/staging/external-secret.yml) (this is the one for staging)
72+
73+
To work with the secret in AWS you can use the web interface or the cli tool:
74+
```
75+
aws secretsmanager get-secret-value --secret=<% .Name %>/kubernetes/stage/<% .Name %>
76+
```
77+
78+
The intent is that the last part of the secret name is the component of your application this secret is for. For example: if you were adding a new billing service, the secret might be called `<% .Name %>/kubernetes/stage/billing`
6679

6780
## Cron Jobs
6881
An example cron job is specified in [kubernetes/base/cronjob.yml][base-cronjob].
@@ -136,6 +149,5 @@ The deployment only requires the environment variables:
136149
<!-- Links -->
137150
[base-cronjob]: ./kubernetes/base/cronjob.yml
138151
[base-deployment]: ./kubernetes/base/deployment.yml
139-
[base-deployment-secret]: ./kubernetes/base/deployment.yml#L49-58
140152
[env-prod]: ./kubernetes/overlays/production/deployment.yml
141153
[circleci-details]: ./.circleci/README.md
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This will pull the contents of a secret from AWS Secret Manager and put it into a Kubernetes secret.
2+
# Any changes made to the AWS secret should be automatically synced over.
3+
# An AWS secret for the project should have been created automatically by /scripts/create-db-user.sh in the infrastructure project
4+
apiVersion: kubernetes-client.io/v1
5+
kind: ExternalSecret
6+
metadata:
7+
name: <% .Name %>
8+
spec:
9+
backendType: secretsManager
10+
dataFrom:
11+
- <% .Name %>/kubernetes/stage/<% .Name %>

templates/kubernetes/overlays/dev/kustomization.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ patchesStrategicMerge:
77
resources:
88
- ../../base
99
- ingress.yml
10+
- external-secret.yml
1011

1112
configMapGenerator:
1213
- name: <% .Name %>-config
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This will pull the contents of a secret from AWS Secret Manager and put it into a Kubernetes secret.
2+
# Any changes made to the AWS secret should be automatically synced over.
3+
# An AWS secret for the project should have been created automatically by /scripts/create-db-user.sh in the infrastructure project
4+
apiVersion: kubernetes-client.io/v1
5+
kind: ExternalSecret
6+
metadata:
7+
name: <% .Name %>
8+
spec:
9+
backendType: secretsManager
10+
dataFrom:
11+
- <% .Name %>/kubernetes/prod/<% .Name %>

templates/kubernetes/overlays/production/kustomization.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ patchesStrategicMerge:
77
<% end %>
88
resources:
99
- ../../base
10+
- external-secret.yml
1011
<%if eq (index .Params `userAuth`) "yes" %>## userAuth enabled - Oathkeeper proxies to backend instead of ingress
1112
# - ingress.yml
1213
<% else %>- ingress.yml<% end %>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This will pull the contents of a secret from AWS Secret Manager and put it into a Kubernetes secret.
2+
# Any changes made to the AWS secret should be automatically synced over.
3+
# An AWS secret for the project should have been created automatically by /scripts/create-db-user.sh in the infrastructure project
4+
apiVersion: kubernetes-client.io/v1
5+
kind: ExternalSecret
6+
metadata:
7+
name: <% .Name %>
8+
spec:
9+
backendType: secretsManager
10+
dataFrom:
11+
- <% .Name %>/kubernetes/stage/<% .Name %>

0 commit comments

Comments
 (0)