---
title: "Engineering Practice"
canonical_url: https://www.janbrennenstuhl.eu/topics/engineering-practice/
author: Jan Brennenstuhl
---

# Engineering Practice

Notes from running software: cloud infrastructure, European hosting, tooling and the occasional migration.


Older notes from running software in production: AWS, migrations, tooling, and more recently moving this site to European infrastructure.


## Entries

- [Goodbye Big Tech: My European JAMstack Migration](https://www.janbrennenstuhl.eu/european-jamstack/) (2025-07-06, essay): A static JAMstack site can run entirely on European providers: Codeberg for code and Forgejo Actions deployment, Bunny CDN for hosting, and Plausible for cookie-free analytics. Markdown: https://www.janbrennenstuhl.eu/european-jamstack/index.md
- [Bunny Shield Review: 3 Things Need Improvement](https://www.janbrennenstuhl.eu/bunny-shield-review/) (2025-06-07, essay): Bunny Shield is easy to set up and has reasonable default rules, but it needs bot allowlisting, traceable WAF event logs and a fix for blocked Let's Encrypt HTTP-01 challenges. Markdown: https://www.janbrennenstuhl.eu/bunny-shield-review/index.md
- [Bunny CDN: How to redirect Root Domain to Subdomain](https://www.janbrennenstuhl.eu/bunny-cdn-domain-redirect/) (2025-04-22, essay): With Bunny DNS you can redirect a root domain to its www subdomain using a redirect (RDR) record, or a pull zone or CNAME record combined with a 301 Edge Rule. Markdown: https://www.janbrennenstuhl.eu/bunny-cdn-domain-redirect/index.md
- [Learning AssertJ: Null ain't Blank](https://www.janbrennenstuhl.eu/assertj-null-not-blank/) (2017-09-05, essay): AssertJ's isNotBlank() passes for a null string, unlike Apache Commons StringUtils and Hibernate Validator, so Java tests that rely on it can miss null values. Markdown: https://www.janbrennenstuhl.eu/assertj-null-not-blank/index.md
- [On Making Spring Security OAuth RFC-compliant](https://www.janbrennenstuhl.eu/spring-security-oauth-rfc/) (2017-02-01, essay): Contributing a small fix to a long-lived library such as Spring Security OAuth means fitting its old Java version, minimal dependencies and backward compatibility, and it teaches you the underlying RFCs. Markdown: https://www.janbrennenstuhl.eu/spring-security-oauth-rfc/index.md
- [AWS DynamoDB: Backup & Recovery Strategy](https://www.janbrennenstuhl.eu/dynamodb-backup/) (2016-01-18, essay): You can back up DynamoDB tables with nightly Data Pipeline exports to S3, use a Lambda function to restage them into a test environment, and restore from the same backups. Markdown: https://www.janbrennenstuhl.eu/dynamodb-backup/index.md
- [Evolution of a Microservice: A Git History Visualisation](https://www.janbrennenstuhl.eu/microservice-evolution/) (2015-05-21, essay): Microservices keep their benefits only if teams cut them down regularly: one service grew from 5k to 15k lines of code in a year and shrank back to about 5k after a split. Markdown: https://www.janbrennenstuhl.eu/microservice-evolution/index.md
- [Abusing JSON: Why AWS CloudFormation sucks?!](https://www.janbrennenstuhl.eu/aws-cloudformation/) (2015-05-21, essay): CloudFormation misuses JSON as a scripting language, which makes templates hard to read and maintain, and tools such as CFN-Sphere add YAML templates and stack dependency resolution on top. Markdown: https://www.janbrennenstuhl.eu/aws-cloudformation/index.md
- [Python Docopt: Convert Tuple List to Dictionary](https://www.janbrennenstuhl.eu/python-tuples-to-dict/) (2015-04-28, essay): With docopt you can turn a comma-separated option such as key1.value1,key1.value2 into a dictionary of lists by splitting it into tuples and collecting them in a defaultdict(list). Markdown: https://www.janbrennenstuhl.eu/python-tuples-to-dict/index.md
- [How to Migrate SVN to GIT with History?](https://www.janbrennenstuhl.eu/svn-to-git/) (2015-04-15, essay): You can migrate an SVN repository to Git with its full history and authors by extracting the SVN authors into an authors file and running git svn clone -A authors.txt. Markdown: https://www.janbrennenstuhl.eu/svn-to-git/index.md
- [How to Check Github Licenses](https://www.janbrennenstuhl.eu/github-license-checker/) (2015-03-25, essay): Github-Licker is a small Python command-line tool that uses the GitHub Licenses API to list the licenses of an organization's repositories and find repositories without a license file. Markdown: https://www.janbrennenstuhl.eu/github-license-checker/index.md
- [AWS Monocyte: Let's Build a Cloud Immune System](https://www.janbrennenstuhl.eu/aws-cloud-immune-system/) (2015-03-18, essay): AWS Monocyte finds and deletes AWS resources in regions outside the EU, so companies can let teams run their own accounts and still enforce EU data rules, if only reactively. Markdown: https://www.janbrennenstuhl.eu/aws-cloud-immune-system/index.md
