Non-prod Environment Management
Are you tired of the arguing back and forth with your QA team that the staging environment is broken again? Or that the data in your database needs to be flushed because of a botched migration? Persistent, non-prod environments are so useful, but can be an immense, thankless, maintenance burden.
Is there an easy way to manage them? Ideally, you have so much automation developers don’t get brought in to deal with the cruft and fragility of non-prod environments and the noise and headache they create as a result. As well, we all want tooling to exist and be available, so that we don’t have to spend cycles creating and maintaining our own tools to fix specific problems.
Render has some useful out of the box solutions that help with non-prod environment management that really reduces the technical lift required to fix common problems. Let’s examine some of them.
Turnkey Environments and Separation of Config and Code
A blueprint spec (aka a render.yaml
) is a definition of an environment. One understated feature of the blueprint is that it can reference resources outside the repo in which it’s declared.
You can create a render.yaml
in a repo that is totally separate from your code and lay out your configuration there by defining the environment variables directly and/or referencing an environment group. In that render.yaml
you’ll state which repo and branch render should deploy- and that can be a totally different repo from the one the render.yaml
lives in.
For example:
This render.yaml
lives in the repo https://github.com/dashdashhard/app-staging.git
on branch main
to define a staging environment:
services:
- type: web
name: app
repo: https://github.com/dashdashhard/app.git
branch: staging
envVars:
- fromGroup: staging-config
autoDeploy: true
And a second, production environment defined by a render.yaml
living in repo https://github.com/dashdashhard/app-prod.git
on branch main
:
services:
- type: web
name: app
repo: https://github.com/dashdashhard/app.git
branch: production
envVars:
- fromGroup: production-config
autoDeploy: false
These two environments reference different branches in the same repo. Both environments have their own configuration, pulled from their own environment groups. Plus, with autoDeploy
, the staging environment will automatically redeploy itself whenever the staging
branch is updated.
Preview Environments
Render gives us the ability to spin up new environments per pull request- letting us test our code changes, database migrations, whatever we need in a throwaway environment.
Let’s say you have a persistent dev
environment declared like this:
previewsEnabled: true
services:
- type: web
name: app
repo: https://github.com/dashdashhard/app.git
branch: dev
envVars:
- fromGroup: dev-config
autoDeploy: true
Note that previewsEnabled
is set to true
.
Whenever a PR is raised to merge into the branch that the persistent environment is hooked to (in our case, dev
), a preview environment is created based on dev
’s render.yaml
for that PR. You have the ability to specify an initialization script for the database state- so you could load a database fixture file, or to load a dump from another environment. You have the tools to initialize your preview environments with whatever data and configuration is relevant for your testing, protecting the persistent dev
environment from incomplete and unmerged changes.
As you add commits to your PR, your preview environment is redeployed automatically with your changes, and destroyed once the PR the environment is created from is merged.
Point in Time Recovery
We have all had database migration scripts fail (and if you haven’t yet, get ready because it’s coming).
If you do manage to, for example, merge a database migration that really messes up your persistent environment’s data, you can always perform a point in time recovery of your database to just before the merge happened while you revert the commit, or merge a fix for it. No more blame games- just a revert and restore and you’re back up and running. This is such an undervalued feature for environment management- it saves us tons of time since we dont have to figure out how to undo the damage, we just restore to a point in time before the damage was done.