Workplace Structure
Learn how to structure your projects and configs most effectively inside a workplace.
The pattern you adopt for naming your project and configs inside Doppler has many implications when it comes to access control, secret comparison features, and more. As such, itβs important to be familiar with some of the most common and recommended ways to name and structure your projects in your Doppler workplace. Throughout this document, weβre going to use examples that use an imaginary company called Acme, Inc. that has an Acme Widgets and Acme Marketplace application.
Project Naming
The Project is the top level organizational element of your workplace. In Doppler, there are some design assumptions around what a project represents. Itβs assumed that a project is a one-to-one mapping to a specific application or service that needs secrets or config variables. From an organizational standpoint, Doppler doesnβt (yet) have a way to group projects into folders, so itβs recommended that you use naming prefix and suffix conventions to group projects logically. Below are some quick best practices when naming your projects:
- Use team name prefixes to group projects together in the project list view.
- Use region codes as suffixes so applications and services remain grouped together.
- Always put portions of the name youβd prefer to group by earlier in the name (e.g.,
<team>-<app>-<service>-<region>
). This will allow you to filter for them more effectively. - The maximum number of Projects on any plan is 1000 (it may be possible to raise this on the Enterprise plan in some situations, but that requires review and approval by Doppler). You can see all of our platform limits here.
You can keep the length of the project list in the dashboard manageable by restricting access to projects using User Groups.
Environment Naming
The Environments in your projects should typically map to deployment environments that you use for your applications and services (e.g., dev
, stg
, prd
, qa
, ci
, etc.). The slug used for each of these environments is used in the API and CLI and dictates the prefix used for Branch Config names (e.g., dev_<branch-config-name>
) and is referred to as the Root Config. Below are some considerations to keep in mind when naming Environments.
- Doppler assumes Environments are all logically related to a single application or service. As such, it assumes secrets will be similar across environments and this is reflected in Dopplerβs comparison features, prompts to save new secrets to other Root Configs, and some other areas as well. Notably, there are some cryptographic operations that happen that can get expensive if you have huge sets of secrets spanning large numbers of Environments β particularly if those Environments are not logically related.
- Access control for Environments impacts access to all Branch Configs under it. So, if you give a user access to the
dev
Environment, theyβll have access to all Branch Configs under that Root Config (with the single exception of Personal Configs). - The maximum number of Environments for a project on any plan is 15. You can see all of our platform limits here.
You can define the default Environments that are added to a new Project by configuring your workplaceβs Default Project Environments.
Shared Projects
If you have secrets that many different projects share (e.g., DATABASE_URL
, DB_USER
, DB_PASSWORD
, STRIPE_API_KEY
, etc.), then you can take advantage of cross-project secret references to avoid duplicating these secrets and risk some getting out-of-sync. Typically, the best way to manage secrets like this is to create projects specifically for housing them (e.g., shared-db-credentials
, global-credentials
, etc.). You can limit access to these projects to specific admin users and references to those secrets can be added to other projects, which will then allow the users who only have access to the specific application projects to make use of them without having the ability to modify them.
- Use a standard prefix for projects like this so theyβre all grouped together (e.g.,
shared-
,global-
, etc.). - Take advantage of Environments to map the appropriate secrets to corresponding application Environments (e.g.,
shared-credentials.dev.STRIPE_API_KEY
toacme-widget.dev.STRIPE_API_KEY
,shared-credentials.prd.STRIPE_API_KEY
toacme-widget.prd.STRIPE_API_KEY
, etc.). This can be useful setting local development secrets as well (e.g., setDB_HOSTNAME
indev
to127.0.0.1
). - Take advantage of secret visibility types to prevent users from seeing the computed value of a referenced secret by setting it to βRestrictedβ in the target config. Note that this will prevent the user from using the config via CLI, so you will typically not want to use βRestrictedβ secrets in Development environments.
If you already have shared secrets set across existing projects and want to move to a shared project structure, you can use Search by Secret Value to find all the locations a secret is set to ensure theyβre all using secret references.
Project Structure Examples
Below youβll find some concrete examples showing how you can organize projects given different applications types.
Microservice
Option 1: Application + Service
This option includes the application and service name in the project names and uses branch configs purely for deployment environments like gcp
or aws
.
eng-acme-widgets-frontend
dev
,stg
,prd
prd_aws
prd_gcp
eng-acme-widgets-worker
dev
,stg
,prd
prd_aws
prd_gcp
eng-acme-marketplace-backend
dev
,stg
,prd
prd_aws
prd_gcp
Benefits
- Better for orgs that have larger/more teams and need to separate access by service
Option 2: Application
This option only includes the application name in the project name. You then create separate branch configs for each service under the main deployment environments.
eng-acme-widgets
dev
,dev_frontend
,dev_worker
prd
,prd_frontend
,prd_worker
eng-acme-marketplace
dev
,dev_frontend
,dev_worker
prd
,prd_frontend
,prd_worker
Downsides
- You lose some access control granularity because you can only grant access at the Environment level. This means you can give a user access to the
prd
config, but canβt control which branch configs they have access to, so they would automatically get access to theprd_frontend
andprd_worker
branch configs under this layout.
Monolith App
Since the app runs as a single service/application all secrets are in a single config
eng-acme-widgets
dev
,stg
,prd
eng-acme-marketplace
dev
,stg
,prd
Region
Incorporating the region into project naming typically involves combining a previous pattern with region suffixes. Keeping the region as a suffix will ensure that the projects are sorted next to each other in the project list view.
Option 1: Application + Service + Region
This option includes the application, service and region in the project name. This results in more projects to manage, but provides the most granular access control possible.
eng-acme-widgets-frontend-us
dev
,stg
,prd
eng-acme-widgets-frontend-eu
dev
,stg
,prd
eng-acme-widgets-backend-us
dev
,stg
,prd
Benefits
- You can have separate access controls for different regions.
Downsides
- Youβll end up with more projects in your project list, which can potentially be unwieldy.
- You donβt get to take advantage of the secret inheritance you would get from root configs if you were to create these as region branch configs instead.
Option 2: Application + Region
This option includes the application and region in the project name. You then create separate branch configs for each service under the main deployment environments.
eng-acme-widgets-us
dev
,dev_frontend
,dev_worker
prd
,prd_frontend
,prd_worker
eng-acme-widgets-eu
dev
,dev_frontend
,dev_worker
prd
,prd_frontend
,prd_worker
Benefits
- Less project sprawl. Youβll have fewer overall projects due to not needing separate projects for each service.
Downsides
- You lose some access control granularity because you can only grant access at the Environment level. This means you can give a user access to the
prd
config, but canβt control which branch configs they have access to, so they would automatically get access to theprd_frontend
andprd_worker
branch configs under this layout.
Option 3: Application + Service
This option includes the application and service name in the project name. You then create separate branch configs for each region under the main deployment environments.
eng-acme-widgets-frontend
dev
prd
,prd_us
,prd_eu
,prd_cn
eng-acme-widgets-backend
dev
prd
,prd_us
,prd_eu
,prd_cn
Benefits
- Less project sprawl. Youβll have fewer overall projects due to not needing separate projects for each region.
- Easy inheritance for secrets used per service β once set in the root config all regions would inherit those secrets, allowing for individual secrets to be overridden in their specific region branch config as needed.
Downsides
- You lose some access control granularity because you can only grant access at the Environment level. This means you can give a user access to the
prd
config, but canβt control which branch configs they have access to, so they would automatically get access to theprd_us
,prd_eu
andprd_cn
branch configs under this layout.
Option 4: Application
This option only includes the application name in the project name. You then create separate branch configs for each service and region under the main deployment environments.
eng-acme-widgets
dev
,dev_frontend_us
,dev_frontend_eu
,dev_worker_us
,dev_worker_eu
prd
,prd_frontend_us
,prd_frontend_eu
,prd_frontend_us
,prd_frontend_eu
Benefits
- Very little project sprawl. Youβll only have one project per logical application with all your services and regions represented as branch configs.
- Easy inheritance for broadly used secrets (i.e., secrets needed in EVERY service) by setting them in the root configs
Downsides
- You lose access control granularity because you can only grant access at the Environment level. This means you can give a user access to the
prd
config, but canβt control which branch configs they have access to, so they would automatically get access to the branch configs for every service in every region for theprd
environment under this layout.
Dynamic Environments
Sometimes you may need an environment that contains dynamic configs that are ephemeral, created programmatically, and subsequently deleted (e.g., configs that are associated with a pull request review app). Be sure to create a separate environment for these. Using a separate environment is ideal because you can scope an Access Token to just having write access to that environment without fear of accidentally making changes to configs in another environment.
Pull Request Review Environments
Create a separate branch config for every Pull Request using the Pull Requestβs ID in the branch name. Set any shared secrets in the root config for the environment β using secret references to your dev
or stg
environments if needed.
- PR Reviews /
pr
pr_12345
Feature Branch Environments
Developers can use Personal Configs for any feature theyβre working on that doesnβt require collaboration. In scenarios where multiple developers are collaborating on a new feature (or the developer is working on multiple separate features at once), they can create new branch configs under the dev
environment. Naming conventions can include the developers name followed by the feature name or just the feature name.
dev_user_feature-name
dev_feature_name
Once the feature is ready for deployment, you can use the βPromoteβ option for new secrets added to the branch config to promote them up to the root config.
Anti-patterns
There are some ways of organizing projects that may seem like it makes sense, but can actually cause problems down the road due to how Doppler is designed to function. The below are some of the most common anti-patterns people fall into using.
Creating one project per team
Doppler currently doesnβt have a feature that allows you to group projects into logical groups or folders. This can lead you to the idea of creating a single project for each team at your company using Doppler and then create an Environment for each of your applications or services. For example, you might create a devops
project and then rather than having a dev
, stg
, and prd
config, you might have something like frontend
, backend
, worker
and frontend_prd
, frontend_stg
, frontend_dev
, etc.
Downsides
- Scales poorly due to the 15 environment limit per project.
- This incurs performance penalties the closer to 15 environments you have and the more secrets you have in your configs due to comparison operations that happen across environment on save that perform expensive cryptographic operations. This is due to the expectation that Environments map closely with deployment environments where the secrets sets are similar from one environment to the next and are all for the same logical application or service.
Updated about 2 months ago