Loading repository data…
Loading repository data…
awslabs / repository
A library with Make targets, Ansible playbooks, Jinja templates (and more) designed to boost common software development tasks and enhance governance.
A library of Make targets, Ansible playbooks, and Jinja templates that you add to a project as a Git submodule to standardize common development tasks.
![]() |
|---|
| Installing AWS Code Habits |
AWS Code Habits is a reusable library you embed in your own repository. It groups everyday development tasks behind consistent make targets so that every contributor runs the same commands to install tools, format code, run linters, manage infrastructure, and generate documentation.
The library has three parts:
lib/make/ provide the commands you run, such as terraform/plan, python/test, and doc/build.lib/ansible/ perform multi-step actions, such as scaffolding .github/ directories and rendering the README.README.md from data in doc/habits.yaml.You add the library to a project as a Git submodule (or as a vendored copy) and include its Make targets from your own Makefile. It is intended for teams that want a shared, version-controlled set of development commands across many repositories.
The following diagram shows how your project consumes the library:
flowchart LR
project["Your project"]
makefile["Your Makefile<br/>includes lib/make/*/*.mk<br/>and lib/make/*.mk"]
targets["make targets<br/>(terraform/plan, python/test, doc/build)"]
tools["Tools<br/>(Terraform, AWS CDK, Python, Node.js, Go)"]
ansible["Ansible playbooks<br/>(lib/ansible/)"]
project --> makefile
makefile -->|include .mk glob| targets
targets -->|run a tool directly| tools
targets -->|multi-step actions| ansible
make targets across repositories.README.md from a single source file, doc/habits.yaml..gitignore, pre-commit configuration, and .github/ directories for actions, workflows, issues, and pull requests.The library supports Linux, macOS, and Windows (with some limitations). Many targets include cross-platform detection and use the appropriate installation method for the host.
You need the following installed before you use the library:
You use AWS Code Habits as a Git submodule. From the root directory of your project, run:
git submodule add --name habits -b main https://github.com/awslabs/aws-code-habits.git habits
This clones the library into a habits/ directory that tracks the main branch.
Pin the submodule to a release. Tracking main exposes you to unannounced changes. After you add the submodule, check out a tagged release (or a specific commit SHA) and commit the resulting submodule pointer:
git -C habits fetch --tags
git -C habits checkout v1.5.0 # or any tag from CHANGELOG.md
git add habits && git commit -m "chore: pin habits to v1.5.0"
See CHANGELOG.md for available releases. To move to a newer release later, repeat the checkout step against a newer tag.
When you next clone your repository, pass --recurse-submodules so the submodule is fetched:
git clone --recurse-submodules <your-repository-url>
If you already cloned the repository without --recurse-submodules, initialize and fetch the submodule with:
git submodule update --init --recursive
To automate the installation steps, use the helper scripts in the scripts/ directory.
Add the submodule with the command in Installation.
Create a Makefile in your project root (or add these lines to an existing one):
export WORKSPACE = $(shell pwd)
export HABITS = $(WORKSPACE)/habits
include $(WORKSPACE)/tools.env # pin the version of your tools
include $(HABITS)/lib/make/*/*.mk
include $(HABITS)/lib/make/*.mk
List the available targets:
make help
You see a list of targets with one-line descriptions:
Available targets:
doc/build Builds documentation
doc/init Initialize documentation
habits/check Performs checks
...
List every target with the default help target:
make help
For the full target reference, see Makefile.md.
Several technology-specific Makefiles add their own help target:
make terraform/help
make nodejs/help
make python/help
make go/help
make gitignore/help
Create a .pre-commit-config.yaml in your working directory:
make pre-commit/init
Run all pre-commit hooks against every file:
make pre-commit/run
Initialize the documentation files. This creates a doc/ directory containing habits.yaml:
make doc/init
Edit doc/habits.yaml, then rebuild the README:
make doc/build
README.md is rendered from doc/habits.yaml. Do not edit README.md by hand — your changes are overwritten on the next make doc/build.
Add aggregate targets to your Makefile that call library targets. For example, to combine documentation and pre-commit checks:
.PHONY: hygiene
hygiene: doc/build pre-commit/run
To drive an AWS CloudFormation workflow:
.PHONY: hygiene
hygiene: aws/cloudformation/hygiene
.PHONY: plan
plan: aws/cloudformation/create-change-set
.PHONY: discard
discard: aws/cloudformation/delete-change-set
.PHONY: apply
apply: aws/cloudformation/execute-change-set
Each technology groups its targets under a common prefix.
Terraform:
make terraform/install
make terraform/init
make terraform/plan
make terraform/apply
make terraform/workspace/list
make terraform/workspace/new WORKSPACE_NAME=dev
AWS Cloud Development Kit (AWS CDK):
make aws/cdk/install
make aws/cdk/bootstrap
make aws/cdk/deploy
make aws/cdk/synth
Python:
make python/install
make python/virtualenv/init
make python/poetry/install
make python/poetry/init
make python/test
Node.js:
make nodejs/install
make nodejs/init/express
make nodejs/init/react
make nodejs/init/vue
make nodejs/add PACKAGE=express
make nodejs/add/dev PACKAGE=jest
Go:
make go/install
make go/app/build OUTPUT=myapp
make go/app/test
Gitignore:
make gitignore/init/web
make gitignore/init/python
make gitignore/init/node
Verify that a project has the files the library expects:
make habits/check
Run technology-specific tests:
make python/test
make python/test/coverage
make nodejs/test
make go/app/test
make go/app/test/coverage
You configure the library through environment files that your Makefile includes and through variables you pass on the command line.
tools.env — pins tool versions. Every *_VERSION variable uses ?=, so a value you set in tools.env overrides the default.*_SHA256 variables — when set, the matching tool installer verifies the downloaded archive with sha256sum -c and aborts on mismatch. When unset, the installer prints a warning and proceeds.CONFIRM — set CONFIRM=yes to skip the confirmation prompt on destructive targets, for example in continuous integration.Destructive targets are gated behind a confirmation prompt: terraform/apply, terraform/destroy, aws/cdk/destroy*, nuke/run, docker/remove-images, docker/remove-volumes, and docker/prune. For the full list of safety variables and recommended values, see docs/HARDENING.md.
You include the library's .mk files from your Makefile. Each .mk file under lib/make/ defines targets for one tool or technology. Targets that perform multi-step actions, such as doc/build and doc/init, delegate to Ansible playbooks under lib/ansible/.
README.md is generated. The doc/build target runs an Ansible playbook that renders the Jinja template lib/ansible/templates/readme.j2 using the data in doc/habits.yaml, then writes the result to README.md.
The following diagram shows the documentation render pipeline:
flowchart LR
cmd["make doc/build"]
target["doc/build target<br/>(lib/make/doc.mk)"]
playbook["Ansible playbook<br/>(lib/ansible/playbooks/doc/build.yaml)"]
data["doc/habits.yaml<br/>(source data)"]
template["readme.j2<br/>(lib/ansible/templates/)"]
readme["README.md<br/>(generated)"]
cmd --> target
target --> playbook
data --> playbook
template --> playbook
playbook -->|render| readme
See Contributing.
See Security to report a vulnerability. Do not file public GitHub issues for security reports.
This project is licensed under the MIT-0 License. See the LICENSE file.
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.