Even though I questioned the wisdom of writing your own network programming applications, I know I would immediately jump into those waters if I were 20 years younger. If you’re like my younger self, you might want to keep a few guidelines in mind.
Be conservative. You don’t have to use OpenFlow or OnePK to insert entries into routing table; BGP will do just fine. Sometimes EEM or a Tcl/Perl/Python script is all you need.
Your gear might also support other SDN-like technologies. Use whatever is available – programming network devices is interesting enough without having to deal with bugs introduced by latest experimental firmware.
Stay away from the data plane. If you can achieve your goals by reconfiguring the device with NETCONF, go for it. If that doesn’t work consider interacting with control plane protocols (BGP is usually the best choice).
Intercepting user traffic with OpenFlow controller and downloading forwarding entries straight into the data plane should be the choice-of-last-resort. Anything else is easier to debug, monitor and troubleshoot.
Stay away from real time operations. In the ideal case, your network devices already have the functionality you need, and you just need to automate their provisioning. Perfect low-hanging fruit; go for it. Try to use tools like Puppet or Chef instead of NETCONF, or create your own abstraction layer (see below).
Do you want to modify device behavior on-the-fly (example: time-based forwarding rules)? Be careful. Always consider worst-case scenarios – what happens if the controller crashes or if the controller state gets out-of-sync with the device state (or configuration). Try to use ephemeral device state (see below) instead of modifying device configuration.
Do you want to implement new device behavior, intercept control-plane traffic, or write your own protocols? Unless you have plenty of in-house resources (think Google) don’t even try to do that in your production network. If you really want to do something along these lines, join a startup (or start your own).
Create an abstraction layer. Don’t write spaghetti code that is tied to a particular device and software release (trust me, I’ve seen such code, and it isn’t pretty).
Define your high-level needs (example: add VLAN X to server group Y), turn them into an API or public methods of an object, and split your code in two parts: the generic part that handles user requests, and device-specific part that implements them. When you have to add support for more devices, you’ll add new instances of the device-specific code without touching the generic code.
Don’t depend on the SDN controller. What happens if the SDN controller crashes? Will your network melt down or will it revert to business-as-usual hop-by-hop forwarding? Minimally-intrusive architectures like BGP SDN or ephemeral additions to routing tables done with BGP FlowSpec or Cisco’s OnePK are the safest choice.
Don’t forget that when bad things inevitably happen, it’s the graceful recovery that matters most.
Always have a backup plan. You might be tempted (or forced) to implement an architecture that relies solely on an SDN controller to work (it could be anything, from NEC’s ProgrammableFlow to Juniper’s QFabric or Cisco's ACI). There’s nothing wrong with that, but don’t put all the eggs in one basket – always have a well-documented backup plan. If the controller fails, or the controller software gets corrupted and crashes, you have to know what to do next.
You might find a few more interesting details in my SDN and OpenFlow webinars; quite a few of them are public thanks to vendors sponsoring them.