|
| 1 | +# ADR 001: Use ENV variable to control behavior in production-like envs |
| 2 | + |
| 3 | +## Status |
| 4 | + |
| 5 | +Accepted |
| 6 | + |
| 7 | +## Context |
| 8 | + |
| 9 | +We would like to be able to use WebValve to fake external service |
| 10 | +integrations in production-like environments. |
| 11 | + |
| 12 | +When using WebValve in a production-like environment, we'd like to be |
| 13 | +able to support three different use-cases: |
| 14 | +* enable all services by default, and don't load WebValve at all. This |
| 15 | + is equivalent to WebValve's current production behavior: |
| 16 | + zero-overhead, no risk of accidentally loading a fake service |
| 17 | + instead of a real one. |
| 18 | +* enable all services by default (as if WebValve is disabled) but allow |
| 19 | + each service to be flipped into faking mode based on an env |
| 20 | + variable. This allows us to support faking a service in a staging |
| 21 | + environment where we cannot actually integrate with a real or |
| 22 | + sandbox version of the external service while still connecting to |
| 23 | + real versions of all other services. |
| 24 | +* disable all services by default (as if WebValve is enabled) but allow |
| 25 | + each service to be flipped into real mode based on an env variable. |
| 26 | + This allows us to spin up cheap one-off environments for |
| 27 | + user-testing, proof-of-concepting, etc. |
| 28 | + |
| 29 | +In summary, we need ways to control: |
| 30 | +* the activation of WebValve: loading the library, loading |
| 31 | + the fakes, configuring WebMock |
| 32 | +* the default mode of WebValve: intercepting vs. allowing |
| 33 | + (pass-through) |
| 34 | +* the explicit enabling / disabling of individual services |
| 35 | + |
| 36 | +We came up with a few approaches to support these use-cases: |
| 37 | + |
| 38 | +*Activate if required* |
| 39 | +This will load and activate WebValve when it's required. If you don't |
| 40 | +want to activate it, don't require it. The downside to this approach is |
| 41 | +it's easy to accidentally load WebValve in the wrong env. Additionally, |
| 42 | +in an env where we want to enable all services by default and only |
| 43 | +disable select ones, we'd have to define the ${SERVICE}_ENABLED env |
| 44 | +variable for all services and update each time we add a new services, |
| 45 | +which can be quite annoying. |
| 46 | + |
| 47 | +*Activate based on env variables* |
| 48 | +Introduce a new WEBVALVE_SERVICE_ENABLED_DEFAULT env variable that |
| 49 | +controls the default service enabled behavior, or the "mode" webvalve |
| 50 | +runs in: on and allowing traffic by default, or on and intercepting |
| 51 | +traffic by default. If the WEBVALVE_ENABLED variable is unset, don't |
| 52 | +activate the lib. If WEBVALVE_ENABLED is set to truthy (1/t/true) and |
| 53 | +WEBVALVE_SERVICE_ENABLED_DEFAULT is unset then load in passthru mode, |
| 54 | +allowing fakes to be toggled on explicitly via their ${SERVICE}_ENABLED |
| 55 | +env variable. If WEBVALVE_ENABLED is explicitly set to to truthy and |
| 56 | +WEBVALVE_SERVICE_ENABLED_DEFAULT is set to falsey (0/f/false) then load |
| 57 | +in intercepting mode, allowing fakes to be toggled off explicitly via |
| 58 | +their ${SERVICE}_ENABLED env variable. |
| 59 | + |
| 60 | +*Don't support it at all* |
| 61 | +Lastly, a sort of non-option option: don't support faking in |
| 62 | +production-like envs. Don't support any envs other than dev and test. |
| 63 | +Advise that the gem should only go in the dev/test group. This is safest |
| 64 | +for production use, but means that production-like envs that want to |
| 65 | +swap out real versions of services would have to do it by actually |
| 66 | +deploying a version of their fake service and connecting to it out of |
| 67 | +process as if it were a real service. This is nice from the "make it |
| 68 | +real" angle, but introduces quite a bit of overhead and it's |
| 69 | +well-aligned with the WebValve philosophy of making things convenient |
| 70 | +and as isolated as possible. |
| 71 | + |
| 72 | +## Decision |
| 73 | + |
| 74 | +We chose the "Activate based on env variables" approach. It introduces |
| 75 | +more complexity to this library, but support for these use-cases feels |
| 76 | +worth it. We're not the happiest with having |
| 77 | +`WEBVALVE_SERVICE_ENABLED_DEFAULT` as an env variable name, but I think |
| 78 | +that we can document it clearly to head off confusion for the power |
| 79 | +users that actually want to utilize WebValve in production-like |
| 80 | +environments. For the standard user, nothing about how they're currently |
| 81 | +using WebValve will change. |
| 82 | + |
| 83 | +Here's a summary of the behavior based on environment. |
| 84 | + |
| 85 | +When the env is test/development |
| 86 | +* webvalve is enabled and always runs in intercepting mode where |
| 87 | + services are intercepted by default |
| 88 | + |
| 89 | +When the env is NOT test/development, e.g. production |
| 90 | +* webvalve is disabled unless WEBVALVE_ENABLED=1/t/true |
| 91 | +* when WEBVALVE_ENABLED is truthy, webvalve is enabled in allowing mode |
| 92 | + where all traffic is allowed by default |
| 93 | +* $SERVICE_ENABLED=0/f/false can be used to switch a service into intercepting |
| 94 | + mode, i.e. enable the fake service |
| 95 | +* when WEBVALVE_ENABLED is truthy and |
| 96 | + WEBVALVE_SERVICE_ENABLED_DEFAULT=0/f/false then webvalve is enabled in |
| 97 | + intercepting mode where all traffic is intercepted by default |
| 98 | +* $SERVICE_ENABLED=1/t/true can be used to switch a service into |
| 99 | + allowing mode, i.e. allow the traffic to that service to go through to |
| 100 | + the internet |
| 101 | + |
| 102 | +## Consequences |
| 103 | + |
| 104 | +More complexity to manage in this library. |
| 105 | + |
| 106 | +Controlling WebValve activation via an ENV variable, makes it slightly |
| 107 | +easier to unintentionally enable WebValve in production. |
| 108 | + |
| 109 | +The current behavior of WEBVALVE_ENABLED in production is slightly |
| 110 | +altered: by default we will allow all traffic in production. |
0 commit comments