Need serial at the task level for delegate_to or another solution

ansible has a “serial” option at the playbook level but not at the tasks level. I feel like i need a similar construct to avoid race conditions when I have multiple hosts delegate_to something. Perhaps there is an existing ansible idiom to help me?

My current problem is copying a bunch of ssl csr’s to a certificat_authority. Then i delegate_to the ca. The trouble comes when the CA tries to sign multiple certs in parallel.

  • name: Sign the request
    delegate_to: “{{certificate_authority}}”
    command: creates=“{{ca_out_dir}}/{{ansible_fqdn}}.crt”
    openssl ca -batch -in “{{ca_in_dir}}/{{ansible_fqdn}}.csr”
    -out “{{ca_out_dir}}/{{ansible_fqdn}}.crt”
    -keyfile “{{ca_key}}”
    -config “{{ca_cnf}}”
    -passin “file:{{ca_keystore_password_path}}”

Output: The task fails for the first host, but fails for others.

Certificate is to be certified until Oct 17 21:32:45 2024 GMT (3650 days)

Write out database with 1 new entries

unable to rename /etc/pki/21ct/SigningCA1/ca.db.serial.new to /etc/pki/21ct/SigningCA1/ca.db.serial

reason: No such file or directory

I agree that it would be nice to have serial on the task level. Until
that happens you could break out of your current play with a one task
play that does just this but with "serial: 1" set. Then go back to
another play that doesn't use serial to finish the rest of the tasks.

“ansible has a “serial” option at the playbook level but not at the tasks level.”

While you can’t set serial on a task, you can also in 1.8 set “run_once” to a task and it will run on just one host in the loop.

Breaking out to a new play and then restarting a different play is definitely an option.

I think a lot of people don’t know a playbook can have more than one play in it.

Another workaround is to use with_items: play_hosts, when: inventory_hostname == item. This can be used inside a role, but generates huge amounts of output (len(play_hosts)² lines).

I think the right way here would be to fix the signing script to either work with randomly generated temporary directories or use some locking mechanism.

Michael DeHaan michael@ansible.com napisał:

“Another workaround is to use with_items: play_hosts, when: inventory_hostname == item.”

This will not do what you are thinking it does.