You mentioned multiple environments. The suggestion I made before is
only sufficient for one environment. In our shop, we use "fully
articulated group names" that consist of the problem
"domain", the
"
environment", plus host classes as required to specify the
hosts without relying on special hostname patterns or other tricks.
In your case, suppose your app is called "xkcd", and you have
environments named "dev", "tst", "spt", and "prd", each of which
contains a db host and a few app hosts. Using our shop's inventory
conventions for the "xkcd" problem domain would result in the
inventory below. Though not required, by convention we always use a
host's FQDN as the inventory name (i.e.
ansible_fqdn==inventory_hostname). We may also set up an "all"
pseudo environment that encompasses all the hosts in the problem
domain. It's occasionally useful in playbooks, and it also helps
ensure we've created our group hierarchy the way we expect. In
particular, if we find we're having to specify a hostname more than
once in a problem domain, we probably have not created the correct
hierarchy of sub_groups.
[xkcd_all:children]
xkcd_dev
xkcd_tst
xkcd_spt
xkcd_prd
[xkcd_all_db:children]
xkcd_dev_db
xkcd_tst_db
xkcd_spt_db
xkcd_prd_db
[xkcd_all_app:children]
xkcd_dev_app
xkcd_tst_app
xkcd_spt_app
xkcd_prd_app
[xkcd_dev:children]
xkcd_dev_db
xkcd_dev_app
[xkcd_dev_db]
dbhost0d.our.org
[xkcd_dev_app]
apphost0d.our.org
[xkcd_tst:children]
xkcd_tst_db
xkcd_tst_app
[xkcd_tst_db]
dbhost0t.our.org
[xkcd_tst_app]
apphost0t.our.org
apphost1t.our.org
[xkcd_spt:children]
xkcd_spt_db
xkcd_spt_app
[xkcd_spt_db]
dbhost0s.our.org
dbhost1s.our.org
[xkcd_spt_app]
apphost0s.our.org
apphost1s.our.org
[xkcd_prd:children]
xkcd_prd_db
xkcd_prd_app
[xkcd_prd_db]
dbhost0p.our.org
dbhost1p.our.org
[xkcd_prd_app]
apphost0p.our.org
apphost1p.our.org
apphost2p.our.org
apphost3p.our.org