Files
MokoCLI/templates/workflows/terraform/deploy.yml.template
T
Jonathan Miller fa0b5b7865 fix: update all workflow templates for Gitea Actions compatibility
- Add GA_TOKEN to token fallback chain across all 25 workflow templates
  (secrets.GA_TOKEN || secrets.GH_TOKEN || github.token)
- Replace hardcoded MokoStandards clone URLs with platform-detecting
  MOKO_CLONE_TOKEN/MOKO_CLONE_HOST env vars in 11 templates
- Replace actions/github-script@v7 with shell-based API calls in
  repo_health (Joomla + Dolibarr) and validate-joomla-project
- Replace hardcoded ApiClient('api.github.com') with PlatformAdapterFactory
  in health-check.yml and integration-tests.yml
- Add TODO markers for terraform github-script blocks (complex logic)
- Update publish-to-mokodolimods token references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:43:31 -05:00

211 lines
7.5 KiB
Plaintext

# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# This file is part of a Moko Consulting project.
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: MokoStandards.Terraform
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API
# PATH: /templates/workflows/terraform/deploy.yml.template
# VERSION: 04.06.00
# BRIEF: Terraform infrastructure deployment workflow for multiple environments
# NOTE: Applies Terraform configurations to provision and manage infrastructure
name: Terraform Deploy
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy'
required: true
type: choice
options:
- staging
- prod
action:
description: 'Terraform action'
required: true
type: choice
options:
- plan
- apply
- destroy
auto_approve:
description: 'Auto-approve apply/destroy (use with caution)'
required: false
type: boolean
default: false
permissions:
contents: read
pull-requests: write
id-token: write # Required for OIDC authentication
issues: write
env:
TF_VERSION: '1.7.0'
TF_WORKING_DIR: '.'
jobs:
terraform-deploy:
name: Terraform ${{ inputs.action }} - ${{ inputs.environment }}
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
# Configure cloud provider credentials
# Example for AWS:
- name: Configure AWS Credentials
if: ${{ vars.CLOUD_PROVIDER == 'aws' }}
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ vars.AWS_REGION || 'us-east-1' }}
# Example for Azure:
# - name: Azure Login
# if: ${{ vars.CLOUD_PROVIDER == 'azure' }}
# uses: azure/login@v1
# with:
# creds: ${{ secrets.AZURE_CREDENTIALS }}
# Example for GCP:
# - name: Authenticate to Google Cloud
# if: ${{ vars.CLOUD_PROVIDER == 'gcp' }}
# uses: google-github-actions/auth@v2
# with:
# workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
# service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
- name: Terraform Init
run: |
terraform init \
-backend-config="key=${{ inputs.environment }}/terraform.tfstate" \
-backend-config="bucket=${{ vars.TF_STATE_BUCKET }}" \
-backend-config="region=${{ vars.AWS_REGION || 'us-east-1' }}"
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Terraform Workspace
run: |
terraform workspace select ${{ inputs.environment }} || terraform workspace new ${{ inputs.environment }}
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Terraform Plan
id: plan
run: |
terraform plan \
-var-file="environments/${{ inputs.environment }}.tfvars" \
-out=tfplan \
-no-color
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Upload Plan
uses: actions/upload-artifact@v6.0.0
with:
name: tfplan-${{ inputs.environment }}-${{ github.run_number }}
path: ${{ env.TF_WORKING_DIR }}/tfplan
retention-days: 30
- name: Terraform Apply
if: inputs.action == 'apply' && (inputs.auto_approve || inputs.environment != 'prod')
id: apply
run: |
terraform apply -auto-approve tfplan
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Terraform Apply (Production - Manual Approval Required)
if: inputs.action == 'apply' && inputs.environment == 'prod' && !inputs.auto_approve
id: apply_prod
run: |
echo "Production deployment requires manual approval"
echo "Please review the plan and approve in GitHub environment settings"
terraform apply tfplan
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Terraform Destroy
if: inputs.action == 'destroy' && inputs.auto_approve
id: destroy
run: |
terraform destroy \
-var-file="environments/${{ inputs.environment }}.tfvars" \
-auto-approve
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Terraform Output
if: inputs.action == 'apply' && (steps.apply.outcome == 'success' || steps.apply_prod.outcome == 'success')
id: output
run: terraform output -json
working-directory: ${{ env.TF_WORKING_DIR }}
- name: Comment on Issue/PR
if: always()
uses: actions/github-script@v6 # TODO: Replace with curl for Gitea compatibility
with:
script: |
const fs = require('fs');
const action = '${{ inputs.action }}';
const env = '${{ inputs.environment }}';
const outcome = '${{ steps.apply.outcome || steps.destroy.outcome || steps.plan.outcome }}';
let body = `## Terraform ${action.toUpperCase()} - ${env}\n\n`;
body += `**Status:** ${outcome === 'success' ? '✅ Success' : '❌ Failed'}\n`;
body += `**Environment:** \`${env}\`\n`;
body += `**Action:** \`${action}\`\n`;
body += `**Triggered by:** @${{ github.actor }}\n\n`;
if (action === 'apply' && outcome === 'success') {
body += '### Infrastructure Updated Successfully\n\n';
try {
const outputs = '${{ steps.output.outputs.stdout }}';
body += '<details><summary>Terraform Outputs</summary>\n\n';
body += '```json\n' + outputs + '\n```\n\n';
body += '</details>\n';
} catch (e) {
body += '_Outputs not available_\n';
}
}
// Post to issue if triggered from issue
if (context.issue.number) {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
- name: Summary
if: always()
run: |
echo "### Terraform Deployment Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Environment:** ${{ inputs.environment }}" >> $GITHUB_STEP_SUMMARY
echo "- **Action:** ${{ inputs.action }}" >> $GITHUB_STEP_SUMMARY
echo "- **Status:** ${{ job.status }}" >> $GITHUB_STEP_SUMMARY
echo "- **Run Number:** ${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY