Template Repositories with GitHub and Terraform

Fergus MacDermot
5 min readSep 12, 2020

This page covers GitHub template repositories: what, why and how to set up and makes some suggestions for what a template could include. As with everything, get the basics right early on, to avoid technical debt in the future.

What are template repos?

Template repos in GitHub allow users to generate a new repo with the same structure including files, folders and branches as another repo. This means that when repo A is marked as a template repo, it can be used to generate files and folders when creating repo B . It’s the cookie cutter concept and so is a once only operation, which means changes to the template will not be reflected in template driven repos. I keep a basic template for a Terraform repo in GitHub.

Why should I use them?

  • Avoiding copy and paste between repos, jump start a project

Everyone hates the initial set up of a repo when it is ‘what files do I need in here’, ‘what structure do we use in this company’ etc etc. No need to have those boring initial commits where baseline files and folders are copied in. It’s all done for you.

  • Creating organisational standards, better for automation

It is highly likely that your organisation has standard structures, policies and principles and using templates is a good way to ensure a project starts off this way. For the automation team it helps. Automation only works well with predictable patterns because outliers and non-standard structures create those ugly conditional statements.

How to Set Up?

Setting template repos up is very easy. GitHub provide simple guidelines for manual set up. However, you really should be using some form of automation to manage your GitHub repos. For Pulumi you can use the isTemplate property to create a template repository, then when creating a new repo use RepositoryTemplate. For Terraform, on the github_repository resource, set the is_template property to true. and note that the terraform code overrides the template. Setting up the repo itself in Terraform can be done with the GitHub provider like this:

resource "github_repository" "template_repo_terraform" {
name = "template-repo-terraform"
description
= "Repo that can be used as a baseline to terraform projects"

private
= false
has_issues
= true
has_wiki
= false
allow_merge_commit
= true
allow_squash_merge
= false
allow_rebase_merge
= false
delete_branch_on_merge
= true
auto_init
= true
is_template
= true
gitignore_template
= "Terraform"
license_template
= "mit"
topics
= ["template", "terraform"]
}

# Set up baseline configs for the repo
resource "github_branch_protection" "template_repo_terraform" {
repository = github_repository.template_repo_terraform.name
branch = "master"
enforce_admins
= false
required_status_checks
{
strict = true
contexts
= ["Terraform", "triage"]

}
# uncomment to require reviewers, not needed with only one person
// required_pull_request_reviews {
// dismiss_stale_reviews = true
// require_code_owner_reviews = false
// }
}

What are Useful Examples?

Every project will have a different context and so the actual template files will change. There are a few key concepts to consider when setting up a repo:

  • anything that is copy and pasted into a new repository should be added to the template.
  • standards, guidelines and folder structures are ideal as templates, this includes things like expected documentation, code and script locations
  • build processes are often the same and so make them part of the template
  • templates provide initial considerations and guidelines to a project creator

Here are some examples that are likely to be core elements in a new project.

readme -the contents will obviously change per project, the purpose of the readme will not. It should contain what the project does, why it is useful, how to get started, how to get help and who looks after the project.

PR template -the PR template is an important method for providing help and promoting good practices on how to make contributions. It saves time for the reviewer and contributor by explaining the correct way to create a PR. The template should include guidelines on any processes and pre-requisites for PRs, for example, description of why the PR is needed, what checks and testing has been done, tickets numbers, security considerations.

codeowners -these files are useful for showing ownership of folder and files, as well as ensuring merges only occur with the owners consent.

license -important on open source projects to set the conditions for using the project. Most go with MIT or Apache License that allow free usage, more importantly, if your project has no license, it means the Enterprises will not/cannot use your code because it may be considered as “all rights reserved” by the owner.

.gitignore -a no brainer, who wants to be bothered by warnings to add unnecessary files.

folder structure -to remove friction for developers when moving between teams it can be useful to have a predefined folder structure that everyone knows. It also pre-empts the ‘where do I put this’ line of thought. Common folder structures would include locations for code, scripts, documentation, test data, sql and configuration.

build frameworks -builds processes should be clear and simple. On the same type of project, build methods should be standardised across a company to avoid outliers and Galapagos style builds. The preferred option is to create a build framework that hides the complexity from developers. Imagine if a new step such as a security scan is introduced in to the build process, how many projects would need fixing? Docker images are often ideal to do this.

documentation -similar to a readme, providing a template for documentation encourages usage. Examples are lightweight architectural decision records, decisions are often made on a day to day and it is very useful to keep a record of these in the code to help new developers understand the evolution of the code or project.

pre-commit files -projects often have pre-commit files that perform tasks such as linting before a commit. They do require installation and so can be better as GitHub actions.

GitHub actions -GitHub actions cab be really useful for a number of purposes. Build, release, linting, commit message rules and labelling are the obvious use cases.

Summary

Templates save a huge amount of time when setting up a new repository by removing boring decisions like folder structure and initial file creation. On top of that, predictable patterns reduce friction and cognitive overload when moving between projects because a developer will not expend effort figuring out where things are. Set the templates up as early as possible for maximum benefit!

At the time of writing, GitHub templates do not support variable substitution, that would be a very useful addition. It is a bit annoying to update files with project names.

Links

Template Repositories from GitHub

ThoughtWorks: Lightweight Architectural Decision Records (in GitHub)

Licenses and why you should

--

--

Fergus MacDermot

Better engineering through platform engineering. I work 100% remote for an awesome company Ikigai Digital building digital banks in cloud environments.