Best practices using Blueprints in a production/staging environment setting

I’m having a little trouble understanding the best way to use Blueprints in a production/staging environment setting.

Currently we’re using a single Blueprint instance that manages two web services for staging and production.

The Blueprint instance is setup on the staging branch.

Our development process is simple: we merge feature branches into staging and then merge staging into production for release.

The process works well until we want to update headers (i.e. Content-Security-Policy headers) or other environment settings via the Blueprint render.yaml file.

Ideally we would like to update the Blueprint and when the change is pushed to staging only the staging service is updated.

And when pushed to production only the production service is updated.

Currently when a Blueprint change has been pushed to staging for review, the settings in the production are also updated, can this be avoided?

I assumed that changes to the production environment wouldn’t happen until changes to production were pushed but am I wrong to assume this, is this not how it works and is there a better way to do this?

Hi Mike,

The advice is to use the “branch” feature of the blueprint.

services:
    - name: my-staging-app 
      branch: staging
    - name: my-production-app 
      branch: production

The blueprint itself will get autoupdated when its branch is changed, but the services will only get autoupdated when their branch is changed.

Hope that helps!

Hi, thanks for your reply,

I understand about the branch feature of Blueprints but I don’t understand the best way to get around the following problem.

If I have the following Blueprint on a staging branch, something like:

services:
  - name: my-staging-app 
    branch: staging
    headers:
      - path: /*
        name: Content-Security-Policy
        value: script-src 'self' *.stripe.com

  - name: my-production-app 
    branch: production
    headers:
      - path: /*
        name: Content-Security-Policy
        value: script-src 'self' *.stripe.com

Let’s say I want to add *.facebook.com to staging and production. I add the following to both services:

headers:
  - path: /*
    name: Content-Security-Policy
    value: script-src 'self' *.stripe.com *.facebook.com
...etc.

The following will happen:

  • staging is deployed with the new header
  • production is also deployed with the new header when I don’t want it to be, but not a big problem this time…

Inversely, let’s say I want to remove *.facebook.com from the Content Security Policy
I update the Blueprint to remove facebook.com to the following:

headers:
  - path: /*
    name: Content-Security-Policy
    value: script-src 'self' *.stripe.com
...etc.

And deploy to staging, the following will happen:

  • staging is deployed with the new header, great I can test it
  • production is also deployed with the new header and uh-oh, it breaks my production code because the Content Security Policy is no longer permitting calls to *.facebook.com and any code using their JS library will not work.

A simple solution might be to have the Blueprint on the production branch but then staging wouldn’t be updated…

Does this make my problem clearer? The problem is more about running two services with a dependency on a single branch alongside code that is updated and tested per branch.

A simpler example might be if I have the following code that sets the env vars for both services in the Blueprint.

For example the env var is the source of an inline app:

services:
  - name: my-staging-app 
    branch: staging
    envVars:
      - key: APP_DOMAIN
        value: example.com

  - name: my-production-app 
    branch: production
    envVars:
      - key: APP_DOMAIN
        value: example.com

If the Blueprint is deployed to staging
and I want to change the domain to something else

Option 1:

  • I update the Blueprint file changing my-staging-app envVars key to something-else.com
  • I also update the Blueprint file changing my-production-app envVars key to something-else.com also
  • I update some code ready for the new update
  • I deploy to staging for testing
  • staging env vars have been updated
  • production env vars have been updated but the update to production is premature because I haven’t tested it yet, so potential for breakage if new domain and old code don’t align
  • merge staging to production
  • everything should now work as env vars and code align

Option 2:

  • I update my-staging-app envVars key to something-else.com
  • I leave the my-production-app envVars as it was
  • I update some code ready for the new update
  • I deploy to staging for testing
  • staging env vars have been updated and production env vars have not
  • I test it on staging and all looks good
  • merge staging to production, uh-oh, I can’t merge staging to production because the production service doesn’t have the correct env vars yet

So before merging I need to add another step:

  • I update the Blueprint file again changing my-production-app envVars key to something-else.com
  • I deploy to staging
  • staging env vars have not been updated, production env vars have been updated
  • I then merge staging to master
  • everything should now work as env vars and code align

This process would be better if:

  • I update the Blueprint file changing my-staging-app envVars key to something-else.com
  • I also update the Blueprint file changing my-production-app envVars key to something-else.com also
  • I update some code ready for the new update
  • I deploy to staging for testing and only staging code and staging environment settings are updated concurrently
  • I merge to production
  • Then production code and production environment settings are updated at the same time

I read and tested this Best practices for staging & prod environments, like a pipeline, using blueprints - #2 by anniesexton which is a similar problem but the two solutions seem to skirt around the issue of setting environment settings.

Hi Mike,

Thank you for specifying the issue with updating environment settings with really clear examples. It’s not possible right now to have the ideal flow that you’ve specified, but I agree that it should be easier and doable without that extra step. I’ve created a post on feedback.render.com here that you can subscribe to for updates. We have a team dedicated to making it easier to work with multiple environments, services, and making it easier to use Render with larger teams. They’ll be considering your request when figuring out what to work on next.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.