Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tfmake/tfmake
Automating Terraform with the power of make.
https://github.com/tfmake/tfmake
github-actions make terraform
Last synced: about 1 month ago
JSON representation
Automating Terraform with the power of make.
- Host: GitHub
- URL: https://github.com/tfmake/tfmake
- Owner: tfmake
- License: mit
- Created: 2023-02-27T20:13:56.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-10-30T21:28:01.000Z (about 1 month ago)
- Last Synced: 2024-10-30T22:17:37.704Z (about 1 month ago)
- Topics: github-actions, make, terraform
- Language: Shell
- Homepage:
- Size: 127 KB
- Stars: 17
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-tf - tfmake - Automating Terraform with the power of make. (Tools / Community providers)
README
# tfmake
**tfmake** is a tool for automating Terraform with the power of make. It is designed for projects with multiple modules; particularly when dependencies among them are present and an ordered execution is required.
## Requirements
- bash 4+
- yq
- make## Limitations
- To ensure an ordered execution, all dependencies between modules MUST be explicitly declared.
- A module path SHOULD NOT contain spaces; e.g. use `sample_module` instead of `sample module`.## Installation
### Git
```bash
git clone https://github.com/tfmake/tfmake.git
sudo cp -r tfmake/usr/local/* /usr/local/
sudo chmod +x /usr/local/bin/tfmake
```## Usage
```
Usage:
tfmake command [options]Core Commands:
context Set the execution context: plan, apply, or destroy.
init Initialize the data directory for Terraform execution.
makefile Generate a Makefile for Terraform execution.
run Run the generated Makefile for Terraform execution.Other Commands:
cleanup Cleanup the data directory.
config Modify tfmake configuration.
graph Generate a graph from Terraform modules and their dependencies.
summary Create a Markdown summary.
touch Touch modified files.
version Show the current version.Shortcut Commands:
plan Shortcut for core commands using the "plan" context.
apply Shortcut for core commands using the "apply" context.
destroy Shortcut for core commands using the "destroy" context.GitHub Commands:
gh-pr-comment Add a comment to a GitHub pull request.
gh-step-summary Add content to GitHub Step Summary.Global options:
-h, --help, help Print this help and exit.
-v, --version An alias for the "version" subcommand.
```## How tfmake works
### The .tfmake file
**tfmake** is based on the _explicit declaration_ of dependencies between modules. In a Terraform project, this could be inferred from the usage of `terraform_remote_state` data resource; although implicit dependencies cases could exist.
The syntax for the `.tfmake` file is as follow:
```YAML
dependencies: [, , ..., ]
```e.g. if module C depends on A and B, the following declaration is needed:
```YAML
dependencies:
- A
- B
```> All dependencies MUST be declared. Omitting some of them based on transitivity is discouraged.
### Core commands
Similar to Terraform, **tfmake** is composed of multiple commands, each one playing an important role in a predefined sequence.
The core sequence is made up of four commands, as illustrated in the next diagram.
```mermaid
flowchart LRclassDef primary fill:#a3cfbb,stroke:#a3cfbb,color:#136c44;
classDef secondary fill:#fee69b,stroke:#fee69b,color:#987405;context("tfmake context")
init("tfmake init")
makefile("tfmake makefile")
run("tfmake run")context --> init --> makefile --> run
context:::primary
init:::primary
makefile:::primary
run:::primary
```#### tfmake context
Allows to define the Terraform command to execute: `plan`, `apply`, or `destroy`.
```
tfmake context plan
```#### tfmake init
As the name suggests, this command deals with the initialization process, used to discover the Terraform modules, and their dependencies. That information is persisted for further usage.
```
tfmake init
```Sometimes, a requirement arises to ignore some modules inside a project. The option `-i|--ignore` supports it, by passing a space separated list of modules.
```
tfmake init -i "X Y Z"
```#### tfmake makefile
This command acts like a code generator, using the information gathered by **init** to create a `Makefile`. Each module is added as a _target_, with their files and dependencies as _prerequisites_. The **tfmake** context determines the Terraform command to use as part of the _target's recipes_.
```
tfmake makefile
```What follows is an adapted example for a three-module project plan `Makefile`.
```Makefile
all: A B CA: $(wildcard A/*.tf A/*.tfvars)
terraform -chdir="A" init
terraform -chdir="A" planB: $(wildcard B/*.tf B/*.tfvars) A
terraform -chdir="B" init
terraform -chdir="B" planC: $(wildcard C/*.tf C/*.tfvars) A B
terraform -chdir="C" init
terraform -chdir="C" plan
```When the `Makefile` is there, it's possible to use it for running the [make](https://man7.org/linux/man-pages/man1/make.1.html) utility.
One of the goals of **tfmake** is to avoid unnecessary executions. If a module (_target_) files or their dependencies don't change, there is no need to run a `plan`, `apply`, or `destroy` on it. This behavior, derived from the `make` way of working, reduces the execution time and favors cost optimization.
> The make program uses the makefile description and the last-modification times of the files to decide which of the files need to be updated.
#### tfmake run
As mentioned before, a `Makefile` is the entrypoint for `make` execution. The **run** command brings some advantages over it, including multiple modes of execution and a proper handling of failures for CI/CD pipelines.
By default (`tfmake run`), the command calls `make` and runs it with the semantics described above, avoiding unnecessary executions. However, two other modes exist with the options `--all` and `--dry-run`.
The first one executes Terraform `plan`, `apply`, or `destroy` for all modules, whereas the second is similar to the default mode, producing a list of modules but without running their recipes.
### A special command
#### tfmake touch
The **touch** command is a wrapper over the corresponding Linux utility, and is used to change the modification time of modules files. This is mandatory in a GitHub Actions workflow after a [checkout](https://github.com/actions/checkout) or could be used in a local environment to force the `make` semantics.
For instance, using the modules A, B and C; a change in a `.tf` file inside B will cause the execution of it and C in that order.
The command could be executed with the option `-f|--files` and a list of space separated files.
```
tfmake touch -f "A/main.tf B/main.tf"
```is equivalent to
```
tfmake touch -f "A/main.tf" -f "B/main.tf"
```> In a GitHub Actions workflow use `tj-actions/changed-files` to get the list of changed files.
### Outputs and feedback
When the **run** command is finished, the outputs from Terraform executions for each module are stored for further processing. The **summary** command produces a report in Markdown format, after joining them all.
When running `tfmake` as part of a GitHub Actions workflow, it is possible to use the report to provide feedback in two different ways.
The first is by means of a Pull Request comment, with the help of the following command.
```
tfmake gh-pr-comment --number "${{ github.event.pull_request.number }}"
```The second alternative is based on the GitHub Actions Step Summary feature, with the help of the **gh-step-summary** command.
## License
[MIT License](https://github.com/tfmake/tfmake/blob/main/LICENSE)