Comment Re:Is Ruby's Decline In Popularity Permanent? (Score 2) 253
When the rise and fall of the Ruby empire is written, Chef will probably have a part in both stages. Ruby is more a victim there, but some of my most frustrating encounters with Ruby have involved Chef. Sticking to Ruby earned Chef favour from developers but Puppet's custom DSL choice was the right one. Using Ruby forces hard dependencies where everything ends up being dependent on 'windows' and 'yum' and 'apt'.
A major problem with the first era of config management / DevOps was too much code that does too little. Instead of telling Chef via an abstraction to enable the apache service, you have to write:
service 'apache2' do
service_name apache_service_name
case node['platform_family']
when 'rhel'
if node['platform_version'].to_f < 7.0 && node['apache']['version'] != '2.4'
restart_command "/sbin/service #{apache_service_name} restart && sleep 1"
reload_command "/sbin/service #{apache_service_name} graceful && sleep 1"
end
when 'debian'
provider Chef::Provider::Service::Debian
when 'arch'
service_name apache_service_name
end
supports [:start,:restart, :reload, :status]
action [:enable,:start]
only_if "#{node['apache']['binary']} -t", environment: { 'APACHE_LOG_DIR' => node['apache']['log_dir'] }, timeout: 10
end
And this is one of the better written actively maintained cookbooks.
Then there is the annoyingly common convention where every time there is a new release of the underlying package, you have to update a hash in the Chef code and release a new version of the Chef cookbook, which of course is delayed - looking at you Elasticsearch.
It runs 'yum install elasticsearch' which installs a signed package from the repository. But the first law of config management is 'support everything and let the lowest common denominator dictate design'. So supporting whichever crappy OS / release that does not have native packages always takes priority over writing something that just works and will continue to just work.
e.g. The Chef yum provider can't handle obsolete package versions. If you tell Chef to install somepackage-x.y.1, and that version has been obsoleted by somepackage-x.y.2, somepackage-x.y.2 gets installed while Chef thinks it installed somepackage-x.y.1.
The next time you run Chef with exactly the same config, it will fail because of the implicit downgrade.
Which brings us to the Third law of config management: Idempotence in config management is like world peace for the U.N. - promising an idealized unachievable goal confers nobility and thus failing at it all the time is ok.
Ruby isn't the culprit here but it is the enabler. Manual dependency management means no one configures versioned cookbook dependencies. So your infrastructure is code defined, but what that code is is a spur of the moment thing as Chef fetches the freshest stuff off supermarket.chef.io. Bringing us to the second law 'it mostly works' is good enough.
In the world of clustered distributed multi-node services, the much praised Kitchen test framework can't test multi node deployments. Have a two-node Elasticsearch cluster - forget writing tests, and add a bunch of timeout hacks to handle asynchronous builds. Let's have a long existential discussion over whether multi-node testing is really needed and continue to write tests for whether "package 'apache2'" really installed apache2: https://github.com/test-kitche...
I should stop before I get started on how Chef remains blissfully unaware if two resources map to the same filesystem entity. Last one wins yay!
And I don't mean if you screwed up and defined it twice, but even if it is defined somewhere else in the crapload of cookbook dependencies.
Or the maddening inadequacy of wrapper cookbooks as a solution to the problem where you end up with several local diverging forks of upstream cookbooks.
Config managemnt won't save Ruby. Config management tools were much better than what came before. They will live on as the right solution to a far narrower range of problems than what they were aimed at. Containers are devouring the rest of that pie. Containerization, unlike Idempotence, is the right goal. Hiccups in reaching it are fine. Containerization is 42.
I can compare two tools I have used a fair bit, Foreman (in Red Hat Satellite) guise, a Rails app, and Jenkins. Sure the enduring and plugin friendly underpinnings of Jenkins matters. And they are different tools. But one is now a bloated app with lots of not high quality code, a resource hogging slow performer, and massive breaking changes with every release. The other is reborn in sleek new completely code defined automation form (Jenkins Pipelines), while still being compatible with stuff written 10-12 years ago.
I almost want to walk over to the Java folks and tell them they had a point.