Workflow breakdown

You must store workflow files in the .github/workflows directory of your repository.

name:

name: this-is-an-example

optional The name of your workflow. GitHub displays the names of your workflows on your repository’s “Actions” tab. If you omit name, GitHub sets it to the workflow file path relative to the root of the repository.

run-name:

run-name: some text

optional The name for workflow runs generated from the workflow, which will appear in the list of workflow runs on your repository’s “Actions” tab.

run-name: Deploy to ${{ inputs.deploy_target }} by @${{ github.actor }}

on:

on:

Specifies the trigger for this workflow. You can define single or multiple events that can trigger a workflow, or set a time schedule. You can also restrict the execution of a workflow to only occur for specific files, tags, or branch changes.

Run workflow when you push a commit or tag.

 on:
  push:

Run workflow when specific branches are pushed (main) or when a branch starts with (releases) but ignore specific branches (updates)

on:
 push:
  branches:
   - 'main'
   - 'releases/**'
  branches-ignore:
   - 'updates'

Run workflow when specifics tags are pushed (prod) or when tags starting with (v1.**)

on:
 push:
  tags:
   - prod
   - v1.**

Run workflow when push affects specific files such as any java script files (**.js)

on:
 push:
  paths:
   - '**.js'

Run workflow but not if the push affects files in a specific path name pattern.

on:
 push:
  paths-ignore:
    - '.github/workflows/**'

Runs your workflow when activity on a pull request in the workflow’s repository occurs. For example, if no activity types are specified, the workflow runs when a pull request is opened or reopened or when the head branch of the pull request is updated.

 on:
  pull_request:

Run workflow when a specific type of pull requests is opened (opened, reopened)

on:
 pull_request:
  types: [opened, reopened]

To manually trigger a workflow, use the workflow_dispatch event.

on: workflow_dispatch

To manually trigger a workflow and require inputs before proceeding. This example will ask you to choose one of two options (apply, destroy) and the value can then be used within the steps to trigger a specific step.

on:
  workflow_dispatch:
    inputs:
      TFAction:
        type: choice
        description: Terraform action
        options:
        - Apply
        - Destroy

<insert rest of workflow between here>

  steps:
   - name: Terraform Apply - manually
    if: ${{ inputs.TFAction == 'apply'}}
    run: terraform apply -auto-approve -input=false
    
   - name: Terraform Destroy - manually
    if: ${{ inputs.TFAction == 'destroy'}}
    run: terraform destroy -auto-approve    

env:

env:

A map of environment variables that are available to the steps of all jobs in the workflow.

These variables can be used to call the Actions secrets values.

env:
 ARM_CLIENT_ID: ${{secrets.ARM_CLIENT_ID}}
 ARM_CLIENT_SECRET: ${{secrets.ARM_CLIENT_SECRET}}
 ARM_TENANT_ID: ${{secrets.ARM_TENANT_ID}}
 ARM_SUBSCRIPTION_ID: ${{secrets.ARM_SUBSCRIPTION_ID}}

defaults:

defaults:

Use defaults to create a map of default settings that will apply to all jobs in the workflow.

This example sets the default shell (bash) and working directory (project).

defaults:
 run:
  shell: bash
  working-directory: project/

jobs:

jobs:

References

Workflow syntax for GitHub Actions

Events that trigger workflows

# .github/workflows/infrastructure.yaml
#
# this workflow will
#   1) create a github hosted ubuntu runner
#   2) use github hosted secrets to authenticate to azure
#   3) checkout the code from the working-directory
#   4) install terraform on the runner
#   5) check whether the configuration files are formatted properly
#   6) initialize the terraform backend
#   7) validate the terraform file
#   8) generate a terraform plan
#       8a) if the trigger is a pull_request then the format, init and plan will be written to the comments
#   9) highlights if a plan fails
#   10) if destroy is selected via a workflow_dispatch the resources will be destroyed
#   11) if all else is okay then the resources will be created/updated

name: Infrastructure

# this workflow should only run when a commit is pushed to the main branch or on any pull requests
# any changes to the workflow folder will be ignored
on:
  workflow_dispatch:
    inputs:
      TFAction:
        type: choice
        description: Terraform action
        options:
        - Apply
        - Destroy

  push:
    paths-ignore:
      - '.github/workflows/**'
    branches:
      - main
  
  pull_request:

# this workflow uses data in the this path
defaults:
  run:
    working-directory: project/

# use a github runner
jobs:
  action:
    runs-on: ubuntu-latest

# use github secrets to authenticate to azure
    env:
      ARM_CLIENT_ID: ${{secrets.ARM_CLIENT_ID}}
      ARM_CLIENT_SECRET: ${{secrets.ARM_CLIENT_SECRET}}
      ARM_TENANT_ID: ${{secrets.ARM_TENANT_ID}}
      ARM_SUBSCRIPTION_ID: ${{secrets.ARM_SUBSCRIPTION_ID}}


    steps:
      # checkout the current configuration from the working-directory
      - name: Checkout the code
        uses: actions/checkout@v3
    
      # retrieves the Terraform CLI used in the GitHub action workflow
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1

      # checks whether the configuration has been properly formatted. If the configuration isn't properly formatted this step will produce an error.
      - name: Terraform format
        id: fmt
        run: terraform fmt

      # initializes the configuration used in the GitHub action workflow
      - name: Terraform Init
        id: init
        run: terraform init
        
      # validates the configuration used in the GitHub action workflow
      - name: Terraform Validate
        id: validate
        run: terraform validate -no-color

      # generates a Terraform plan
      - name: Terraform Plan
        id: plan
        run: terraform plan -no-color -input=false
        continue-on-error: true

      # adds a comment to the pull request with the results of the format, init and plan steps.
      # in addition, it displays the plan output (steps.plan.outputs.stdout).
      # this step only runs on pull requests.
      - name: Update Pull Request
        uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
            #### Terraform Initialization ✅\`${{ steps.init.outcome }}\`
            #### Terraform Plan ✅\`${{ steps.plan.outcome }}\`
            #### Terraform Validation ✅\`${{ steps.validate.outcome }}\`
            <details><summary>Show Plan</summary>
            \`\`\`\n
            ${process.env.PLAN}
            \`\`\`
            </details>
            *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
            github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: output
            })            
      
      # returns whether a plan was successfully generated or not.
      # this step highlights whenever a plan fails because the "Terraform Plan" step continues on error
      - name: Terraform Plan Status
        if: steps.plan.outcome == 'failure'
        run: exit 1
      
      # applies the configuration (automated trigger)
      # this step will only run when a commit is pushed to main
      # either directly or as a result of a pull request
      - name: Terraform Apply - on push
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: terraform apply -auto-approve -input=false

      # allows you to create all the resources (manual trigger)
      # only runs when manually triggered by workflow dispatch and selecting the apply choice
      - name: Terraform Apply - manually
        if: ${{ inputs.TFAction == 'apply'}}
        run: terraform apply -auto-approve -input=false

      # allows you to destroy all the resources (manual trigger)
      # only runs when manually triggered by workflow dispatch and selecting the destroy choice
      - name: Terraform Destroy - manually
        if: ${{ inputs.TFAction == 'destroy'}}
        run: terraform destroy -auto-approve      
Last modified July 21, 2024: update (e2ae86c)