dflook/terraform-github-actions

repository·main·Indexed 21 days ago

https://github.com/dflook/terraform-github-actions

A suite of GitHub Actions for automating Terraform and OpenTofu workflows. Features include planning, applying, linting, drift detection, and management of ephemeral test environments. Provides specific actions for Terraform (dflook/terraform-*) and OpenTofu (dflook/tofu-*), including tools for validation, formatting, and workspace management.

Tokens
46.3K
Snippets
124
Records
161
Agent score
74%

What's inside dflook-terraform-github-actions

  1. Retrieve Terraform root-level outputs with terraform-output

    main

    The terraform-output action retrieves root-level outputs from a Terraform configuration and makes them available as GitHub Actions outputs or a JSON file. This is useful for passing infrastructure metadata (like hostnames, IDs, or network configurations) from a Terraform apply step to subsequent steps in a workflow.

    Key Features

    • Individual Outputs: Every Terraform output becomes a unique GitHub Action output.
    • JSON File: A single JSON file containing all outputs is generated at the path specified by json_output_path.
    • Type Casting:
      • Primitives (string, number, bool): Cast to strings (booleans become 'true' or 'false').
      • Complex Types (list, set, tuple, map, object): Cast to a JSON string. Use the GitHub Actions fromJson() function to parse them back into objects/arrays.
    - name: Get outputs
      uses: dflook/terraform-output@v2
      id: tf-outputs
      with:
        path: my-terraform-config
  2. Generate an OpenTofu plan with `tofu-plan`

    main

    The tofu-plan action generates an OpenTofu plan. If triggered by a Pull Request event, it automatically adds a comment to the PR containing the plan results. To use the generated plan in a subsequent step (e.g., with dflook/tofu-apply), you should capture the plan_path output.

    Note: To enable PR comments, you must provide a GITHUB_TOKEN via environment variables with at least pull-requests: write permissions.

    - name: Generate Plan
      uses: dflook/tofu-plan@v3
      with:
        path: ./terraform
        label: production
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  3. Check for infrastructure drift with tofu-check

    main

    The tofu-check action is used to detect drift in OpenTofu managed resources. It runs the tofu plan command and fails the GitHub Actions build if any changes are required. This is ideal for scheduled jobs to notify you if manual changes have been made to your infrastructure outside of your OpenTofu configuration.

    name: Check for infrastructure drift
    
    on:
      schedule:
        - cron:  "0 8 * * *"
    
    jobs:
      check_drift:
        runs-on: ubuntu-latest
        name: Check for drift of OpenTofu configuration
        steps:
          - name: Checkout
            uses: actions/checkout@v4
    
          - name: Check
            uses: dflook/tofu-check@v2
            with:
              path: my-tofu-configuration
  4. Check for Terraform drift with terraform-check

    main

    The terraform-check action is used to detect drift in Terraform-managed resources. It executes a terraform plan and fails the GitHub Actions build if any changes are required. This is typically used in scheduled workflows to notify developers when manual changes have been made to infrastructure that deviate from the defined Terraform configuration.

    name: Check for infrastructure drift
    
    on: 
      schedule:
        - cron: "0 8 * * *"
    
    jobs:
      check_drift:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v4
    
          - name: Check
            uses: dflook/terraform-check@v2
            with:
              path: my-terraform-configuration
  5. Handle complex Terraform outputs in GitHub Actions

    main

    When the terraform-apply action outputs Terraform complex types (lists, sets, tuples, maps, or objects), they are exported as JSON strings.

    • Lists/Sets/Tuples are cast to JSON arrays.
    • Maps/Objects are cast to JSON objects.

    To use these values in a GitHub Actions workflow expression, use the fromJSON() function.

    # Example: Accessing a complex output
    - name: Use Output
      run: echo "The hostname is ${{ fromJSON(steps.apply.outputs.service_hostname) }}"
  6. Understand tofu-remote-state outputs and type casting

    main

    The action provides two ways to access OpenTofu outputs:

    1. json_output_path: A string representing the path to a JSON file containing all root module outputs. This file is relative to the Actions workspace.

      • OpenTofu list, set, and tuple types are cast to a JSON array.
      • OpenTofu map and object types are cast to a JSON object.
    2. Individual Outputs: An action output is created for every output defined in your OpenTofu configuration.

      • Primitive types (string, number, bool): Cast to a string. Boolean values become 'true' or 'false'.
      • Complex types (list/set/tuple & map/object): Output as a JSON string. To use these in a workflow expression, use the GitHub Actions fromJSON() function.

    Example Mapping: If your OpenTofu config has:

    output "service_hostname" {
      value = "example.com"
    }

    Running the action produces an output named service_hostname with the value example.com.

  7. How the terraform-version action determines versions

    main

    The terraform-version action identifies the correct Terraform/OpenTofu and provider versions for a root module. It follows a specific precedence order to discover the version, stopping at the first match found:

    1. Cloud Workspace: The version set in a remote backend or cloud configuration (if the workspace exists).
    2. Terraform Configuration: The required_version constraint in your .tf files. If a range is provided, the latest matching version is used.
    3. tfswitch: A .tfswitchrc file in the module path.
    4. tfenv: A .terraform-version file in the module path.
    5. asdf: A .tool-versions file in the module path or any parent path.
    6. Environment Variable: The TERRAFORM_VERSION variable (supports version constraints; uses the latest match).
    7. State File: The version that created the current state file (best effort).
    8. Default: The latest available Terraform version.

    Note: Other actions in the dflook/terraform-github-actions suite automatically perform this discovery. You only need to run this specific action if you need to access the version numbers as GitHub Actions outputs in your workflow.

  8. How the tofu-version action determines versions

    main

    The tofu-version action automatically discovers the correct OpenTofu and provider versions for your root module. It follows a specific precedence order to find the version, stopping at the first match found in this order:

    1. Cloud Workspace: The version set in a remote backend or cloud configuration (if the remote workspace exists).
    2. Configuration Constraint: A required_version constraint within your OpenTofu configuration.
    3. tfswitch: A .tfswitchrc file in the module path.
    4. tofuenv: A .opentofu-version file in the module path.
    5. tfenv: A .terraform-version file in the module path.
    6. asdf: A .tool-versions file in the module path or any parent path.
    7. Environment Variables: The TERRAFORM_VERSION variable (or OPENTOFU_VERSION if the former is unset) containing a version constraint.
    8. State File: The OpenTofu version that created the current state file (best effort).
    9. Default: The latest available OpenTofu version.

    Note: Other actions in the dflook/terraform-github-actions suite use this same discovery logic automatically. You only need to run this specific action if you need to access the version numbers as workflow outputs.

  9. Use the terraform-fmt-check action

    main

    The terraform-fmt-check action uses the terraform fmt command to verify that all files in a specified Terraform configuration directory follow the canonical format. If any files are improperly formatted, the action will add a failing GitHub check for the specific file and fail the job. This is ideal for enforcing formatting standards before merging code.

    Basic Usage

    To run a check on every push, use the following workflow configuration:

    name: Check file formatting
    
    on: [push]
    
    jobs:
      check_format:
        runs-on: ubuntu-latest
        name: Check Terraform file are formatted correctly
        steps:
          - name: Checkout
            uses: actions/checkout@v4
    
          - name: terraform fmt
            uses: dflook/terraform-fmt-check@v2
            with:
              path: my-terraform-config
  10. Use a pre-built custom image

    main

    The most efficient method for custom environments is to build a custom image once and push it to a registry. Because GitHub Actions does not allow specifying a custom image for an existing Docker-based action, you must follow these steps:

    1. Fork the repository.
    2. Create a custom Dockerfile based on the official image (e.g., danielflook/terraform-github-actions:v1.37.0) and install your required tools.
    3. Update the action.yaml metadata files in your fork to point the image key to your custom image in a registry.
    4. Use your forked actions in your workflows.

    Example Custom Dockerfile:

    FROM danielflook/terraform-github-actions:v1.37.0
    
    RUN curl -skL https://aka.ms/InstallAzureCLIDeb | bash
    RUN apt-get install -y --no-install-recommends postgresql-client

    Example action.yaml modification:

    runs:
      using: docker
      image: docker://your-registry/your-custom-image:latest

    Example Workflow usage:

    jobs:
      plan:
        runs-on: ubuntu-latest
        name: Create terraform plan
        steps:
          - name: plan
            uses: <your_org>/terraform-github-actions/terraform-plan@main
    runs:
      using: docker
      image: docker://danielflook/terraform-github-actions:v1.37.0
  11. Use the tofu-fmt-check action to validate OpenTofu formatting

    main

    The tofu-fmt-check action uses the tofu fmt command to ensure all OpenTofu configuration files in a specified directory follow the canonical format. If any files are incorrectly formatted, the action adds a failing GitHub check for the specific file and fails the job. This is ideal for preventing unformatted code from being merged.

    Basic Usage

    To run a check on a specific directory (e.g., my-tofu-config) on every push:

    name: Check file formatting
    
    on: [push]
    
    jobs:
      check_format:
        runs-on: ubuntu-latest
        name: Check OpenTofu file are formatted correctly
        steps:
          - name: Checkout
            uses: actions/checkout@v4
    
          - name: tofu fmt
            uses: dflook/tofu-fmt-check@v2
            with:
              path: my-tofu-config
  12. Use the tofu-remote-state action to retrieve OpenTofu outputs

    main

    The tofu-remote-state action retrieves root-level outputs from an OpenTofu remote state. It allows you to access provisioned infrastructure values (like URLs, hostnames, or IDs) in subsequent steps of your GitHub Actions workflow.

    To use it, you must specify the backend_type and provide the necessary configuration via backend_config or backend_config_file.

    jobs:
      get_remote_state:
        runs-on: ubuntu-latest
        steps:
          - name: Get remote state
            uses: dflook/tofu-remote-state@v2
            id: remote-state
            with:
              backend_type: s3
              backend_config: |
                bucket=tofu-github-actions
                key=tofu-remote-state
                region=eu-west-2
    
          - name: Use an output
            run: |
              echo "The URL is ${{ steps.remote-state.outputs.url }}"