External Secrets Usage Patterns #1088
-
|
I've been slowly adopting my Docker stacks to doco-cd, and I want to get feedback on whether the patterns I'm following for external secret usage are ideal or if I'm missing any features or patterns that could simplify things. First off, I'm storing my compose files in a mono repo similar to this example in the documentation: I am also taking advantage of the working_dir: apps/
auto_discover: true
auto_discover_opts:
depth: 1This works amazingly, but I'm not sure how to scale external secrets with this pattern and maintain the principle of least privilege. Pattern 1: Environment Variable SecretsGiven this structure, the obvious pattern that comes to mind is to namespace my external secrets: working_dir: apps/
auto_discover: true
auto_discover_opts:
depth: 1
external_secrets:
WORDPRESS_SECRET_1: "op://vault/item/field"
NGINX_SECRET_1: "op://vault/item/field"This works, but technically, compose files could use other stacks' secrets. It also has the downside of changing or rotating any secrets, causing a full redeploy of all stacks in the config. A second pattern that comes to mind is to use multiple YAML documents: name: wordpress
working_dir: apps/wordpress
external_secrets:
WORDPRESS_SECRET_1: "op://vault/item/field"
---
name: nginx
working_dir: apps/nginx
external_secrets:
NGINX_SECRET_1: "op://vault/item/field"This isolates secrets at the expense of making the config more verbose. I'm also not sure if this pattern could be used alongside auto discovery, i.e., an explicitly defined stack will overwrite the auto-discovered stack, or if I need to go all in on explicit definitions with this pattern. My Ideal PatternI don't think this is possible today, but my ideal pattern would be to have a root-level where the the root working_dir: apps/
auto_discover: true
auto_discover_opts:
depth: 1and external_secrets:
WORDPRESS_SECRET_1: "op://vault/item/field"Is something like this possible? Pattern 2: Secrets in Configuration FilesThe other pattern I am encountering is secrets that are defined in configuration files, where the underlying service does not support configuration via environment variables. As I'm using 1Password for my external secrets manager, I've followed the Pre Post Deployment Scripts instructions and setup an init container to use services:
service1:
image: [...]
volumes:
- config:/config:ro
depends_on:
render-config:
condition: service_completed_successfully
render-config:
image: 1password/op:latest
user: root
volumes:
- config:/config
- ./settings.tpl.yaml:/in/settings.tpl.yaml
environment:
OP_SERVICE_ACCOUNT_TOKEN: ${OP_SERVICE_ACCOUNT_TOKEN}
command: |
sh -c 'op inject -f -i /in/settings.tpl.yaml -o /config/settings.yaml'
volumes:
config:This works, but feels verbose and unnecessary given my external secrets are available for use with doco-cd. I know SOPS is an option, but I would prefer to use my secrets manager if possible. Is it possible to use doco-cd to inject secrets into configuration files, similar to how it processes SOPS encryption? Is there a better pattern I am overlooking? My ideal pattern would be to use secret references directly in files, as follows: app:
password: {{ WORDPRESS_SECRET_1 }}This would probably require a whitelist of files in the deployment config or a naming scheme like Anyway, thank you for this lovely piece of software! I appreciate how extensible it is, and it's been a joy migrating my stack to use it. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
Nested doco-cd config files is definitely something I can consider to implement. :) You can reduce the size of your second pattern by using variable interpolation in a compose config and reference that config in your service with the configs definition. services:
service1:
image: app
configs:
- source: settings.yaml
target: /config/settings.yaml
mode: 0440
configs:
settings.yaml:
content: |
app:
password: ${OP_SERVICE_ACCOUNT_TOKEN} |
Beta Was this translation helpful? Give feedback.
Nested doco-cd config files is definitely something I can consider to implement. :)
You can reduce the size of your second pattern by using variable interpolation in a compose config and reference that config in your service with the configs definition.