Common usage for scaling

I am working on my cookbook which can set up etcd cluster. Now I can set up a static cluster env through the attributes. Say the attributes named etcd.members=[host1,host2,host3]. But now I want to add a member “host4” to the existing cluster. What I can do now is to modify the attributes etcd.members=[host1,host2,host3,host4], then run the cookbook on each node because each node need to modify the etcd configuration to add the “host4” related information.

My question: is there a more “smart” way? Seems I must run cookbook
on each node when adding a new member? When I have many members, it is
terrible to do this scaling.

Any ideas?

Generally it's best to periodically run chef-client. Chef Client/Server are designed around this use case and have numerous mechanisms for avoiding unneeded load on the Chef Server for "no-op" Chef Client runs. If you need the overall infrastructure to converge quickly with changes, you can sacrifice a bit of scale and run Chef Client on a shorter interval, like 5 minutes or even 1 minute.