The most successful software vendors rely on repeatability, auditability, and simplicity when building solutions. The emergence of infrastructure as code (IaC) has enabled developers to apply these infrastructure practices allocation. What are the best practices for storing IaC? Should IaC code be stored with the application and feature code? Should it be stored separately in its own application-specific repository? Or must all IaC code for all applications in an organization reside in the same repository?
Let’s explore these questions, determine the trade-offs between each solution, and create guidelines that take your organization’s needs into account.
The problem with IaC storage with feature code
The naive option for storing IaC is to keep all IaC code in the application repository that consumes that IaC code as part of its CI/CD pipeline. It’s easy to set up, doesn’t require complex permission assignment, and will fully visible developers working on this codebase, making it easier to retrieve context. This facility is the reason why 20% of developers surveyed say they always store feature code and IAC in the same repository. However, there are a number of issues with keeping IaC code together with function code.
Software development best practices include minimizing redundancy. Storing all IaC code in the dependent application’s codebase violates best practices by requiring that infrastructure-as-code not only contain application-specific allocation information, but also all of the basic infrastructure. Organizations can classify infrastructure shared between several applications and ecosystems as fundamental infrastructure. Examples of such a basic fundamental infrastructure include Kubernetes clusters and log storage accounts.
Also, storing the IaC code with the function code is risky. Allowing developers admin-level access to all the deployment scripts necessary to bring code to production violates the principle of least privilege and makes it easier for attackers to move laterally. successfully hack a developer account.
Organizations enjoy a degree of secrecy regarding their deployment processes; the deployment pipeline and its configurations are tailored, and attackers who have a map of the services used by an organization can more easily engineer supply chain attacks. Storing IaC with feature code makes a code leak reveal all CI/CD configurations not only for the application, but for the entire organization. The last thing an organization should do is perform recognition of an attacker for them, but that’s exactly what happens in the situation above.
Storing infrastructure as code with product code may be easier to set up initially, but violates the principle of least privilege and zero trust principles. This method of storing code introduces unnecessary risk – there has to be a better way.
Storing all IaC code together is not the solution
Since storing IaCs with feature code in a common repository is not the optimal solution, what about storing all IaCs in a dedicated IaC repository? This would allow DevOps and security teams to implement granular access controls and make code redundancy easily identifiable and avoidable. However, this organizational structure introduces its own problems.
When all IaCs are stored in a separate shared repository, it becomes difficult to match feature changes to IaC changes. This scenario introduces friction into development processes, slows developer velocity, and increases tension between development teams, DevOps teams, and security teams.
Storing all IaCs in a common repository gives developers virtually no control over security decisions affecting their workflows. Between the lack of ownership and the extra steps needed to modify code-specific deployment scripts, storing all IaCs together prevents developers from quickly changing IaCs and hurts the organization unnecessarily.
IaC falls into two categories: basic and feature-specific
IaC and other CI/CD scripts ultimately fall into two categories: base and function.
Basic deployment scripts can be described as code widely used by an organization for, among other things, routine deployment actions or to interface with shared resources. Separating this code allows organizations to assign core IaC ownership and maintenance responsibilities to their DevOps team, which is well suited for maintaining a shared infrastructure.
IaC feature scripts are the pieces of code used to provision and manage the resources associated with specific software. Developers frequently interact with deployment scripts related to their deliverables; changing release stages, changing gateways, updating server configurations, and many other needs require different management protocols for IaC versus base IaC.
Now that we understand the difference between functionality and basic IaC, we can define appropriate management strategies for each.
The Solution: A Hybrid Approach to IaC Storage
Best practices call for categorizing feature IaC and core IaC differently and dividing responsibilities between separate teams to maximize security without adding unnecessary friction to the development and release process. Basic IaC should be handled by DevOps teams, while feature-specific IaC should be handled by code owners of the managed software.
For your organization, it starts with inventorying the organization’s systems and services. Gaining visibility into how these resources are shared helps inform business decisions about IaC code storage, helping to minimize redundancy in deployment protocols. Visibility is integral to the definition of IaC which underlies the software deployed by the organization versus IaC which is specific to certain applications, libraries and other software deliverables.
Help DevSecOps teams manage IaC and more
Best practices mean little if organizations can’t apply them. A few concluding tips:
- Track assets including registries, repositories, builds, and cloud/IaC deployments
- Implement granular access controls, allowing appropriate allocations of ownership depending on whether the resource is intended to be shared or application-specific
- Provide visibility into resource usage that enables organizations to adhere to principle of least privilege without adding unnecessary friction to the development process
- Provide a asset inventory by integrating directly with your organization’s software supply chain components
These integrations allow for complex insights that simply aren’t possible with other security tools. Additionally, these integrations enable constant monitoring of security updates, reducing the time between zero-day discovery and vulnerability remediation.