Is it time for sensible infrastructure as code defaults in Rails?

Hello - I’m new to this discussion board (although not new to Rails at all)

I don’t see any discussion on this topic right now. Every time our teams have a new site to launch we do one of two things

If we’re working fast and want a staging environment we just deploy to Heroku. Sometimes teams immediately hit a gotcha in that Heroku doesn’t support sqllite (the default Rails db) and it’s moved to Posgres or MySQL. This always gets torn down in favor of Terraform and Ansible when we need a production environment.

When we’re ready to deploy to production we configure terraform and ansible to build infrastructure and deploy the application to our environments. We have a bunch of separate repos in GitHub for modules associated with those, and we end up making some level of spaghetti out of where our secrets are stored - rails credentials vs AWS parameter store (SSM) etc. This is the main area of rails where we tend to “configure” rather than follow any sort of community driven convention.

Since Rails is Convention over Configuration, is it time to start discussing whether Rails can provide reasonable defaults for Infrastructure as Code?

The main consternation I have about this idea is that infrastructure is usually a paid service (although most providers have a free tier), and favoring a provider doesn’t sound like a great idea. I do think, however, that bringing opinionated DevOps practices into Rails could be a huge value add if done right.

5 Likes

Everyone has their preferred stack, so everyone will have a different understanding of what is considered sensible defaults. Rails for me was so approachable because it was so easy to get up and running without having to install any additional software (for example, sqlite vs other databases).

In the end, it’s a trade-off. Either we appeal to beginners and reduce friction or we reduce configuration burden for experienced programmers. To find a sweet spot is difficult and it won’t ever appeal to everyone.

It’s healthy to question the status quo, but I think it’s also important to keep Rails simple and welcoming for new people.

3 Likes

You wouldn’t need to install any additional software to run it locally (like in your sqlite case or even in the case of mailers) but when it comes to configuration for a live environment, especially in the case of mailers, rails provides extremely fast configuration for Exim, Mailgun, Mandrill, Postfix, Postmark, Qmail, and Sendgrid, and the “sensible default” is just printing emails to the console.

2 Likes

I wonder if there is a way to abstract things so that different infrastructure providers could provide plugins.

so - if I want to run on Heroku, I add gem 'HerokuInfrastructure' if I want to run on Hatchbox, it is gem 'HatchboxInfrastructure'

I realise this may be crazy talk…

1 Like

I was kind of thinking this could pretty much piggy back on terraform since it has a bunch of providers supported out of the box. It’s not unlike rails to be picky about this stuff, for example webpacker in Rails 6 is just using webpack with some sane defaults and the most basic configurations in webpacker.yml. Even the configuration of it differentiates slightly in that you merge the configs like

const { environment } = require('@rails/webpacker')
const customConfig = require('./custom')
environment.config.merge(customConfig)

module.exports = environment

I don’t see why you couldn’t do the same with terraform modules and even provide rake tasks for easy plan, apply, destroy of environments other than production that are defined under config/environments (qa, stage, etc.)

1 Like

This conversation is somewhat related.

It talks about the tension between making rails new easy for newbies vs appropriate for experienced developers. It proposes a set of preconfigured defaults for different circumstances plus a --interactive flag to switch on and off common options.

2 Likes