TL;DR: I tried this, but it doesn't work.

The problem with this is that when ansible runs it does not persist facts - they are gathered at the beginning of a play. The percona-server role needs facts about all the servers because it needs to populate the gcomm:// addresses in order to establish node replication. Without facts, we do not have the IP's of the all the nodes available to us.

Reversing the order, with 'db' before 'db[0]' does not work because secondary nodes need to be brought up after the primary node starts with 'bootstrap-pxc.'  Similarly, splitting this into 2 separate plays will also not work because the primary needs to be differentiated from the secondaries by being in the 'boostrap-pxc' state. It is not OK to have all the nodes start up at once as all will fail.  

I also thought of calling something like:
hosts: db
roles:
  - percona-common

hosts: db[0]
vars:
  boostrap: True
roles:
  - percona-server

hosts: db
roles:
  - percona-server

in order to get the facts gathered early in the run, but, again, we need the primary to be differentiated from the secondaries.  There is no way I know of to say "all nodes except primary" in a hosts declaration for the 3rd stanza above. 

This left me with no other choice but to register a bunch of variables and check them in the role.