Skip to content

Merge branch 'main' into execute-orchestrate-custom-actions #1

Merge branch 'main' into execute-orchestrate-custom-actions

Merge branch 'main' into execute-orchestrate-custom-actions #1

Workflow file for this run

name: Pipelines
run-name: Run Gruntwork Pipelines
on:
workflow_call:
inputs:
# This field can be overriden to customize the runner used for pipelines
# workflows.
#
# IMPORTANT: To use self-hosted runners this workflow must be hosted in
# the same GitHub organization as your infra-live repository.
# See https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-self-hosted-runners
#
# The value must be an escaped JSON string that will be decoded to the
# jobs.runs-on field
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on
#
# For example:
# - A simple github runner: "\"ubuntu-22.04\""
# - A list of labels: "[\"self-hosted\", \"linux\"]"
# - A map: "{group: \"ubuntu-runners\", labels: \"ubuntu-20.04-16core\"}"
runner:
type: string
default: '"ubuntu-latest"'
api_base_url:
type: string
default: "https://api.prod.app.gruntwork.io/api/v1"
pipelines_binary_url:
type: string
default: ""
description: "Override where we fetch pipelines from, used for internal testing"
secrets:
PIPELINES_READ_TOKEN:
required: true
PR_CREATE_TOKEN:
required: false
env:
PIPELINES_CLI_VERSION: v0.36.2
PIPELINES_ACTIONS_VERSION: v3.4.3# TODO: update to whatever version comes after we merge matching actions PR

Check failure on line 40 in .github/workflows/pipelines.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/pipelines.yml

Invalid workflow file

You have an error in your yaml syntax on line 40
# GitHub Actions tends to hit resource exhaustion and kill running jobs
# if we leave parallelism unbounded, so we set the max to 10 for a sane default.
TERRAGRUNT_PARALLELISM: 10
jobs:
pipelines_orchestrate:
name: Detect Infrastructure Changes
runs-on: ${{ fromJSON(inputs.runner) }}
steps:
- name: Record workflow env vars
env:
PIPELINES_BINARY_URL: ${{ inputs.pipelines_binary_url }}
run: |
time_now=$(date -u +"%s")
echo "PIPELINES_JOB_START_TIME=$time_now" >> $GITHUB_ENV
echo "PIPELINES_BINARY_URL=$PIPELINES_BINARY_URL" >> $GITHUB_ENV
- name: Fetch Gruntwork Read Token
id: pipelines-gruntwork-read-token
uses: gruntwork-io/pipelines-credentials@v1
with:
PIPELINES_TOKEN_PATH: "pipelines-read/gruntwork-io"
FALLBACK_TOKEN: ${{ secrets.PIPELINES_READ_TOKEN }}
api_base_url: ${{ inputs.api_base_url }}
- name: Fetch Org Read Token
id: pipelines-customer-org-read-token
uses: gruntwork-io/pipelines-credentials@v1
with:
PIPELINES_TOKEN_PATH: pipelines-read/${{ github.repository_owner }}
FALLBACK_TOKEN: ${{ secrets.PIPELINES_READ_TOKEN }}
api_base_url: ${{ inputs.api_base_url }}
- name: Fetch Create PR Token
id: pipelines-propose-infra-change-token
uses: gruntwork-io/pipelines-credentials@v1
with:
PIPELINES_TOKEN_PATH: propose-infra-change/${{ github.repository_owner }}
FALLBACK_TOKEN: ${{ secrets.PR_CREATE_TOKEN }}
api_base_url: ${{ inputs.api_base_url }}
- name: Checkout Pipelines Actions
id: checkout_actions
uses: actions/checkout@v4
with:
path: pipelines-actions
repository: gruntwork-io/pipelines-actions
ref: ${{ env.PIPELINES_ACTIONS_VERSION }}
token: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
- name: Validate PIPELINES_READ_TOKEN
if: always() && steps.checkout_actions.conclusion != 'success'
env:
GH_TOKEN: ${{ github.token }}
GITHUB_ORG: ${{ github.repository }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
shell: bash
run: |
logs_url="https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
msg=$(printf "<h2>❌ Plan for $PR_HEAD_SHA</h2>❌ Gruntwork Pipelines was unable to checkout the <code>pipelines-actions</code> repository. Please ensure the <code>PIPELINES_READ_TOKEN</code> is valid and unexpired. <a href=\"https://docs.gruntwork.io/pipelines/security/machine-users#ci-read-only-user\">Learn More</a><br><br><br><a href=\"$logs_url\">View full logs</a>")
echo "::error:: $msg"
echo "$msg" >> "$GITHUB_STEP_SUMMARY"
pull_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
gh pr comment $pull_number -b "$msg" -R $GITHUB_ORG || true # || true incase this fails on a non-PR run
- name: Check out repo code
uses: actions/checkout@v4
with:
path: infra-live-repo
fetch-depth: 0
token: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
- name: Preflight Checks
uses: ./pipelines-actions/.github/actions/pipelines-preflight-action
with:
PIPELINES_READ_TOKEN: ${{ secrets.PIPELINES_READ_TOKEN }}
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
PR_COMMENT_WRITE_TOKEN: ${{ steps.pipelines-propose-infra-change-token.outputs.PIPELINES_TOKEN }}
- name: Pre Orchestrate Custom Action
uses: ./pipelines-actions/.github/custom-actions/pre-orchestrate
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
PR_COMMENT_WRITE_TOKEN: ${{ steps.pipelines-propose-infra-change-token.outputs.PIPELINES_TOKEN }}
- name: Pipelines Orchestrate
id: orchestrate
uses: ./pipelines-actions/.github/actions/pipelines-orchestrate
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
PR_COMMENT_WRITE_TOKEN: ${{ steps.pipelines-propose-infra-change-token.outputs.PIPELINES_TOKEN }}
- name: Post Orchestrate Custom Action
uses: ./pipelines-actions/.github/custom-actions/post-orchestrate
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
PR_COMMENT_WRITE_TOKEN: ${{ steps.pipelines-propose-infra-change-token.outputs.PIPELINES_TOKEN }}
jobs: ${{ steps.orchestrate.outputs.jobs }}
outputs:
pipelines_jobs: ${{ steps.orchestrate.outputs.jobs }}
pipelines_execute:
env:
JOB_NAME: ${{ contains(matrix.jobs.Action.Command, 'plan') && 'Plan' || 'Apply' }} - ${{ matrix.jobs.ChangeType }} - ${{ matrix.jobs.WorkingDirectory }}
name: ${{ contains(matrix.jobs.Action.Command, 'plan') && 'Plan' || 'Apply' }} - ${{ matrix.jobs.ChangeType }} - ${{ matrix.jobs.WorkingDirectory }}
needs: [pipelines_orchestrate]
runs-on: ${{ fromJSON(inputs.runner) }}
# GHA can't check for length, so we just check if there is an item in the 0 index
if: fromJson(needs.pipelines_orchestrate.outputs.pipelines_jobs)[0] != null
strategy:
fail-fast: false
matrix:
jobs: ${{ fromJson(needs.pipelines_orchestrate.outputs.pipelines_jobs) }}
steps:
- name: Record workflow env vars
env:
PIPELINES_BINARY_URL: ${{ inputs.pipelines_binary_url }}
run: |
time_now=$(date -u +"%s")
echo "PIPELINES_JOB_START_TIME=$time_now" >> $GITHUB_ENV
echo "PIPELINES_BINARY_URL=$PIPELINES_BINARY_URL" >> $GITHUB_ENV
- name: Fetch Gruntwork Read Token
id: pipelines-gruntwork-read-token
uses: gruntwork-io/pipelines-credentials@v1
with:
PIPELINES_TOKEN_PATH: "pipelines-read/gruntwork-io"
FALLBACK_TOKEN: ${{ secrets.PIPELINES_READ_TOKEN }}
api_base_url: ${{ inputs.api_base_url }}
- name: Fetch Org Read Token
id: pipelines-customer-org-read-token
uses: gruntwork-io/pipelines-credentials@v1
with:
PIPELINES_TOKEN_PATH: pipelines-read/${{ github.repository_owner }}
FALLBACK_TOKEN: ${{ secrets.PIPELINES_READ_TOKEN }}
api_base_url: ${{ inputs.api_base_url }}
- name: Fetch Create PR Token
id: pipelines-propose-infra-change-token
uses: gruntwork-io/pipelines-credentials@v1
with:
PIPELINES_TOKEN_PATH: propose-infra-change/${{ github.repository_owner }}
FALLBACK_TOKEN: ${{ secrets.PR_CREATE_TOKEN }}
api_base_url: ${{ inputs.api_base_url }}
- name: Checkout Pipelines Actions
uses: actions/checkout@v4
with:
path: pipelines-actions
repository: gruntwork-io/pipelines-actions
ref: ${{ env.PIPELINES_ACTIONS_VERSION }}
token: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
- name: Check out repo code
uses: actions/checkout@v4
with:
path: infra-live-repo
fetch-depth: 0
token: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
- name: Bootstrap Workflow
id: gruntwork_context
uses: ./pipelines-actions/.github/actions/pipelines-bootstrap
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
change_type: ${{ matrix.jobs.ChangeType }}
branch: ${{ matrix.jobs.Ref }}
working_directory: ${{ matrix.jobs.WorkingDirectory }}
account_id: ${{ matrix.jobs.AccountId }}
terragrunt_command: ${{ matrix.jobs.Action.Command }} ${{ matrix.jobs.Action.Args }}
additional_data: ${{ toJson(matrix.jobs.AdditionalData) }}
child_account_id: ${{ matrix.jobs.AdditionalData.ChildAccountId }}
account_names: ${{ matrix.jobs.AdditionalData.AccountNames }}
- name: Pre Execute Custom Action
uses: ./pipelines-actions/.github/custom-actions/pre-execute
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
account_id: ${{ matrix.jobs.AccountId }}
account_name: ${{ matrix.jobs.Name }}
job: ${{ toJson(matrix.jobs) }}
gruntwork_context: ${{ toJson(steps.gruntwork_context.outputs) }}
- name: "Run terragrunt ${{ steps.gruntwork_context.outputs.terragrunt_command }} in ${{ steps.gruntwork_context.outputs.working_directory }}"
id: terragrunt
uses: ./pipelines-actions/.github/actions/pipelines-execute
env:
TERRAGRUNT_AUTH_PROVIDER_CMD: "pipelines auth terragrunt-credentials --ci github-actions --cloud aws --wd . --disk-cache-duration-minutes 10"
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
tf_binary: ${{ steps.gruntwork_context.outputs.tf_binary }}
working_directory: ${{ steps.gruntwork_context.outputs.working_directory }}
terragrunt_command: ${{ steps.gruntwork_context.outputs.terragrunt_command }}
infra_live_repo_branch: ${{ steps.gruntwork_context.outputs.branch }}
gruntwork_config_file: ${{ steps.gruntwork_context.outputs.gruntwork_config_file }}
infra_live_repo: "."
infra_live_directory: "."
deploy_branch_name: ${{ steps.gruntwork_context.outputs.deploy_branch_name }}
- name: Get Logs URL
id: get_logs_url
uses: ./pipelines-actions/.github/actions/pipelines-get-job-logs-url
if: always()
with:
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
job_name: ${{ env.JOB_NAME }}
step_name_prefix: "Run terragrunt"
- name: Update comment
if: always()
uses: ./pipelines-actions/.github/actions/pipelines-status-update
with:
step_name: ${{ matrix.jobs.ChangeType }}
step_working_directory: ${{ matrix.jobs.WorkingDirectory }}
step_status: ${{ steps.terragrunt.conclusion == 'success' && 'success' || 'failed' }}
step_details: ${{ steps.terragrunt.outputs.formatted_plan_output }}
step_details_extended_log: ${{ steps.terragrunt.outputs.execute_stdout_log }}
pull_request_number: ${{ steps.gruntwork_context.outputs.pr_number }}
step_logs_url: ${{ steps.get_logs_url.outputs.step_logs_url }}
PR_COMMENT_WRITE_TOKEN: ${{ steps.pipelines-propose-infra-change-token.outputs.PIPELINES_TOKEN }}
- name: Post Execute Custom Action
uses: ./pipelines-actions/.github/custom-actions/post-execute
with:
PIPELINES_GRUNTWORK_READ_TOKEN: ${{ steps.pipelines-gruntwork-read-token.outputs.PIPELINES_TOKEN }}
PIPELINES_CUSTOMER_ORG_READ_TOKEN: ${{ steps.pipelines-customer-org-read-token.outputs.PIPELINES_TOKEN }}
account_id: ${{ matrix.jobs.AccountId }}
account_name: ${{ matrix.jobs.Name }}
job: ${{ toJson(matrix.jobs) }}
gruntwork_context: ${{ toJson(steps.gruntwork_context.outputs) }}
formatted_plan_output: ${{ steps.terragrunt.outputs.formatted_plan_output }}
execute_stdout_log: ${{ steps.terragrunt.outputs.execute_stdout_log }}
plan_folder: ${{ steps.terragrunt.outputs.plan_folder }}
outputs:
account_id: ${{ matrix.jobs.AccountId }}
branch: ${{ steps.gruntwork_context.outputs.branch }}
action: ${{ steps.gruntwork_context.outputs.action }}
working_directory: ${{ steps.gruntwork_context.outputs.working_directory }}
terragrunt_command: ${{ steps.gruntwork_context.outputs.terragrunt_command }}
additional_data: ${{ steps.gruntwork_context.outputs.additional_data }}
child_account_id: ${{ steps.gruntwork_context.outputs.child_account_id }}