Ask HN: Chef, Ansible, Puppet- When to Use Configuration Management?
I wonder where these tools fit today and how they are used. Since a lot of applications are moving to containers and Kubernetes I'm struggling to understand what's the current state these tools.
26 comments
[ 2.4 ms ] story [ 63.4 ms ] threadRather than a dev ask a server guy to make a vm, then join it to the domain, then move it to the right OU, then install anti-virus, etc. then ask a dba to install SQL server, import the database schema, setup permissions, and enable network access, we write an ansible playbook that does it all in a repeatable manner, the same way every time.
You have an n-tier app with a reverse proxy load balancing for 3 web servers and 1 database server, and you want one copy of this app for dev, one for staging, and one for prod, and you want them all the same?
Ansible to the rescue (or better, Terraform, which gives you more control IMO)
You need one more environment for testing the changes to a new system? Add a line in Ansible and rerun the whole thing.
CM systems like Ansible or Terraform let you do Infra As Code and treat your servers like cattle, not pets.
A server acts weird? take out of load balancer, delete the entire VM, re-run ansible to recreate it, poof its happy again.
We use Terraform to setup new reproducible environments for all of our projects. We have full modules for ECS, EC2 and various others combination of services that we repeatedly use on AWS. It makes it really easy to set something up and not worry about it. Helps us setup bastions, rds, clusters, task definitions, scaling, vpc, alb and all the other things you'd have to waste couple of hours/days to get right.
Having said that, it's very weird to hear about using these sorts of tools with containers. The whole point of containers is that they don't require any configuration at all at the container level, because that's already handled when the container image is created. After that point it's a container orchestration problem, and that's left to the Docker Swarm/Kubernetes systems out there.
My question to you is - but who installs the Docker Swarm or Kubernetes system and make sure it runs and can be accessed by outside world?
I think you are missing the point or maybe I am not understanding where you are coming from but in order to bring your code to a server you have multiple layers/steps you go through:
- Code layer
- Artifact/Image layer (Docker Image)
- Orchestration layer (EKS/ECS/Swarm/Compose)
- Server Layer (Your local env, any hosted 3rd party server, your on-premise server).
First you write the code, then you build it into an image, then you push the image to a registry or directly, then you update your orchestration layer that handles the image. Orchestration layer can't magically setup your server, vpc and other services.
Containers do not have anything to do with these tools. They are tools that supplement the workflow. Just like CI is there to help you run the tests, build those images and push them to a registry and trigger updates to your orchestration engine or new deploys, that's how terraform/chef/pupet are there to make configuration changes to those servers.
At a certain point, you may start to need more logic in your build. If you have a big container designed to run an older app, you may need to install a lot of dependencies; and maybe you're lucky and there's a Makefile, maybe not. The result might be some ugly shell script that gets more complex and harder to read over time, as you re-implement more and more of what would already be in the wheelhouse of a good config manager.
You could instead just use Ansible or Chef Zero to run all of that logic inside your container. Packer is happy to run Chef Zero and output totally compliant Docker containers for you that don't use a normal Dockerfile at all. It's not common, but it's certainly an option, if you're looking for a reason why these tools might persist into the future.
Other than that, the strongest use cases are:
- Provisioning "legacy" stuff like EC2 or VMWare VMs, and bare metal
- Keeping long-lived servers up to date and maintaining their replace-ability as best as possible (i.e. the next best thing to immutable infra is replaceable infra)
- Automating integrations, i.e. Ansible and Chef have a ton of modules for services like Zabbix, Consul, etc. you can use as part of your script to get a machine totally ready to serve on the network without you re-implementing API calls.
Why?
Chef even now lacks a good ad-hoc mode that makes it easy to run one liners. Little info on Puppet. Do know that Puppet uses a separate tool called Bolt for ad hoc commands, while Ansible has it built in.
Chef really tries to force you to use their Chef server to really run anything. If you just want to provision a single server you needed to use an unofficial tool, knife-solo, which isn't supported anymore or chef-zero, the new tool, which lacks documentation. (So does knife-solo, but I got it to work.).
The binary builds of Chef now require an EULA license agreement to use run it. Even thou the open source version is under Apache2. The annoying part is you have to place a file on every machine to keep running it. This is also not documented properly.
Bad documentation was something I was hoping Chef had gotten over a long time ago.
Some resources of Chef just do not work as documented and I end up using manual execute commands while Ansible's providers usually consistently works. Ansible documents which providers are by the community (and are included in the main package) and which are maintained by the Ansible team and are guaranteed to have a stable API. Something I really appreciate and gives me confidence in my Ansible scripts. Ansible also a Docker provider.
Chef also really requires you to use a Ruby gem manager which is a hassle if you are not using Ruby right now. Since I have stopped using Ruby it is a lot easier to just 'sudo apt install ansible'.
My biggest issue with Ansible is that the error messages can be very poor.
Take the snap provider for example. The older version on Ubuntu 18.04 does not support the later snap provider in later version of Ansible that my dotfile manager uses. This by itself is a small issue, but the error message it gives is very makes you think you have a syntax issue with an unrelated part rather than an undocumented keyword.
Huge proponent of Packer + Terraform. Running commands and copying files on boot of VM instances can be a bit dodgy (cloud-init) or using Terraform provisioner "file" or provisioner "remote-exec", but they work. Typically you want to "bake" as much as possible into the AMI using Packer and anything that is runtime dependent, can be setup by Terraform on instance create using the methods described above.
If you running standard Docker containers and AWS, highly recommend AWS ECS using Fargate[1]. No servers to manage, just define the services and container details and ECS runs the containers for you. Blue-green deploys and auto-scaling out of the box with health checks.
If you running Kubernetes, I highly recommend looking at using Terraform to manage the Kubernetes resources[2]. Helm, while nearly a defacto standard is full of edge cases, weird quirks, and utter frustration. Oftentimes Helm is required though to work within the Kubernetes ecosystem.
IMHO once you hit a certain scale the dream of vendor-independence is a lie anyway. But while you are still small, I wouldn't box yourself in. Just my opinion of course.
Assuming that you can't or aren't able to containerize your app, Ansible is a great all-arounder largely because of it being agentless. It's easy to install and easy to scale. However, really large organizations usually want to use their configuration management as a CMDB of sorts. While Red Hat has Ansible Tower for this, Chef provides a much more mature offering (from hearsay; I haven't actually used Tower).
I dismiss Puppet these days. It's more legacy compared to Chef, and it's harder to get recent information when searching for stuff. It's also really hard to test locally compared to Chef with test-kitchen.
If you know and use Ruby, Chef can be a good choice. Otherwise, go with Ansible. It's a lot more simple and flexible IMHO, and it's growing rapidly (for those reasons). A note tho, while Chef is Ruby it is still a DSL that will take some time to learn, which puts it on the same level as Ansible's YAML based "language" that you have to learn.
I like Chef but despite being a Ruby fanboi I still use Ansible for all new development. It's just a better developer experience.
https://cfengine.com
I have to deal with ansible at work, with all its warts and accidental misfeatures. Doing CFEngine for my personal stuff is a bliss.