TF-via-PR
TF-via-PR copied to clipboard
GitHub Action to plan and apply OpenTofu/Terraform (TF) via pull request (PR) automation.
OpenTofu/Terraform via Pull Request
[!IMPORTANT]
GitHub Action to automate OpenTofu or Terraform (TF) CLI commands via pull request (PR) interaction.
Overview: Highlights · Usage · Security · Changelog · License

Highlights
What does it do?
Add PR comments or workflow input in the form of CLI commands to trigger OpenTofu or Terraform operations.
Run TF CLI commands dynamically on PR open, update and close without manual intervention.
- Automate TF plan and apply as part of GitOps framework to deliver consistent infrastructure-as-code (IaC) across environments.
- Run multiple TF commands in a matrix strategy for parallel provisioning of resources across different workspaces or directories.
Speed up workflow by caching TF module plugins and substituting input variables.
- Use ".terraform.lock.hcl" file (which should be included in version control) to cache TF plugins and associated dependencies for faster subsequent workflow runs.
- A number of input parameters can be substituted in the parsed command, such as: workspace, var-file and backend-config pre/suffixes.
Who is it for?
Best suited for DevOps and Platform engineers who want to empower their teams to self-service TF without the overhead of self-hosting runners, containers or VMs like Atlantis.
- Environment deployment protection rules mitigate the risk of erroneous changes along with standardized approval requirements.
- Each PR and associated workflow run holds a complete log of infrastructure changes for ease of collaborative debugging as well as audit compliance.
Usage
How does it work?
Functional workflow examples are provided below, along with associated permissions and triggers. The full list of inputs is documented below.
- TF via PR Comments
- TF via PR Comments or Input
- TF via PR Input with AWS Authentication
- TF via PR Input with Matrix Strategy
-
TF via PR Input with
tenv
Proxy
[!NOTE]
- Pin your workflow version to a specific release tag or SHA to harden your CI/CD pipeline security against supply chain attacks.
- Environment variables are automatically assumed, enabling cloud provider authentication (e.g., preceding aws-actions/configure-aws-credentials action can be used to pass short-lived credentials).
Where to use it?
Use-case: Provision resources in a workspace with a variable file, followed by targeted destruction. View PR.
#1 PR Comment: Plan configuration in a workspace with a variable file.
-tf=plan -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars
#2 PR Comment: Apply configuration in a workspace with a variable file.
-tf=apply -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars
#3 PR Comment: Plan destruction of targeted resources in a workspace with a variable file.
-tf=plan -destroy -target=aws_instance.sample,data.aws_ami.ubuntu -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars
#4 PR Comment: Apply destruction of targeted resources in a workspace with a variable file.
-tf=apply -destroy -target=aws_instance.sample,data.aws_ami.ubuntu -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars
Use-case: Provision resources with a backend, followed by destruction without confirmation, simultaneously. View PR.
#1 PR Comment: Plan configuration with a backend file.
-tf=plan -chdir=stacks/sample_bucket -backend-config=backend/dev.tfbackend
#2 PR Comment: Apply configuration with a backend file.
-tf=apply -chdir=stacks/sample_bucket -backend-config=backend/dev.tfbackend
#3 PR Comment: Destroy configuration with a backend file without confirmation.
-tf=apply -destroy -auto-approve -chdir=stacks/sample_bucket -backend-config=backend/dev.tfbackend
Parameters
Inputs
Name | Description |
---|---|
apply_require_approval Default: false |
Boolean flag to require PR review approval for TF apply commands or consider deployment protection rules. |
backend_config_from_workspace Default: false |
Boolean flag to re-use TF -workspace as -backend-config argument, if supplied. |
backend_config_prefix Example: ../backend/ |
String prefix for TF -backend-config argument, if -backend-config (or -workspace and backend_config_from_workspace ) is supplied. |
backend_config_suffix Example: .tfbackend |
String suffix for TF -backend-config argument, if -backend-config (or -workspace and backend_config_from_workspace ) is supplied. |
cache_plugins Default: true |
Boolean flag to cache TF plugins for faster workflow runs (requires .terraform.lock.hcl file). |
chdir_prefix Example: stacks/ |
String prefix for TF -chdir argument. This is a global argument that switches to a different directory. |
cli_uses Example: tofu |
String name of TF CLI to use and override default assumption from wrapper environment variable. |
command_input Example: -tf=plan -workspace=dev |
String input to run TF CLI command with arguments directly via workflow automation. |
fmt_enable Default: true |
Boolean flag to enable TF fmt command and display diff of changes. |
plan_outline Default: true |
Boolean flag to output TF plan outline of changes. |
recreate_comment Default: true |
Boolean flag to recreate PR comment on update instead of editing the existing one. |
validate_enable Default: false |
Boolean flag to enable TF validate command check. |
var_file_from_workspace Default: false |
Boolean flag to re-use TF -workspace as -var-file argument, if supplied. |
var_file_prefix Example: ../env/ |
String prefix for TF -var-file argument, if -var-file (or -workspace and var_file_from_workspace ) is supplied. |
var_file_suffix Example: .tfvars |
String suffix for TF -var-file argument, if -var-file (or -workspace and var_file_from_workspace ) is supplied. |
Outputs
Name | Description |
---|---|
command Example: {tf:plan,chdir:stacks/sample_bucket} |
JSON object of the parsed command. |
comment_id Example: 1234567890 |
String ID of the PR comment created or updated by the workflow. |
plan_id Example: stacks-sample-bucket-tfplan |
String ID of the TF plan file artifact's unique identifier. |
tf_fmt |
String output of the truncated TF fmt command. |
tf_output |
String output of the truncated last TF command. |
Security
Integrating security in your CI/CD pipeline is critical to practicing DevSecOps. This GHA aims to be secure by default, and it should be complemented with your own review to ensure it meets your (organization's) security requirements.
- All 3 GHAs used in this workflow are pinned to a specific SHA to prevent supply chain attacks from upstream dependencies: actions/cache, actions/github-script and actions/upload-artifact.
- Restrict changes to certain environments with deployment protection rules or
apply_require_approval
so that approval is required from authorized users/teams before changes to the infrastructure can be applied. - Ease of integration with OpenID Connect by passing short-lived credentials as environment variables to the workflow.
Changelog
- All notable changes to this project are documented in human-friendly releases.
- The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[!NOTE]
All forms of contribution are very welcome and deeply appreciated for fostering open-source projects.
- Please create a PR to contribute changes you'd like to see.
- Please raise an issue to discuss proposed changes or report unexpected behavior.
- Please open a discussion to share ideas about where you'd like to see this project go.
- Please consider becoming a stargazer if you find this project useful.
Includes a GitHub Codespaces dev container, which offers a tailored TF development environment, complete with tools and runtimes to lower the barrier to entry for contributors.
License
- This project is licensed under the permissive Apache License 2.0.
- All works herein are my own and shared of my own volition.
- Copyright 2022-2024 Rishav Dhar — All wrongs reserved.