Infrastructure as Code Best Practices with Terraform for DevOps
João Victor Alhadas | Dec 17, 2024
At Cheesecake Labs, we work on a wide range of projects, each with unique demands and complexities. After 10 years of working with clients to build scalable digital products that help solve real-world problems, we’ve noticed some recurring themes in our work.
With these challenges in mind, we decided to put together starter kits on our main stack that we can use from one project to the next.
Let’s take a look at the details of our Django Starter Kit.
The Django Starter Kit is a project in constant revision. It’s designed to contain reusable code for most of our projects in a robust and scalable architecture, ensuring each project starts out with a strong and adaptable foundation.
Our starter is more than just boilerplate code. It’s a dockerized, production-ready project containing:
Our architecture is composed of two types of modules — the core app and other apps. The main goal is to ensure that all apps, besides the core app, remain independent and decoupled.
The core app serves as the backbone of our project, containing essential components that are required across the entire application. It contains various functionalities, including settings, common code, abstractions, and utilities that can be shared and used by other apps within the project.
All other apps are modules that can interact with the core app. They all share a similar structure that looks like this:
.
├── models
│ └── ...
├── services
│ └── ...
├── utils
│ └── ...
├── v1
│ ├── user
│ │ ├── get
│ │ │ ├── views.py
│ │ │ ├── docs.py
│ │ │ ├── serializers.py
│ │ │ ├── tests_get_user.py
│ │ │ ├── use_case.py
│ │ │ └── ...
│ │ ├── ...
│ ├── urls.py
│ └── ...
├── urls.py
├── conftest.py
└── ...
Code language: Django (django)
Some files like __init__.py and migrations were omitted to keep only the most important aspects of the structure.
In our architecture, every endpoint has a folder containing the following:
In scenarios where multiple use cases share similar business logic, business logic is extracted and consolidated into the services or the utils folder, ensuring a cohesive and organized codebase. Our architectural philosophy emphasizes keeping business logic within specific designated areas: use cases, models, and services/utils.
Keeping code readable and maintainable can be a big challenge. That’s why keeping the apps decoupled is so important.
This is how we handle app independence in the starter kit:
from core.models import User as CoreUser
class User(CoreUser):
def my_app_specific_property(self):
...
class Meta:
proxy = True
Code language: Django (django)
class ModelName(BaseModel):
essential_field = models.TextField()
class Meta:
managed = False
db_table = 'original_app_model_name'
class ModelWhichNeedsRelationship(BaseModel):
relation = models.ForeignKey(ModelName, ...)
...
Code language: Django (django)
The Django starter kit has been essential in maintaining code quality and consistency across our projects.
But our journey doesn’t end here. At Cheesecake Labs, we recognize that web and mobile development requires ongoing adaptation and innovation.
We firmly believe that while our current approach is a robust foundation, there’s no silver bullet. We remain committed to refining our architecture to meet the unique demands of each project that comes our way.
Some of the exciting features we’re planning for the future:
We’re excited to keep innovating and finding new ways to streamline our development and build better products for our clients.
To learn more about how we work at Cheesecake Labs, check out the rest of our blog, where we cover all things software development and design and dive deep into our processes and approach.
And if you’d like expert help building delightful digital products, let’s chat! We’d love to hear from you.
A computer scientist who loves to study new technologies. Also enjoys rap, watching movies and TV shows, sports (especially soccer), and playing videogames.