Declarative scripts make it easy to manage a fleet.
Declarative scripts make it easy to manage a fleet.
for i in range(100):
ip = cidrhost(subnet, i)
if exists := get_server(ip):
continue
create_server(ip=ip)
and so on. I don't like it, but because it's procedural/imperative, not because it's particularly more 'petty' than the Terraform (or equivalent) would be.For me it's more about what I'm doing, conceptually. I want a server to exist, it to have access to this S3 bucket, etc. - the logic of how to interface with the APIs to make that happen, to manage their lifecycle and check current state etc. isn't what I'm thinking about. (In Terraform terms, that belongs in the provider.) When I write the above I'm just thinking I want 100 servers, so:
resource "cloud_server" "my_servers" {
count = 100
ip = cidrhost(subnet, count.index)
# and so on
}
comes much more naturally.The difference between just using some Python vs Terraform is idempotency. TF isn’t going to touch the nodes the script succeeded on; if you have to start your for-loop script it will, which may not be desirable.
Frankly these days configuration management is a bit dated…
You’re much better off in most cases using a tool like Packer with whatever system you want to bake an image, then use a simple user-data script for customization.
It’s very hard to scale continuous config management to thousands of servers.
Packer and Terraform do different jobs (they're both by Hashicorp!) - you can bake an immutable image all you like, you still need to get a server, put the image on it, give it that S3 bucket it needs, IAM, etc.