skip to Main Content

I am trying to implement a github actions workflow with a job which will plan and apply my terraform code changes only for directory where changes were made. The problem I am currently facing is that I can’t figure out how to switch directories so that terraform plan is executed from a directory where code has been updated/changed.

I have a monorepo setup which is as follow:

repo
  tf-folder-1
  tf-folder-2
  tf-folder-3

Each folder contains an independent terraform configuration. So, for example I would like run a workflow only when files change inside tf-folder-1. Such workflow needs to switch to working directory which is tf-folder-1 and then run terraform plan/apply.

jobs:
  terraform:
    name: "Terraform"
    runs-on: ubuntu-latest
  defaults:
    run:
      working-directory: ./tf-folder-1
  steps:
    - name: Checkout
      uses: actions/checkout@v3     

    - name: Configure AWS credentials from Test account
      uses: aws-actions/configure-aws-credentials@v1
      with:
        role-to-assume: arn:aws:iam::000000000000000:role/deploy-role
        aws-region: eu-west-2

    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v2
    ...

So far, I have the above terraform job but it only runs for statically defined working-directory. It doesn’t work with a use case where it should run the workflow when changes happen within specific folder. Can someone advise how to fix this pipeline?

Thanks

3

Answers


  1. Chosen as BEST ANSWER

    Here is the solution to run multiple jobs based on number of directories that have been update.

    In the below snippet you can see directories job which will check which directories have been updated, later it output an array or switch which is then used in matrix strategy for terraform job.

    jobs:
      directories:
        name: "Directory-changes"
        runs-on: ubuntu-latest
        steps:
          - uses: theappnest/terraform-monorepo-action@master
            id: directories
            with:
              ignore: |
                aws/**/policies
                aws/**/templates
                aws/**/scripts
          - run: echo ${{ steps.directories.outputs.modules }}
        outputs:
          dirs: ${{ steps.directories.outputs.modules }}
      
      terraform:
        name: "Terraform"
        runs-on: ubuntu-latest
        needs: directories
        strategy:
          matrix:
            directories: ${{ fromJson(needs.directories.outputs.dirs) }}
        defaults:
          run:
            working-directory: ${{ matrix.directories }}
        steps:
          - name: Checkout
            uses: actions/checkout@v3
    
          - name: Setup Terraform
            uses: hashicorp/setup-terraform@v2
            with:
              cli_config_credentials_token: ${{ secrets.TF_CLOUD_TEAM_API_TOKEN_PREPROD }}
    
          - name: Terraform Format
            id: fmt
            run: terraform fmt -check
    
          - name: Terraform Init
            id: init
            run: terraform init
          
          - name: Terraform Validate
            id: validate
            run: terraform validate -no-color
    
          - name: Terraform Plan
            id: plan
            if: github.event_name == 'pull_request'
            run: terraform plan -no-color -input=false
            continue-on-error: true
    

  2. GitHub Actions has path filtering you can take advantage of when you are working with workflows that are triggered off a push or push_request event.

    For example say you have a monorepo with the directories, tf_1, tf_2, and tf_3. You can do something like below for when changes occur to the directory tf_1.

    name: Demonstrate GitHub Actions on Monorepo 
    on:
      push:
        branches:
          - master
        paths:
          - 'tf_1/**'
    
    defaults:
      run:
        working-directory: tf_1 
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v1
    

    For more details on path filtering, please refer to the GitHub Actions syntax documentation.

    Login or Signup to reply.
  3. You can use a GitHub action that outputs the directories where the files have changed/modified, for example, this one: Changed-files or even perform the calculation with a shell step using git diff.

    If you use the GHA suggested you can set the input dir_names to true, which would output unique changed directories instead of filenames, based on the results of that you can change the directory to run your Terraform operations.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search