- Use dynamic routing within the core, particularly if you have fail-over capacity; use static routing within the LAN (unless you anticipate regular changes and/or you need to optimize operations with automated mechanisms).
- Use the topology that suits you – I typically imagine a tree in the cases you describe. It is relatively flexible and adaptable in the middle. However, in simple cases, all topologies reduce to an almost identical layout. So choice of topology must suit the complexity you anticipate.
- Don't forget to plan for visibility.
In this last case, I am thinking about network performance and troubleshooting. No matter what you implement, dealing with inevitable problems can be easier or harder later on. Most network designs seem to emphasize maintenance or flexibility (with security always winning out). Rarely have I seen any real consideration given to visibility.
For the consummate network engineer who plans and executes networks with impeccable attention to detail (there are a few of you out there), building it right is all that matters. But for those of us with too little time, resources, or both, problems will inevitably arise – typically from oversight, or poor network hygiene, or "active" users. Finding the problems is typically the most frustrating and time consuming part of the resolution process. Time better used elsewhere.
What does that mean? The use of Layer 2 meshes, MPLS, third party networks, VPNs, VLANs, firewalls, etc. make it harder to see what is going wrong where. For example, ensure that the time-tested tools like "ping" and "traceroute" always work. Blocking ICMP, or extensive use of Layer 2 devices (like routing switches), may satisfy one need. If you have to control ICMP, consider limiting it instead of fully blocking. Or block only certain types and not all ICMP.
There are numerous other considerations related to visibility. You should consider how you typically troubleshoot and ensure that your methods are supported by your design.