Rethinking Configuration for Preview Environments: A new approach from Flowerwork

Patrick Wiseman

Most programming frameworks aren’t set up in a way that takes into account having more than one deployed environment. They consider development, testing and production environments, and that’s it. But realistically, any team building an advanced SaaS product will have more than one deployed environment.

So what can you do in response as your development efforts scale and your team hits this roadblock? Here’s a look at how we’re solving this problem at Flowerwork with a new approach for domain configuration.

The status quo of domain configuration – and why it’s a problem

Most programming languages and frameworks provide a way for developers to work locally in a development environment or a test environment that will mimic how they may work in a production environment.

For example, dotenv files contain the configuration for local development that will be made present in a deploy environment through environment variables, such as previews, staging or production. In most cases these only live on local development machines without any backups, and every new hire must spend time setting up their local environment (along with any external dependencies) during onboarding.

The end result is typically a setup that looks similar to this:

  • Dev is the environment for developers to run a server locally and is often paired with a local dotenv file
  • Test is the environment for developers to run tests locally or in CI
  • Prod is the environment for the application to run in production

This setup creates challenges when it comes to consistency (as everyone ends up running their own version of a local dev environment) and can prove time consuming, particularly for new team members since setting up a local environment serves as a roadblock to shipping code.

Why we’re flipping the status quo on its head

A better way to think about your core three environments is as development, test and deployed. This approach ultimately looks something like this:

  • The development configuration describes how to have the app behave when developing locally. What tends to top the list for Flowerwork is:
    • Human readable logs
    • Allowing stack traces on errors
    • A debug log level to show most log messages
    • A connection string for a local database
    • Configuration to watch for code changes and hot reload
    • External service integrations via dotenv files
  • The test configuration provides behavior to run tests locally and in CI. At Flowerwork, this includes:
    • A warning log level to hide most log output
    • Mock expected external network connections
    • A rule to disallow non-mocked external network connections
    • Inclusion of a mock database or mock database adapter
    • External service integrations via dotenv files
  • The deployed configuration provides the shared behavior to how you’d like all deployed environments to behave – previews, staging and production. We include the following at Flowerwork:
    • An info log level
    • Forced SSL connections
    • Disabled stack traces
    • External services configured via environment variables

Overall, this approach offers improvements over the status quo because it means that the only change when moving to production is the configuration, which allows you to promote the artifact you’ve already built.

For instance, if you’ve tested a container image in your preview environment and confirmed it is good to deploy to production, your Continuous Delivery scripts can promote the image rather than rebuilding that image for production. This creates quicker deliveries and ensures fewer opportunities for errors on the path to production, thereby reducing risk in the delivery pipeline.

How we’re making this new approach happen: Enter domain configuration

Of course this new approach leads to an important conundrum: If all of your deployed environments contain the same base configuration, how do you handle configuration differences between the environments? The answer is environment variables.

Specifically, one of the major difficulties with preview environments has been how to handle many different configurations for external integrations. At Flowerwork, we overcome this challenge by adding a second type of configuration in addition to environment configuration. This new configuration is known as domain configuration.

Domain configuration describes any configuration of secrets based on the hostname. This allows you to have different secrets and configurations for each deployed environment – Preview #1, Preview #2, Preview #3, Staging, Production, etc. Ultimately, these should live at something like 1.myapp.dev.env, 2.myapp.dev.env and so on.

Under this mindset, we store and deploy our trusted production operational secrets through Kubernetes ConfigMaps and Secrets injected into deployments at runtime. For our non-production operational secrets, we simplify our development workflow by creating a dotenv file for each hostname that we check into source control (which allows us to roll out configuration changes alongside application code changes). And we do this for every preview hostname to create a unique configuration for each preview environment.

As an added bonus, internally we use ngrok for our local development environments so our third party integrations for authentication and webhooks work locally. Because everyone has a unique domain for local development, we manage our local development host names the same way as any other domain configuration so that we can roll out additions, deletions and updates to our local environment domain configurations in the same manner as we would for our preview environments.

Equally noteworthy, this approach takes our onboarding to the next level because it allows us to set up a new local development hostname for new hires and have them ready to go with a fully configured local environment from their first day. How’s that for a win-win?

Ready to get started?

Interested in learning more about how to increase the agility of your development and delivery processes while decreasing risk? Contact us today to discover how Flowerwork can help.