Add Terraform CI/CD pipeline
This commit is contained in:
parent
345f67374c
commit
c057781ad6
248
.gitea/workflows/terraform.yml
Normal file
248
.gitea/workflows/terraform.yml
Normal file
@ -0,0 +1,248 @@
|
||||
name: Terraform CI/CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
action:
|
||||
description: 'Action to perform'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- plan
|
||||
- apply
|
||||
- destroy
|
||||
|
||||
env:
|
||||
TF_VERSION: "1.9.0"
|
||||
WORKING_DIR: "./terraform" # Adjust to your terraform directory
|
||||
|
||||
jobs:
|
||||
# Stage 1: Linting and Syntax Checks
|
||||
lint-and-validate:
|
||||
name: Lint and Validate
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: https://github.com/hashicorp/setup-terraform@v3
|
||||
with:
|
||||
terraform_version: ${{ env.TF_VERSION }}
|
||||
|
||||
- name: Terraform Format Check
|
||||
id: fmt
|
||||
run: terraform fmt -check -recursive
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Terraform Init (for validation)
|
||||
run: terraform init -backend=false
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Terraform Validate
|
||||
run: terraform validate
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Check Format Result
|
||||
if: steps.fmt.outcome == 'failure'
|
||||
run: |
|
||||
echo "❌ Terraform formatting check failed. Run 'terraform fmt -recursive' to fix."
|
||||
exit 1
|
||||
|
||||
# Stage 2: Security Scanning
|
||||
security-scan:
|
||||
name: Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint-and-validate
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Checkov (Open Source Security Scanner)
|
||||
uses: https://github.com/bridgecrewio/checkov-action@v12
|
||||
with:
|
||||
directory: ${{ env.WORKING_DIR }}
|
||||
framework: terraform
|
||||
soft_fail: false # Set to true to not fail the pipeline on security issues
|
||||
output_format: cli
|
||||
|
||||
- name: Run tfsec (Terraform Security Scanner)
|
||||
uses: https://github.com/aquasecurity/tfsec-action@v1.0.3
|
||||
with:
|
||||
working_directory: ${{ env.WORKING_DIR }}
|
||||
soft_fail: false
|
||||
|
||||
# Stage 3: Terraform Init and Plan
|
||||
plan:
|
||||
name: Terraform Plan
|
||||
runs-on: ubuntu-latest
|
||||
needs: security-scan
|
||||
if: github.event_name == 'push' || github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && (github.event.inputs.action == 'plan' || github.event.inputs.action == 'apply'))
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: https://github.com/hashicorp/setup-terraform@v3
|
||||
with:
|
||||
terraform_version: ${{ env.TF_VERSION }}
|
||||
terraform_wrapper: false
|
||||
|
||||
- name: Configure Terraform Credentials
|
||||
run: |
|
||||
# Add your cloud provider credentials here
|
||||
# Example for AWS:
|
||||
# echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
|
||||
# echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
|
||||
|
||||
# Example for Azure:
|
||||
# echo "ARM_CLIENT_ID=${{ secrets.ARM_CLIENT_ID }}" >> $GITHUB_ENV
|
||||
# echo "ARM_CLIENT_SECRET=${{ secrets.ARM_CLIENT_SECRET }}" >> $GITHUB_ENV
|
||||
# echo "ARM_SUBSCRIPTION_ID=${{ secrets.ARM_SUBSCRIPTION_ID }}" >> $GITHUB_ENV
|
||||
# echo "ARM_TENANT_ID=${{ secrets.ARM_TENANT_ID }}" >> $GITHUB_ENV
|
||||
|
||||
# For GCP, you might need to create a credentials file
|
||||
echo "Configure your provider credentials here"
|
||||
|
||||
- name: Terraform Init
|
||||
run: terraform init
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
env:
|
||||
# Add backend configuration secrets if needed
|
||||
TF_CLI_ARGS_init: "-backend-config=access_key=${{ secrets.BACKEND_ACCESS_KEY }}"
|
||||
|
||||
- name: Terraform Plan
|
||||
run: terraform plan -out=tfplan.binary
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Convert Plan to JSON
|
||||
run: terraform show -json tfplan.binary > tfplan.json
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Upload Terraform Plan
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: terraform-plan
|
||||
path: |
|
||||
${{ env.WORKING_DIR }}/tfplan.binary
|
||||
${{ env.WORKING_DIR }}/tfplan.json
|
||||
${{ env.WORKING_DIR }}/.terraform/
|
||||
${{ env.WORKING_DIR }}/.terraform.lock.hcl
|
||||
retention-days: 30
|
||||
|
||||
- name: Comment Plan on PR
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const plan = fs.readFileSync('${{ env.WORKING_DIR }}/tfplan.json', 'utf8');
|
||||
const output = `#### Terraform Plan 📖
|
||||
|
||||
<details><summary>Show Plan</summary>
|
||||
|
||||
\`\`\`json
|
||||
${plan}
|
||||
\`\`\`
|
||||
|
||||
</details>`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: output
|
||||
});
|
||||
|
||||
# Stage 4: Terraform Apply
|
||||
apply:
|
||||
name: Terraform Apply
|
||||
runs-on: ubuntu-latest
|
||||
needs: plan
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'apply')
|
||||
environment:
|
||||
name: production
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: https://github.com/hashicorp/setup-terraform@v3
|
||||
with:
|
||||
terraform_version: ${{ env.TF_VERSION }}
|
||||
terraform_wrapper: false
|
||||
|
||||
- name: Download Terraform Plan
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: terraform-plan
|
||||
path: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Configure Terraform Credentials
|
||||
run: |
|
||||
# Same credentials configuration as in plan stage
|
||||
echo "Configure your provider credentials here"
|
||||
|
||||
- name: Restore Terraform Init Files
|
||||
run: |
|
||||
# The .terraform directory is already restored from artifacts
|
||||
echo "Terraform initialization files restored"
|
||||
|
||||
- name: Terraform Apply
|
||||
run: terraform apply -auto-approve tfplan.binary
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Output Terraform Outputs
|
||||
run: terraform output -json > terraform-outputs.json
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Upload Terraform Outputs
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: terraform-outputs
|
||||
path: ${{ env.WORKING_DIR }}/terraform-outputs.json
|
||||
retention-days: 90
|
||||
|
||||
# Stage 5: Terraform Destroy (Manual/Authorized Only)
|
||||
destroy:
|
||||
name: Terraform Destroy
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'destroy'
|
||||
environment:
|
||||
name: production-destroy # Requires manual approval in repository settings
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Terraform
|
||||
uses: https://github.com/hashicorp/setup-terraform@v3
|
||||
with:
|
||||
terraform_version: ${{ env.TF_VERSION }}
|
||||
terraform_wrapper: false
|
||||
|
||||
- name: Configure Terraform Credentials
|
||||
run: |
|
||||
# Same credentials configuration as previous stages
|
||||
echo "Configure your provider credentials here"
|
||||
|
||||
- name: Terraform Init
|
||||
run: terraform init
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Terraform Destroy
|
||||
run: terraform destroy -auto-approve
|
||||
working-directory: ${{ env.WORKING_DIR }}
|
||||
|
||||
- name: Notify Destroy Completion
|
||||
run: |
|
||||
echo "🔥 Terraform infrastructure has been destroyed!"
|
||||
echo "Destroyed by: ${{ github.actor }}"
|
||||
echo "Timestamp: $(date -u)"
|
||||
Loading…
x
Reference in New Issue
Block a user