Re:Beyond the default Rails environments
by crymer11 on Thursday June 13, 2013 @10:39AM
(#5874252)
The authors of the 12 factor app methodology seem to disagree:
"Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called “environments”) named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle." -http://www.12factor.net/config
Re:Beyond the default Rails environments
by bryanlarsen on Thursday June 13, 2013 @11:27AM
(#5874554)
I don't think the two approaches are as far apart as they appear at first glance. Later on in the article they talk about removing Rails.env.production? from their code.
The twelve factor app calls for strict separation of config from code. I suspect that 37 signals has that, or pretty close.
Actually storing the config in environment variables is a Heroku-ism. There are other ways of doing it; chef is another good way. What matters is the strict separation.
Re:Beyond the default Rails environments
by hoov on Thursday June 13, 2013 @01:16PM
(#5875235)
I think that this is right. I also think that storing configuration information in environment variables doesn't scale past a handful of settings. I'm also not sure that it's the best way of storing secrets. If you're working in a real SOA environment, you may have dozens of external services to talk to, and possibly secrets for each one. At that point, you probably can't use environment variables. And, even if you do -- you'll be managing them in some sort of persistent storage, probably with versioning.
Re:Beyond the default Rails environments
by beat on Thursday June 13, 2013 @02:34PM
(#5875771)
Another advantage of using environment rather than a config file for configuration is not leaving a file full of secrets lying around in your environment. And why is loading your environment so difficult? If I can put foo=bar in a config file, I can put export FOO='bar' in a startup script, and delete the startup script once the application has started.
Re:Beyond the default Rails environments
by ibrahima on Thursday June 13, 2013 @08:51PM
(#5877692)
This is wrong and dangerous. From whom are you trying to keep these variables secret? Assuming a sane sysadmin, sensitive files would only be readable by the user which needs to run the application. And environment variables can be read from the procfs file system by the same user that launched them: http://serverfault.com/questions/66363/environment-variables...
Not to mention that if an attacker has shell access to your application user account, you're already owned. So again, who are you trying to hide these variables from? Because it seems like this is just security theater and additional inconvenience (why delete and recreate the file on each deploy?) for literally no benefit.
Re:Beyond the default Rails environments
by purephase on Thursday June 13, 2013 @09:49AM
(#5873994)
The custom configuration part of that is the most interesting. Sadly, we have a lot of Rails.env.production? scattered everywhere. I'm not sure I understand the examples DHH provided though.
Re:Beyond the default Rails environments
by stiff on Thursday June 13, 2013 @11:26AM
(#5874539)
I have written a configuration plug-in that I think is slightly better (for example allows local overwriting of the settings, not just per-environment):
Re:Beyond the default Rails environments
by yxhuvud on Thursday June 13, 2013 @12:38PM
(#5874972)
Yes, that is nice and all, but could we please remove the assumption that there will only be one database.
Yes, it is possible to work with several at once, but automating the setup of an environment that have several databases, each with migrations, is no fun at all.
What would be really nice would be to have one list of databases, and one map between environments and databases.
Re:Beyond the default Rails environments
by alberth on Thursday June 13, 2013 @10:44AM
(#5874284)
Is anyone else deeply concerned that 37signals puts actual production data into their non-production environments (which are inherently insecure given the nature of those environments and who needs access to them)?
Re:Beyond the default Rails environments
by themcgruff on Thursday June 13, 2013 @11:20AM
(#5874501)
We treat all environments as production. However we add additional security to staging since it's the most experimental. (Additional security meaning it can only be accessed via VPN and after two factor authentication.)
To be very clear: Beta, production, rollout and staging environments are secure. They run all the same front end security provisions, same data center, same patches, etc. The difference is they run differing versions of the code base based on development.
Re:Beyond the default Rails environments
by gyepi on Thursday June 13, 2013 @11:04AM
(#5874405)
No. If your non-production environments are less secure than your production environment, then you're doing something wrong. In fact, non-production environments generally have a much smaller population of users and they are tend to be more security minded. Or should be.
Re:Beyond the default Rails environments
by alberth on Thursday June 13, 2013 @11:12AM
(#5874455)
You're missing the point. In non-production environments a large user base (eg developers, etc) have direct access to the database as needed for development.
In production environments, they do not.
This is exactly why data masking technologies exist. To mask/transform production data in non-production to that non-production has meaningful data but not REAL data
Re:Beyond the default Rails environments
by rmaccloy on Thursday June 13, 2013 @01:38PM
(#5875362)
I'm certain all 37s employees have access to the production database anyway; they're still a fairly small company.
The only real additional risk here is running non-production code against live data; e.g. the risk of a feature branch sending extra email to customers. Given the nature of their products this is probably manageable, assuming they don't run batch jobs (via eg. resque)
Re:Beyond the default Rails environments
by gyepi on Thursday June 13, 2013 @05:32PM
(#5876720)
Fair enough, but if they were large enough to require that sort of privilege separation, then the entire post would make a lot less sense. Furthermore, I think the target audience has the same demographics; relatively small companies where the development team is also the production team.
Thanks for the reference to data masking; it should be more common.
Re:Beyond the default Rails environments
by AhtiK on Thursday June 13, 2013 @11:00AM
(#5874379)
Hypothetically speaking if the load-balancer is directing the traffic depending on the cookies then the environments can be very well separated behind the balancer.
My other thought on this was if they use any separate static web asset management or it's all one single environment-switching for ruby.
These days one could easily work with the stable REST server and all the web assets are switched between staging/beta/etc envs.
Re:Beyond the default Rails environments
by rancor on Thursday June 13, 2013 @10:27AM
(#5874180)
IMO, the existance of code to configure more then one production-like environment is an anti-pattern. The remedy is using configuration management (Chef/Puppet/whatever) to put the correct environment specific configuration into place in a non-executable config file. Any other policy will lead to environmental drift.
Re:Beyond the default Rails environments
by dragonwriter on Thursday June 13, 2013 @10:43AM
(#5874275)
I'm not sure there is a substantive difference between "code" and a "non-executable config file". The latter is something that is read by an executable and which results in specific execution that differs by the content of the file; the difference between this and interpreted code is semantic rather than substantive.
E.g., for any combination of a YAML configuration file and a Ruby function which reads and applies it, there is a corresponding Ruby function which achieves exactly the same result without the configuration file.
There are other reasons to prefer the config file approach, but a policy which deploys the correct code to each environment will have exactly the same behavior with regard to environmental drift as one which deploys identical code the correct config file.
Re:Beyond the default Rails environments
by fchief on Thursday June 13, 2013 @10:34AM
(#5874219)
This is what we do, but we can also do his rollout example in production by putting both new and old into production side by side and then targeting percentages of new users.
Re:Beyond the default Rails environments
by gkop on Thursday June 13, 2013 @12:40PM
(#5874987)
Tried this and it didn't work for me. I found each additional RAILS_ENV value was an annoying point of divergence between environments that should be as like as possible.
Eg, the whole point of staging is to be as like to production as possible, and running the staging server in RAILS_ENV=production is a dead easy way to accomplish this goal. For the very few differences (eg database config), I further refine the production environment by consulting a SECONDARY_ENV variable that may be set to either production or staging.
Eg, ideally CI is as close to the developer's test environment as possible, so that tests that pass locally pass in CI and vice-versa, and running the CI jobs in RAILS_ENV=test is a dead easy way to accomplish this goal. For the very few differences (eg using xvfb in CI), I further refine the test environment by consulting a CI variable that may be set to either true or false.
"Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called “environments”) named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle." -http://www.12factor.net/config
The twelve factor app calls for strict separation of config from code. I suspect that 37 signals has that, or pretty close.
Actually storing the config in environment variables is a Heroku-ism. There are other ways of doing it; chef is another good way. What matters is the strict separation.
Not to mention that if an attacker has shell access to your application user account, you're already owned. So again, who are you trying to hide these variables from? Because it seems like this is just security theater and additional inconvenience (why delete and recreate the file on each deploy?) for literally no benefit.
https://github.com/jaroslawr/dynamic_configuration
Yes, it is possible to work with several at once, but automating the setup of an environment that have several databases, each with migrations, is no fun at all.
What would be really nice would be to have one list of databases, and one map between environments and databases.
To be very clear: Beta, production, rollout and staging environments are secure. They run all the same front end security provisions, same data center, same patches, etc. The difference is they run differing versions of the code base based on development.
In production environments, they do not.
This is exactly why data masking technologies exist. To mask/transform production data in non-production to that non-production has meaningful data but not REAL data
The only real additional risk here is running non-production code against live data; e.g. the risk of a feature branch sending extra email to customers. Given the nature of their products this is probably manageable, assuming they don't run batch jobs (via eg. resque)
Thanks for the reference to data masking; it should be more common.
My other thought on this was if they use any separate static web asset management or it's all one single environment-switching for ruby.
These days one could easily work with the stable REST server and all the web assets are switched between staging/beta/etc envs.
See my response to gyepi below for more info
E.g., for any combination of a YAML configuration file and a Ruby function which reads and applies it, there is a corresponding Ruby function which achieves exactly the same result without the configuration file.
There are other reasons to prefer the config file approach, but a policy which deploys the correct code to each environment will have exactly the same behavior with regard to environmental drift as one which deploys identical code the correct config file.
Eg, the whole point of staging is to be as like to production as possible, and running the staging server in RAILS_ENV=production is a dead easy way to accomplish this goal. For the very few differences (eg database config), I further refine the production environment by consulting a SECONDARY_ENV variable that may be set to either production or staging.
Eg, ideally CI is as close to the developer's test environment as possible, so that tests that pass locally pass in CI and vice-versa, and running the CI jobs in RAILS_ENV=test is a dead easy way to accomplish this goal. For the very few differences (eg using xvfb in CI), I further refine the test environment by consulting a CI variable that may be set to either true or false.