For single machine, Vagrant’s built in ansible provisioner is good. For multi-machine, you could consider using the dynamic inventory (slooow), or better, just source a configuration file (json, yaml, csv, ini, whatever) from the Vagrantfile and from a dynamic inventory.
I created some example scenarios where, Vagrant, Shell Scripts, and Ansible dynamic inventory from a config file (one source of truth):
The only draw back, is that it doesn’t reflect current state of the systems (that they are running), only that they are configured to run, and how to access them through Vagrant’s private key.