Serial: usage across multiple plays

I’m trying to write a rolling-update.yml playbook that calls other playbooks and makes use of the serial: attribute.

It goes something like this:

rolling-update.yml:

  • hosts: nonprod-app-servers
    serial: “30%”
    pre_tasks:
  • name: disable node in the F5 Pool
  • include: peoplesoft.yml
    post_tasks:
  • name: enable node in the F5 Pool

peoplesoft.yml playbook calls multiple roles with different host targets

  • hosts: peoplesoft-nonprod-servers
    roles:
  • ps-common
  • hosts: nonprod-app-servers:nonprod-unixprcs-servers
    roles:
  • ps-tuxedo
  • hosts: nonprod-app-servers
    roles:
  • ps-app-domains

… and so on…

What I want is to call rolling-update.yml and target a cluster so that it runs through the entire rolling-update playbook on 30% of the targeted group at a time. However, as I understand it, there’s two problems with this.

A) you can’t apply serial: to an included playbook and
B) even if you could, it would be a different play and starts the next set of hosts before moving on to the next play.

I’m kinda hoping my only recourse isn’t to explicitly call all my roles in the rolling-update playbook, since I have a list of 7 roles that apply to various parts of the infrastructure and that list is growing weekly. I’d prefer to just reuse the existing peoplesoft.yml playbook and call that from other playbooks.

Appreciate any thoughts/insight, even if only to tell me i’m hosed and to suck it up stop reusing the peoplesoft.yml playbook.

After working on it some more, I realized that I can’t easily just call my roles in the rolling-update.yml because I still have the limitation of needing to apply certain roles to certain hosts and that would require the start of a new play within the playbook which would break the serial execution. The only way I can see forward here is to tag the roles and use --skip-tags: when calling the playbook and exclude the roles which don’t need to be applied everywhere. Feels kinda like a hacky way to accomplish it though.

Found a workable answer in another thread here indirectly.

I can use the when clause on roles to gate the execution of a role.

It will look like this:

  • hosts: nonprod-app-servers
    serial: “30%”
    pre_tasks:
  • name: disable node in the F5 Pool
    roles:
  • {role: ps-common, when: “‘peoplesoft-nonprod-servers’ in group_names” }
  • {role: ps-tuxedo, when: “‘nonprod-appservers’ in group_names” }
    … etc
    post_tasks:
  • name: enable node in the F5 Pool

Not the way i’d prefer to do it(serial working across playbook includes) but it’ll do the job. If anyone has any alternatives or thoughts, i’d still be happy to hear about them.

P.S. In case anyone comes across this post trying to do the same thing, there’s a bug with serial: where percentages aren’t calculated correctly when the host number is below 1. To be corrected in a coming version release.