I have a chef recipe that runs migrations in opsworks. It runs php artisan migrate --force on each server. Is there a way to only run the migration one time on the first server it happesn to get to? I have 3 online at all times.
Short answer: Add a tag or an attribute and use it as a guard for the execution.
You'll still can have a race condition and the execution on multiple server as the index is updated every min (approximately) on chef-server side.
Long answer: You have to use something to keep a state, anything from zookeeper to any easy updated source of truth can fill this gap, without more details on your environment any answer will be opinionated by what is the best too for the answer-er. Voting to close as primarily opinion based.
You can always create a new 'utility' layer (custom layer type) which only has the one recipe that you need and attach only one of the instances to it.
That way you have your main layer with the 3 instances on it and with the rest of your recipes, and one of the instances will also belong to the extra layer.
You can attach an instance to a layer by going to 'instances' and then 'add new instance' and clicking the 'Existing instances' tab. The only problem is that you cannot attach a running instance to a layer, instead you have to stop it, then attach it, and then restart it.
Note: if you need to run this command after a deployment then make sure you readd your normal deploy recipes in the 'deploy' step, otherwise you risk your recipe not being in the correct order in the chef run_list.