Skip to content

feat: Added inputs for tf-init step #2

feat: Added inputs for tf-init step

feat: Added inputs for tf-init step #2

---
run-name: 'Terraform workflow'
on:
workflow_call:
inputs:
working_directory:
required: true
type: string
description: 'Root directory of the terraform where all resources exist.'
provider:
required: true
type: string
description: 'Cloud provider to run the workflow. e.g. azurerm, aws, gcp or digitalocean'
aws_region:
required: false
type: string
default: us-east-2
description: 'AWS region of terraform deployment.'
gcp_region:
required: false
type: string
description: 'GCP region of terraform deployment.'
var_file:
required: false
type: string
description: 'Terraform var file directory. e.g. vars/dev.tfvars'
destroy:
required: false
type: boolean
default: false
description: 'Set true to to destroy terraform infrastructure.'
approvers:
required: false
type: string
description: 'Approvals list to approve apply or destroy'
terraform_version:
type: string
default: 1.3.6
description: 'Required erraform version '
timeout:
required: false
type: number
default: 10
description: 'Timeout for approval step'
minimum-approvals:
required: false
type: string
default: 1
description: 'Minimum approvals required to accept the plan'
token_format:
required: false
type: string
default: access_token
description: 'Output format for the generated authentication token. For OAuth 2.0 access tokens, specify "access_token". For OIDC tokens, specify "id_token". To skip token generation, leave this value empty'
access_token_lifetime:
required: false
type: string
default: 300s
description: 'Desired lifetime duration of the access token, in seconds'
project_id:
required: false
type: string
description: 'ID of the default project to use for future API calls and invocations.'
create_credentials_file:
required: false
type: string
default: true
description: 'If true, the action will securely generate a credentials file which can be used for authentication via gcloud and Google Cloud SDKs.'
backend_bucket_name:
required: false
type: string
errored_tfstate_path:
required: false
type: string
secrets:
AZURE_CREDENTIALS:
required: false
description: 'Azure Credentials to install Azure in github runner.'
AWS_ACCESS_KEY_ID:
required: false
description: 'AWS Access Key ID to install AWS CLI.'
BUILD_ROLE:
required: false
description: 'AWS OIDC role for aws authentication.'
AWS_SECRET_ACCESS_KEY:
required: false
description: 'AWS Secret access key to install AWS CLI'
AWS_SESSION_TOKEN:
required: false
description: 'AWS Session Token to install AWS CLI'
GCP_CREDENTIALS:
required: false
description: 'The Google Cloud JSON service account key to use for authentication'
DIGITALOCEAN_ACCESS_TOKEN:
required: false
description: 'The DigitalOcean Personal Access Token for Application & API'
env-vars:
required: false
description: 'Pass required environment variables'
WORKLOAD_IDENTITY_PROVIDER:
required: false
description: 'The full identifier of the Workload Identity Provider'
SERVICE_ACCOUNT:
required: false
description: 'The service account to be used'
jobs:
terraform-workflow:

Check failure on line 108 in .github/workflows/terraform_workflow.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/terraform_workflow.yml

Invalid workflow file

You have an error in your yaml syntax on line 108
runs-on: ubuntu-latest
outputs:
tfplanExitCode: ${{ steps.tf-plan.outputs.exitcode }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set environment variables
run: |
(
cat <<'_EOT'
${{ secrets.env-vars }}
_EOT
) >> "$GITHUB_ENV"
- name: Install AWS CLI
if: ${{ inputs.provider == 'aws' }}
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }}
role-to-assume: ${{ secrets.BUILD_ROLE }}
aws-region: ${{ inputs.aws_region }}
role-duration-seconds: 900
role-skip-session-tagging: true
- name: Install Azure CLI
if: ${{ inputs.provider == 'azurerm' }}
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Authenticate to Google Cloud'
if: ${{ inputs.provider == 'gcp' }}
uses: 'google-github-actions/auth@v2'
with:
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
create_credentials_file: ${{ inputs.create_credentials_file }}
token_format: ${{ inputs.token_format }}
workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.SERVICE_ACCOUNT }}
access_token_lifetime: ${{ inputs.access_token_lifetime }}
project_id: ${{ inputs.project_id }}
- name: Install doctl
if: ${{ inputs.provider == 'digitalocean' }}
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- name: Set up Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ inputs.terraform_version }}
- name: 'Terraform Format'
if: ${{ inputs.destroy != true }}
id: fmt
uses: 'dflook/terraform-fmt-check@v1'
with:
actions_subcommand: 'fmt'
path: ${{ inputs.working_directory }}
- name: terraform init
run: |
cd ${{ inputs.working_directory }}
terraform init
- name: 'Terraform validate'
if: ${{ inputs.destroy != true }}
id: validate
uses: dflook/terraform-validate@v1
with:
path: ${{ inputs.working_directory }}
- name: Terraform Plan
id: tf-plan
run: |
export exitcode=0
cd ${{ inputs.working_directory }}
if [ "${{ inputs.destroy }}" = true ]; then
if [ -n "${{ inputs.var_file }}" ]; then
terraform plan -destroy -out tfplan --var-file=${{ inputs.var_file }}
else
terraform plan -destroy -out tfplan
fi
else
if [ -n "${{ inputs.var_file }}" ]; then
terraform plan -out tfplan --var-file=${{ inputs.var_file }}
else
terraform plan -out tfplan
fi
fi
- name: Publish Terraform Plan
uses: actions/upload-artifact@v4
with:
name: tfplan
path: ${{ inputs.working_directory }}/tfplan
- name: Create String Output
id: tf-plan-string
run: |
cd ${{ inputs.working_directory }}
TERRAFORM_PLAN=$(terraform show -no-color tfplan)
delimiter="$(openssl rand -hex 8)"
echo "summary<<${delimiter}" >> $GITHUB_OUTPUT
echo "## Terraform Plan Output" >> $GITHUB_OUTPUT
echo "<details><summary>Click to expand</summary>" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo '```terraform' >> $GITHUB_OUTPUT
echo "$TERRAFORM_PLAN" >> $GITHUB_OUTPUT
echo '```' >> $GITHUB_OUTPUT
echo "</details>" >> $GITHUB_OUTPUT
echo "${delimiter}" >> $GITHUB_OUTPUT
- name: "Accept plan or deny"
uses: trstringer/manual-approval@v1
timeout-minutes: ${{ inputs.timeout }}
with:
secret: ${{ github.TOKEN }}
approvers: ${{ inputs.approvers }}
minimum-approvals: ${{ inputs.minimum-approvals }}
issue-title: "Terraform Plan for Infrastructure Update"
# - name: terraform apply
# if: ${{ inputs.destroy != true }}
# run: |
# if [ -n "${{ inputs.var_file }}" ]; then
# cd ${{ inputs.working_directory }}
# terraform apply -var-file="${{ inputs.var_file }}" -auto-approve
# else
# cd ${{ inputs.working_directory }}
# terraform apply -auto-approve
# fi
- name: terraform apply
if: ${{ inputs.destroy != true }}
run: |
cd ${{ inputs.working_directory }}
if [ -f "errored.tfstate" ]; then
echo "Found errored.tfstate, attempting state recovery..."
terraform state push errored.tfstate
# Optionally move or manage the errored.tfstate file
mv errored.tfstate /path/to/backup/location
fi
if [ -n "${{ inputs.var_file }}" ]; then
terraform apply -var-file="${{ inputs.var_file }}" -auto-approve || {
if [ -f "errored.tfstate" ]; then
echo "Copying errored.tfstate to S3..."
aws s3 cp errored.tfstate s3://${{ inputs.backend_s3_bucket }}/${{ inputs.backend_s3_key }}/errored.tfstate
fi
exit 1
}
else
terraform apply -auto-approve || {
if [ -f "errored.tfstate" ]; then
echo "Copying errored.tfstate to S3..."
aws s3 cp errored.tfstate s3://${{ inputs.backend_s3_bucket }}/${{ inputs.backend_s3_key }}/errored.tfstate
fi
exit 1
}
}
- name: Terraform destroy
if: ${{ inputs.destroy == true }}
id: destroy
run: |
if [ -n "${{ inputs.var_file }}" ]; then
cd ${{ inputs.working_directory }}
terraform destroy -var-file="${{ inputs.var_file }}" -auto-approve
else
cd ${{ inputs.working_directory }}
terraform destroy -auto-approve
fi
...