Skip to content

Reusable workflow CI/CD to interface Terraform CLI via GitHub PR comments.

License

Notifications You must be signed in to change notification settings

AlexanderWiechert/tf-via-pr

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Terraform Via PR Comments — Reusable Workflow

Important

This reusable workflow enables you to plan and apply changes to Terraform configurations in bulk with pull request (PR) comments: for a CLI-like experience on the web UI. It's powered by GitHub Actions to maximize compatibility and minimize maintenance for DIY deployments. It's ready-made for AWS as a functional example, and can easily be extended to support other cloud providers.

Overview · Usage [Workflow · Examples · Parameters · AWS] · Security · Roadmap · Contributions · License

Overview

Terraform is a platform-agnostic tool for managing cloud and on-prem resources by provisioning infrastructure as code (IaC).
  • It enables you to define resources in human-readable configuration files that can be version controlled and shared for consistent state management.
GitHub Actions is a continuous integration and continuous deployment (CI/CD) platform that enables you to automate your project's pipelines with custom workflows.
  • This repository hosts a reusable workflow that parses PR comments for Terraform commands and runs them in a remote environment.
  • Also supports GitHub Codespaces dev container, which offers a tailored Terraform development environment, complete with tools and runtimes to lower the barrier to entry for contributors.
Best suited for DevOps and Platform engineers who want to empower their teams to self-service Terraform 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

Workflow

Copy the following snippet into ".github/workflows/terraform.yml" file in your repository. Replace the contents of env_vars with environment variables required by your Terraform configuration.

on:
  issue_comment:
    types: [created, edited]
  pull_request:
    types: [synchronize]

jobs:
  terraform:
    uses: devsectop/tf-via-pr/.github/workflows/tf.yml@main
    secrets:
      env_vars: |
        AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}

Note

  • Pin your workflow version to a specific release tag or SHA to harden your CI/CD pipeline security against supply chain attacks.
  • The optional env_vars input lets you pass in environment variables as key-value pairs while masking sensitive values from logs.
    • Each entry must be on a new line and separated by an equals sign (=).
    • Entries prefixed with BASE64_ will be decoded from Base64 twice. E.g., for passing in temporary/OIDC credentials output from a previous job.

Examples

Use-case scenario: Provision resources in multiple workspaces with different input variables, followed by targeted destruction. View PR in situ.

#1 PR Comment: Plan configuration in a workspace with input variable file.
-terraform=plan -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars

#2 PR Comment: Apply configuration in a workspace with input variable file.
-terraform=apply -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars

#3 PR Comment: Plan destruction of targeted resources in a workspace with input variable file.
-terraform=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 input variable file.
-terraform=apply -destroy -target=aws_instance.sample,data.aws_ami.ubuntu -chdir=stacks/sample_instance -workspace=dev -var-file=env/dev.tfvars

Use-case scenario: Provision resources with multiple different backends in bulk, simultaneously, followed by destruction without confirmation. View PR in situ.

#1 PR Comment: Plan multiple configurations with different backends.
-terraform=plan -chdir=stacks/sample_bucket -backend-config=backend/dev.tfvars
-terraform=plan -chdir=stacks/sample_bucket -backend-config=backend/stg.tfvars

#2 PR Comment: Apply multiple configurations with different backends.
-terraform=apply -chdir=stacks/sample_bucket -backend-config=backend/dev.tfvars
-terraform=apply -chdir=stacks/sample_bucket -backend-config=backend/stg.tfvars

#3 PR Comment: Destroy multiple configurations with different backends without confirmation.
-terraform=apply -destroy -auto-approve -chdir=stacks/sample_bucket -backend-config=backend/dev.tfvars
-terraform=apply -destroy -auto-approve -chdir=stacks/sample_bucket -backend-config=backend/stg.tfvars

Parameters

Inputs

Name Description Default Example
CONFIG_TF_CHDIR_PREFIX String prefix for Terraform -chdir argument. This is a global option that switches to a different directory. stacks/
CONFIG_TF_REQUIRE_APPROVAL Boolean flag to require PR review approval for Terraform apply commands. Consider deployment protection rules for specific environments. false true
CONFIG_TF_VAR_FILE_PREFIX String prefix for Terraform -var-file argument, if -var-file (or -workspace and CONFIG_TF_WORKSPACE_AS_VAR_FILE) is supplied. ../vars/
CONFIG_TF_VAR_FILE_SUFFIX String suffix for Terraform -var-file argument, if -var-file (or -workspace and CONFIG_TF_WORKSPACE_AS_VAR_FILE) is supplied. .tfvars
CONFIG_TF_WORKSPACE_AS_VAR_FILE Boolean flag to re-use Terraform -workspace as -var-file argument, if either of them are supplied. false true
TF_CLI_HOSTNAME Hostname of Terraform cloud/enterprise instance to place within the credentials block of Terraform CLI configuration. app.terraform.io tf.acme.com
TF_CLI_TOKEN API token for Terraform cloud/enterprise instance to place within the credentials block of Terraform CLI configuration.
TF_CLI_VERSION Version of Terraform CLI to install, supporting semver ranges. latest >=1.5.1

Outputs

Name Description Example
COMMENT_SHA SHA of the PR comment that triggered the workflow. 1234567…
PARSED_COMMENT JSON object of the parsed PR comment. [{"terraform":"plan", "chdir":"stacks/sample_bucket"}]
PROMPT_MATRIX Matrix strategy of the last successfully completed job. {"terraform":"plan", "chdir":"stacks/sample_bucket"}
TF_PLAN_ID Unique identifier of the Terraform plan file, used for artifact upload/download and bot comment update. 42stacks-sample-bucket-tfplan
WORKING_DIRECTORY Working directory of the Terraform configuration, used in -chdir argument. stacks/sample_bucket

AWS

Environment isolation is achieved by nesting directories (e.g., stacks/), each with their own providers, to enable management of multiple: backends, workspaces and variable files from a single repository.

Reusable, stateless components can be placed within a dedicated directory (e.g., "stacks/modules/") to be imported into each environment like so.

module "sample_bucket" {
  source = "../modules/s3_bucket"

Note

Security

Integrating security in your CI/CD pipeline is critical to practicing DevSecOps. This reusable workflow is designed to be secure by default, and it should be complemented with your own review to ensure it meets your (organization's) security requirements.

  • All associated GitHub Actions used in this workflow are pinned to a specific SHA to prevent supply chain attacks from third-party upstream dependencies.
  • Restrict changes to certain environments with deployment protection rules so that approval is required from authorized users/teams before changes to the infrastructure can be applied.

Roadmap

  • Pass environment variables to the workflow as secrets to prevent sensitive values from being exposed in logs.
    • The secrets.env_vars input allows any number of key-value pairs to be passed to the workflow for use as masked environment variables, enabling you to customize the workflow to your Terraform configuration.
    • GitHub Actions has no official support for passing secrets from a prior job in the caller workflow to a reusable workflow. Tracked in discussion#13082, discussion#17554 and discussion#26671.
  • Parse PR comments as input commands to interface with Terraform CLI, returning the output as bot comments.
    • Opted to use hashicorp/setup-terraform with a custom wrapper script to enable parsing of PR comments as input commands with CLI arguments.
  • Use GitHub's reusable workflow or composite actions for CI/CD of Terraform configuration changes.
    • Opted for reusable workflow due to more granular control over workflow execution: from managing concurrency of queued workflows to running jobs in parallel with strategy.matrix.
    • Adapted ternary operator-like behavior to enable if-else logic within GitHub Actions expressions.
    • Unlike pull_request, issue_comment events can only be triggered to run on the default branch, which complicates testing changes to the reusable workflow.
    • When the workflow is run with matrix strategy, the output is set by the last successfully completed job rather than a combination of all jobs.

Contributions

All forms of contribution are very welcome and deeply appreciated for fostering open-source software.

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 2023 Rishav Dhar — All wrongs reserved.

About

Reusable workflow CI/CD to interface Terraform CLI via GitHub PR comments.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • HCL 100.0%