One of the mantras of having pre-production environments is that they should be identical to the production environment. Obviously, you do not want to test your software against a different version of MongoDB in Staging vs Prod. It is, however, important to recognize that each environment is tuned for a particular engineering outcome. Staging environments can be useful for demos and tests that are difficult to automate and load-testing environments are about how your application performs under load. They need not blindly match Production.
A Development Environment is one where developers who are working on different parts of an application can collaborate and test interactions between the services they are working on. This can be a change to a backend API that requires a corresponding frontend UI change, or two backend services undergoing a schema or service contract change. It is important to tailor these environments for the purpose they serve so engineers can focus on the aspect of software development, rather than being a puritan about having identical environments.
Of course, if a team is going to have these different environments for specific purposes, one shouldn’t assume there’s only one instance. We routinely spin up development environments that are tied to feature branches. At any given time, we may have several features under development. It is best to empower your engineers so they can spin up environments themselves without having to ask for help from a dedicated infrastructure expert. Your infrastructure as code setup is a good place to see the degree of differences between the various environment flavors. For instance, you may have an ephemeral in-cluster database for development and a managed version of that same database in load test and production environments.
One of the main challenges to having many disposable environments is managing all the various configurations. One common mistake we see is combining configuration with credentials. Configuration includes things like service names and teams should strive to use the same configuration across all environments. If your database in Develop is postgres-db:5432 then it should also be postgres-db:5432 in production.
A great trick is to use Kubernetes headless services to alias service names so postgres-db:5432 in production points to your PaaS PostgresDb for instance. That way, your development team can seamlessly switch between environments without encountering a configuration nightmare. The only thing one would then have to deal with is switching out the credentials which should be managed in a secure credential store. These stores typically have the ability to switch context and roles and this can be leveraged to make the move from one environment to another seemlessly.
Once you have the above setup, it’s really easy to use a tool like Codezero because it extends your local development into any of these environments. Codezero makes it so your local development machine becomes one with any of your environments - including production, if required. This makes it really easy for your developers to use first-class tools like debuggers and IDEs to diagnose, build and make changes to the software. Using environments in conjunction with your local workstation in this way allows team members to make changes and test with unprecedented speed. As this becomes part of the engineering culture, teams have the agility to move from one feature environment to another and even work on issues in production during outages and other incidents if required.
When your team is freed from having to deploy to collaborate and test, there isn’t as much pressure on reducing the time taken up by your CI/CD pipeline. You may be tempted to cut out automated integration tests or really long-running automated UI tests in order to reduce deployment times. The pressure on deployment times is generally because engineers want to quickly test a subset of the application without waiting tens of minutes for the deployment to go through. This can cause teams to start cutting corners in their testing automation. With real-time local collaborative development, you don’t have to wait around for a deployment in order to check that a feature works as intended.
Adopting these DevOps practices propels development teams towards greater efficiency, satisfaction, and superior software quality. By embracing tailored environments, automated provisioning, and seamless integration between development and deployment, teams can significantly shorten development cycles, enhance software reliability, and meet business objectives more effectively. This approach not only optimizes technical processes but also fosters a culture of innovation and continuous improvement. Ultimately, these practices empower teams to deliver software that exceeds expectations, ensuring that they remain competitive in an ever-evolving technological landscape. The essence of modern DevOps is to create an environment where excellence is the norm, driving teams towards the creation of impactful, high-quality software solutions that truly delight their end-users.
Which is - or at least should be - the goal for every professional software development team...
Transform the way your team collaborates with Codezero Teamspaces. Signup for a personal demo and discover how we can help streamline your workflow and boost productivity!