Common Problems in Process, Tooling, Security, and Infrastructure
Numerous early-stage startups use outsourcing to develop their Minimum Viable Product (MVP), quickly building something at a low cost. While this approach has proved quite effective, it comes with several challenges.
Although most outsourcing development shops can deliver a functional product with the requested features, they often overlook other critical aspects of good development, particularly around DevOps.
Many development shops begin building code for their clients in a Github repository they set up for themselves. However, this practice can have negative consequences since it gives the shop control over the code and its access. This can lead to significant issues, especially in cases of payment disputes or conflicts.
Furthermore, it means that you won’t have ownership or control over your code. To avoid these problems, always set up your own Github account and have the shop assist you in creating private repositories that belong to you, both now and in the future.
Although it’s not strictly a DevOps issue, the quality of documentation for development shops can be quite challenging. While they may excel at writing basic code, they often neglect to include comments within the code or provide a clear understanding of how the system operates. This lack of documentation can make it challenging for in-house teams to maintain, modify, and upgrade the MVP into a more mature and scalable product.
To avoid these issues, ensure that your outsourced shop provides good code comments (such as JavaDocs, if applicable), proper architecture diagrams, and detailed DB table descriptions, along with interaction or data flow diagrams. Additionally, they should include information on how and where any third-party APIs are used. This documentation will help ensure that your product can be maintained and expanded over time, even as your team evolves.
Deploy Early & Often
Many development shops collect your requirements, disappear for months, and then deliver an incomplete product for you to test. Unfortunately, it often fails to meet your requirements or has significant flaws that require extensive rework. Moreover, it is typically deployed on their infrastructure and servers every few days or weeks, leading to further rework when eventually deployed on final development and production clouds.
To avoid these problems, consider working with a development shop that follows an agile approach, with shorter sprints and more frequent deliveries. This approach enables you to test the product in smaller increments, identify any issues early on, and make necessary modifications during the development process.
Additionally, it would be beneficial to ensure that the product is developed on an environment that resembles your final deployment environment, such as a cloud infrastructure or production-like environment, to minimize rework when it’s time to deploy.
To avoid the problems of incomplete product delivery and deployment rework, development should build a cloud development environment early on, ideally within the first few weeks of the project. One way to achieve this is by using simple infrastructure-as-code tools like Terraform (although manual setup in the console is also acceptable).
Most development shops tend to set up the simplest possible development environment, typically a single VM and a database. However, this environment should closely resemble the final deployment environment, including features like a Content Delivery Network (CDN), load balancers, and other non-core components.
Ignoring these elements can often cause issues when moving to production later on. While it takes additional time to set up and configure these elements, it is worth the effort to create a development environment that accurately mirrors your final deployment environment.
Once the development environment is set up, development shops should deploy early and often, ideally every few days, to that environment so that you can frequently test the system. While they may claim that the system is not yet ready and they have to build more, it’s rarely true.
Instead, insist that they deploy the skeleton UI, login, and other basic features as soon as possible so that you can see the UI design and other essential elements, which also keeps them on their toes.
Additionally, deploying often forces development shops to establish basic Continuous Integration/Continuous Deployment (CI/CD) processes, such as using GitHub Actions, enabling them (and later you) to deploy automatically without manual intervention. This greatly speeds up the development and deployment process.
Furthermore, automatic building, testing, and deployment of the code should occur regularly, ideally on every merge to the development branch. This not only adheres to best practices but also helps to shorten the time from code to testing.
By deploying early and often, development shops are compelled to document how to build and deploy, work out standard environment separation, secret handling, startup scripts, and other related processes that take time and effort later on.
Most dev shops will totally ignore any elements of observability, such as logging, traces, or even monitoring metrics. Some things like metrics can be added later by a DevOps team, but logging requires changes everywhere in the code, and should be included from the beginning by the developers.
Good logging is critical to troubleshooting and fixing problems, both in development and later in production. You should insist on good structured and multi-level logging (error, warning, info, debug, etc.) in both JSON and text format, as these will save a lot of time and pain later.
Note developers often do not clean up logs or issues in their logs, especially in Java or other verbose systems. The logs in those systems are often full of warnings and information about various issues that are later easily confused for problems. You should insist on clean logs for normal runs, which means just the purposeful logs developers intend to be there.
More advanced shops may include additional observability elements such as rich events with metadata and multi-service tracing.
Security is often neglected by outsourced development teams, with many relying solely on basic frameworks such as Laravel, Rails, or Spring Boot. They may overlook critical security measures such as HTTP headers, password sharing, hard-coded secrets, and opening databases to the world. Poor security practices pose significant risks to any development process, whether in-house or outsourced, and require constant vigilance.
To mitigate these risks, you should require adherence to OWASP development guidelines, including their language-specific cheat sheets and top 10 risks. Additionally, it’s recommended to engage a consultant to conduct compliance reviews before final payment to the outsourced vendor, as security gaps are likely to be uncovered.
Outsourced development companies can be very helpful in starting a project early and inexpensively, but they also present their own set of challenges. While many articles focus on improving product requirements and communication, little attention is often given to the technical and DevOps-related aspects.
It’s crucial to work with your outsourced shop on items such as setting up the development environment, establishing a solid CI/CD pipeline, implementing robust logging and monitoring, and ensuring proper security measures are in place. These elements are essential to the success of your project and product.
By addressing these technical and DevOps-related issues, you can ensure a smooth transition to bringing development in-house, scaling up your operations, and paving the way for future success. So don’t overlook these critical components of outsourced development, and work closely with your vendor to achieve the best possible outcomes. Good luck.