|
|
on:
pull_request:
push:
branches: [main]
jobs:
provision:
runs-on: ubuntu-latest
permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add comment and label.
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_wrapper: false
# Run plan by default, or apply on merge.
- uses: op5dev/tf-via-pr@v13
with:
working-directory: path/to/directory
command: ${{ github.event_name == 'push' && 'apply' || 'plan' }}
arg-lock: ${{ github.event_name == 'push' }}
arg-backend-config: env/dev.tfbackend
arg-var-file: env/dev.tfvars
arg-workspace: dev-use1
plan-encrypt: ${{ secrets.PASSPHRASE }}
Tip
- All supported arguments (e.g.,
-backend-config
,-destroy
,-parallelism
, etc.) are listed below. - Environment variables can be passed in for cloud platform authentication (e.g., configure-aws-credentials for short-lived credentials via OIDC).
- Recommend setting
terraform_wrapper
/tofu_wrapper
tofalse
in order to output the detailed exit code for better error handling.
The following workflows showcase common use cases, while a comprehensive list of inputs is documented below.
Runs on |
Runs on |
Runs on |
Runs on |
Runs on |
Runs on |
Before the workflow uploads the plan file as an artifact, it can be encrypted-at-rest with a passphrase using plan-encrypt
input to prevent exposure of sensitive data (e.g., ${{ secrets.PASSPHRASE }}
). This is done with OpenSSL's symmetric stream counter mode (256 bit AES in CTR) encryption with salt and pbkdf2.
In order to decrypt the plan file locally, use the following commands after downloading the artifact (adding a whitespace before openssl
to prevent recording the command in shell history):
unzip <tf.plan>
openssl enc -d -aes-256-ctr -pbkdf2 -salt \
-in <tf.plan> \
-out tf.plan.decrypted \
-pass pass:"<passphrase>"
<tf.tool> show tf.plan.decrypted
All supported CLI argument inputs are listed below with accompanying options, while workflow configuration inputs are listed here.
Type | Name | Description |
---|---|---|
CLI | working-directory |
Specify the working directory of TF code, alias of arg-chdir .Example: path/to/directory |
CLI | command |
Command to run between: plan or apply .1Example: plan |
CLI | tool |
Provisioning tool to use between: terraform or tofu .Default: terraform |
Check | format |
Check format of TF code. Default: false |
Check | validate |
Check validation of TF code. Default: false |
Check | plan-parity |
Replace plan file if it matches a newly-generated one to prevent stale apply.2 Default: false |
Security | plan-encrypt |
Encrypt plan file artifact with the given input.3 Example: ${{ secrets.PASSPHRASE }} |
Security | retention-days |
Duration after which plan file artifact will expire in days. Example: 90 |
Security | token |
Specify a GitHub token. Default: ${{ github.token }} |
UI | label-pr |
Add a PR label with the command input (e.g., tf:plan ).Default: true |
UI | comment-pr |
Add a PR comment: always , on-change , or never .4Default: always |
UI | comment-method |
PR comment by: update existing comment or recreate and delete previous one.5Default: update |
UI | tag-actor |
Tag the workflow triggering actor: always , on-change , or never .4Default: always |
UI | hide-args |
Hide comma-separated list of CLI arguments from the command input.6 Default: detailed-exitcode,parallelism,lock,out,var= |
UI | show-args |
Show comma-separated list of CLI arguments in the command input.6 Default: workspace |
- Both
command: plan
andcommand: apply
include:init
,fmt
(withformat: true
),validate
(withvalidate: true
), andworkspace
(witharg-workspace
) commands rolled into it automatically.
To separately run checks and/or generate outputs only,command: init
can be used. - Originally intended for
merge_group
event trigger,plan-parity: true
input helps to prevent stale apply within a series of workflow runs when merging multiple PRs. - The secret string input for
plan-encrypt
can be of any length, as long as it's consistent between encryption (plan) and decryption (apply). - The
on-change
option is true when the exit code of the last TF command is non-zero (ensureterraform_wrapper
/tofu_wrapper
is set tofalse
). - The default behavior of
comment-method
is to update the existing PR comment with the latest plan/apply output, making it easy to track changes over time through the comment's revision history.
- It can be desirable to hide certain arguments from the last run command input to prevent exposure in the PR comment (e.g., sensitive
arg-var
values). Conversely, it can be desirable to show other arguments even if they are not in last run command input (e.g.,arg-workspace
orarg-backend-config
selection).
Note
- Arguments are passed to the appropriate TF command(s) automatically, whether that's
fmt
,init
,validate
,plan
, orapply
. - For repeated arguments like
arg-var
,arg-var-file
,arg-backend-config
,arg-replace
andarg-target
, use commas to separate multiple values (e.g.,arg-var: key1=value1,key2=value2
).
Applicable to respective "plan" and "apply" command
inputs ("init" included).
Name | CLI Argument |
---|---|
arg-auto-approve |
-auto-approve |
arg-backend-config |
-backend-config |
arg-backend |
-backend |
arg-backup |
-backup |
arg-chdir |
-chdir Alias: working-directory |
arg-compact-warnings |
-compact-warnings |
arg-concise |
-concise |
arg-destroy |
-destroy |
arg-detailed-exitcode |
-detailed-exitcode Default: true |
arg-force-copy |
-force-copy |
arg-from-module |
-from-module |
arg-generate-config-out |
-generate-config-out |
arg-get |
-get |
arg-lock-timeout |
-lock-timeout |
arg-lock |
-lock |
arg-lockfile |
-lockfile |
arg-migrate-state |
-migrate-state |
arg-parallelism |
-parallelism |
arg-plugin-dir |
-plugin-dir |
arg-reconfigure |
-reconfigure |
arg-refresh-only |
-refresh-only |
arg-refresh |
-refresh |
arg-replace |
-replace |
arg-state-out |
-state-out |
arg-state |
-state |
arg-target |
-target |
arg-upgrade |
-upgrade |
arg-var-file |
-var-file |
arg-var |
-var |
arg-workspace |
-workspace Alias: TF_WORKSPACE |
Applicable only when format: true
.
Name | CLI Argument |
---|---|
arg-check |
-check Default: true |
arg-diff |
-diff Default: true |
arg-list |
-list |
arg-recursive |
-recursive Default: true |
arg-write |
-write |
Applicable only when validate: true
.
Name | CLI Argument |
---|---|
arg-no-tests |
-no-tests |
arg-test-directory |
-test-directory |
Type | Name | Description |
---|---|---|
Artifact | plan-id |
ID of the plan file artifact. |
Artifact | plan-url |
URL of the plan file artifact. |
CLI | command |
Input of the last TF command. |
CLI | diff |
Diff of changes, if present (truncated). |
CLI | exitcode |
Exit code of the last TF command. |
CLI | result |
Result of the last TF command (truncated). |
CLI | summary |
Summary of the last TF command. |
Workflow | check-id |
ID of the check run. |
Workflow | comment-body |
Body of the PR comment. |
Workflow | comment-id |
ID of the PR comment. |
Workflow | job-id |
ID of the workflow job. |
Workflow | run-url |
URL of the workflow run. |
Workflow | identifier |
Unique name of the workflow run and artifact. |
View security policy and reporting instructions.
Tip
Pin your workflow version to a specific release tag or SHA to harden your CI/CD pipeline security against supply chain attacks.
View all notable changes to this project in Keep a Changelog format, which adheres to Semantic Versioning.
Tip
All forms of contribution are very welcome and deeply appreciated for fostering open-source projects.
- Create a PR to contribute changes you'd like to see.
- Raise an issue to propose changes or report unexpected behavior.
- Open a discussion to discuss broader topics or questions.
- Become a stargazer if you find this project useful.
- Handling of inputs which contain space(s) (e.g.,
working-directory: path to/directory
). - Handling of comma-separated inputs which contain comma(s) (e.g.,
arg-var: token=1,2,3
)—useTF_CLI_ARGS
workaround.
- This project is licensed under the permissive Apache License 2.0.
- All works herein are my own, shared of my own volition, and contributors.
- Copyright 2016-present Rishav Dhar — All wrongs reserved.