Skip to content

Cookiecutter for Platform Engineering

Posted on:March 23, 2025

Cookiecutter for Platform Engineering

Overview

What is Cookiecutter?

Cookiecutter is a command-line utility that generates projects from project templates. It allows you to create a project structure that can be reused across multiple projects. Cookiecutter uses Jinja2 templating to generate files based on the project template. Jinja2 is a powerful and familiar templating engine that allows you to define variables and expressions in your templates.

Why Use Cookiecutter for Platform Engineering?

Platform engineering involves creating self-service tools, automation, and infrastructure that reduces the friction for developers. Cookiecutter can be used to create projects that align with platform standards and best practices. By using Cookiecutter, you can ensure consistency across projects and reduce the time spent setting up new projects. The goal of this article is to understand how cookiecutter can be used to create and maintain applications that deploy to a platform.

What We’ll Cover

In this article, we’ll learn how to use Cookiecutter. We’ll create a basic project template and use Cookiecutter to generate a new project based on the template. We’ll also discuss the benefits of using Cookiecutter in platform engineering. In future articles, we’ll explore more advanced use cases of Cookiecutter in platform engineering and how it can be integrated into automation pipelines and other tools.

Prerequisites

Before we get started, make sure you have the following installed:

I recommend using asdf to manage your local development environment. You can install Python 3 using asdf with the following command:

asdf plugin add python
asdf install python 3.13.2
asdf global python 3.13.2

A Basic Template Project

Let’s start by creating a basic project template that we can use with Cookiecutter. We’ll create a simple project structure with a few files and directories. We will create the following files and directories:

basic-cookiecutter-template
├── cookiecutter.json
└── {{ cookiecutter.project_slug }}
    ├── README.md
    └── cookiecutter.json

cookiecutter.json

This file serves as the list of properties with defaults that cookiecutter will use to generate the project. Here is an example cookiecutter.json file:

{
  "project_name": "My App",
  "project_slug": "my-app",
  "project_description": "My App is a simple app.",
  "author": "Your Name"
}

{{ cookiecutter.project_slug }}/README.md

This file isnt required, but will demonstrate how to use Jinja2 templating in the project template. Here is an example README.md file:

# {{ cookiecutter.project_name }}

{{ cookiecutter.project_description }}

Notice the templating syntax {{ cookiecutter.project_name }} and {{ cookiecutter.project_description }}. These will be replaced with the values provided in the cookiecutter.json file when the project is generated.

{{ cookiecutter.project_slug }}/cookiecutter.json

This file is optional and can be used to override the values in the top-level cookiecutter.json file, in case you want to edit the values for a the project later. We’ll go over how that works later.

{
  "project_name": "{{ cookiecutter.project_name }}",
  "project_slug": "{{ cookiecutter.project_slug }}",
  "project_description": "{{ cookiecutter.project_description }}",
  "author": "{{ cookiecutter.author }}"
}

Using Cookiecutter

Now that we have our project template, we can use Cookiecutter to generate a new project. To do this, we need to install Cookiecutter:

# ensure you have python installed

python -m pip install cookiecutter

Once Cookiecutter is installed, we can generate a new project using the project template we created. Make sure you are in the directory where you want to create the new project. Cookiecutter will create a new directory with the project files based on the project template we created earlier.

# reference the project template locally
python -m cookiecutter ./basic-cookiecutter-template

# or use a remote template
python -m cookiecutter gh:username/repo

Cookiecutter will prompt you for the values of the properties defined in the cookiecutter.json file. You can either accept the default values or provide your own values. Once you have provided the values, Cookiecutter will generate the project files based on the project template.

Updating the Project from the template

If you want to update the project later, you can use the cookiecutter.json file in the project directory to update the values. You can then run Cookiecutter again to regenerate the project files with the updated values. Just run the command again in the project directory referencing the project template:

python -m cookiecutter ./basic-cookiecutter-template

Warn: This can cause issues depending on the changes you made to the project. Some knowledge of the project template and the changes you made to the project is required to update the project successfully.

Advanced Template Features

Cookiecutter utilizes Jinja2 templating to generate project files. This really opens up the possibilities for creating dynamic project templates. Before we go too much further, we need to cover some of basic Jinja2 templating syntax.

Statements are surrounded by {% … %} and are used for control flow and logic.

{% ... %}

Expressions are surrounded by {{ … }} and are used to print to the template output.

{{ ... }}

Comments are surrounded by {# … #} and are not included in the template output.

{# ... #}

Lets tip-toe into some of the features you can use to create more versatile templates.

Conditional Blocks

You can use conditional blocks to include or exclude components based on inputs. Lets say you want to include tooling support for a specific language based on the user input. You can use conditional blocks to include or exclude the tooling setup based on the user input.

# ./setup-local.sh
{% if cookiecutter.language == 'python' %}
# setup for python
{% elif cookiecutter.language == 'go' %}
# setup for go
{% endif %}

Filters

Filters can be used to modify the output of expressions. For example, you can use the upper filter to convert a string to uppercase.

{{ cookiecutter.project_name | upper }}

Or you might want to use the replace filter to replace spaces with underscores in a string.

{{ cookiecutter.project_name | replace(' ', '_') }}

Available filters can be found here.

How to Use Cookiecutter for Platform Engineering

My interest in Cookiecutter is primarily related how I can disseminate changes to deployment and automation tools across multiple projects. I want to be able to make a change to a project template, then kick off a automation to update all the projects that use that template. Depending on you’re organization, this could be a great way to automate the update process, unburdening developers and platform engineers from having to manually update each project.

While cookiecutter is only a piece of a larger solution to automating project updates, it is still a powerful tool that can be used to create reusable project templates that align with platform standards and best practices. By using Cookiecutter, you can ensure consistency across projects and reduce the time spent setting up new projects.

Conclusion

In this article, we learned how to use Cookiecutter to create a project template and introduced some ideas on how it can be used in platform engineering. We created a basic project template and used Cookiecutter to generate a new project based on the template. We also discussed how Cookiecutter can be used in platform engineering to streamline project setup, enforce best practices, and improve consistency across projects. By using Cookiecutter, you can create reusable project templates that align with platform standards and reduce the time spent setting up new projects.

In the future, we will explore more advanced use cases of Cookiecutter in platform engineering and dive deeper into how it can be integrated into automation pipelines and other tools.

References