Infrastructure from Code (IfC) is gaining significant interest and sparking conversations among developers and DevOps professionals alike. As organizations strive for greater efficiency and automation in their deployment processes, the appeal of IfC lies in its promise to streamline infrastructure provisioning by automatically inferring the necessary resources from application code.
This innovation offers a seamless way to integrate infrastructure management directly into the development workflow, promising to bridge the gap between development and operation.
However, despite its growing popularity, some are hesitant to try it out. One of the most common misconceptions about Infrastructure from Code (IfC) is that it burdens developers with the responsibility of writing infrastructure-specific configurations directly into their application code.
This misunderstanding leads to the following beliefs:
Developers must have a deep understanding of the runtime infrastructure and resources they are using. This will add to their cognitive load and potentially distract them from their primary focus of writing application logic.
Operations teams lose control and governance over the infrastructure since configurations are embedded directly into the application code by developers. This can result in inconsistent, insecure or noncompliant infrastructure setups.
What IfC Frameworks Actually Do
IfC automates the process of inferring the runtime requirements of an application and creating a specification that documents these requirements. This specification is generated without any specific infrastructure code being added to the application.
For example, to leverage a cloud service like an API gateway, developers write routes into their application and implement handlers for these routes. In many instances, they don’t need to worry about which specific API gateway is being used; they only need to understand that their application will eventually be deployed to leverage one.
The framework is then responsible for mapping the requirements to “providers,” which are responsible for fulfilling the contract. Basically, the framework collects all of the resources and maps them to concrete implementations of modules that:
Provision IAM roles and permissions required to allow the resources to communicate and adhere to governance standards such as least privilege Enable and provision the services and resources required, and set up appropriate naming conventions, label conventions and finer-grained configuration
What Developers Actually Do
In reality, developers using IfC frameworks are not writing infrastructure configurations or Infrastructure as Code (IaC) into their applications. With the approach we’ve taken with the open source Nitric framework, they are not even annotating their code with infrastructure-specific requirements.
Instead, developers focus solely on building their applications, using resources that they import from an SDK. The only difference that the developer might notice is that, when they are declaring their resources, they are required to provide their intended purpose for the resource. This isn’t a configuration, but rather a request for permissions to access it. The following example illustrates an intention from a developer declaring a storage bucket to read, write or delete from it.
import { bucket } from '@nitric/sdk'
const profiles = bucket('profiles').allow('read', 'write', 'delete')
What DevOps Actually Do
In an IfC environment, DevOps teams focus on managing and maintaining the infrastructure separately from application development. They are responsible for ensuring that the infrastructure adheres to the runtime requirements of the application, which are articulated in resource specification. DevOps focus on building and maintaining reusable modules written with IaC frameworks that maintain governance and compliance standards. The following example provisions a storage bucket with a consistent naming and labeling convention.
# A Google cloud storage bucket
resource "google_storage_bucket" "bucket" {
name = "${var.bucket_name}-${random_id.bucket_id.hex}"
location = var.bucket_location
project = var.project_id
storage_class = var.storage_class
labels = {
"x-nitric-${var.stack_id}-name" = var.bucket_name
}
}
How This Solution Maintains Separation of Concerns
Infrastructure from Code (IfC) respects the separation of concerns that a traditional IaC project upholds. You still have distinct application code and infrastructure provisioning code, each of which can be maintained by specific teams independently if desired.
What IfC brings to the table is the automation of the handover process between teams, essentially creating a bridge over the often-troubled waters of inter-team collaboration in some organizations.
This bridge takes the form of a resource specification. This specification allows both development and operations teams to work with confidence. Developers can proceed with the assurance that their runtime requirements will be met, while operations teams can fulfill application requests using safe, secure IaC. This IaC can be inspected with existing tools and workflows, ensuring a robust development and deployment solution.
Conclusion
Ultimately, separating your files and tools does not necessarily lead to true separation of concerns. There will always be an inherent coupling between an application and its runtime. Ideally, your application’s runtime requirements should inform your infrastructure, not the other way around — otherwise, your application could be constrained.
Nitric provides a bridge between your application code and your IaC that can be extended minimally or extensively to suit the requirements of your team. With the Nitric framework, the bridge exists at the resource level, not at the application level. This allows you to enjoy the benefits of IfC across all of your projects consistently.
Give IfC a try and experience firsthand how it can automate processes, improve efficiency and break down communication barriers within your organization.
This article was originally published on The New Stack.