Most puppet documentation shows dependencies within a module or within a manifest, but in a good puppet configuration you should have a modular design and when building hosts or roles, which means you may need to order how the modules should be actioned.
It's a known fact that puppet will perform modules in whatever order it likes but will keep dependencies within modules intact. You may think that using the following would ensure that your classes would happen in the specified order;
Class['abc'] -> Class['efg'] -> Class['xyz']
This you would think ensures that the modules abc will happen before egg followed by xyz. This is not the case even if you have require dependencies within your modules. I have seen items happen in a module after another module which should have completed first using this method.
To ensure that a particular action must happen in a module before another, or better still ensuring that a module must complete before the next module you should do the following;
1. Ensure use of require our dependency arrows in the middle so that there is an exact for and that puppet cannot do other actions at random unless the order is not required, but this would or could cause issues so.
2. Identify last essential action that happens in each module and use those as the dependency link in you node or manifest that brings your modules together.
Example
Module abc has an exec{'first one':
Module efg has a service{'second one':
Module xyz has an exec{'third one':
In your manifest your relationship dependency to ensure modules complete in exact order would be;
Exec['first one'] -> Service['second one'] -> Exec['third one']
Because puppet loads the catalogue first so the types are already loaded in. Namespace is not required unless you have a class of names, but puppet would complain if you has two or more services of the same name so cross module dependency would require unique names for your types.
Now you can perform real module dependency order within puppet.