Major change - break #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Infrastructure CI/CD | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: 'Environment to deploy to' | |
| required: true | |
| type: choice | |
| options: | |
| - dev | |
| - staging | |
| - prod | |
| action: | |
| description: 'Action to perform' | |
| required: true | |
| type: choice | |
| options: | |
| - plan | |
| - apply | |
| - destroy | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'terraform/**' | |
| - 'k8s/**' | |
| - 'helm/**' | |
| - '.github/workflows/infrastructure.yml' | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - 'terraform/**' | |
| - 'k8s/**' | |
| - 'helm/**' | |
| env: | |
| AWS_REGION: us-west-2 | |
| TF_VERSION: 1.6.0 | |
| KUBECTL_VERSION: 1.28.0 | |
| HELM_VERSION: 3.13.0 | |
| jobs: | |
| terraform-plan: | |
| name: Terraform Plan | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'plan') | |
| strategy: | |
| matrix: | |
| environment: [dev, staging, prod] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-session-name: terraform-plan-${{ matrix.environment }} | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Setup OpenTofu (alternative) | |
| if: env.USE_OPENTOFU == 'true' | |
| run: | | |
| curl -fsSL https://get.opentofu.org/install-opentofu.sh | sudo sh | |
| sudo ln -sf /usr/local/bin/tofu /usr/local/bin/terraform | |
| - name: Terraform Format Check | |
| working-directory: terraform | |
| run: terraform fmt -check -recursive | |
| - name: Terraform Init | |
| working-directory: terraform | |
| run: | | |
| terraform init \ | |
| -backend-config="bucket=${{ secrets.TF_STATE_BUCKET }}" \ | |
| -backend-config="key=ffmpeg-api/${{ matrix.environment }}/terraform.tfstate" \ | |
| -backend-config="region=${{ env.AWS_REGION }}" \ | |
| -backend-config="dynamodb_table=${{ secrets.TF_LOCK_TABLE }}" | |
| - name: Terraform Validate | |
| working-directory: terraform | |
| run: terraform validate | |
| - name: Terraform Plan | |
| working-directory: terraform | |
| run: | | |
| terraform plan \ | |
| -var-file="environments/${{ matrix.environment }}.tfvars" \ | |
| -out="${{ matrix.environment }}.tfplan" \ | |
| -detailed-exitcode | |
| continue-on-error: true | |
| - name: Comment PR with Plan | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const plan = fs.readFileSync('terraform/${{ matrix.environment }}.tfplan.txt', 'utf8'); | |
| const output = ` | |
| ## Terraform Plan for ${{ matrix.environment }} | |
| \`\`\` | |
| ${plan} | |
| \`\`\` | |
| Plan: \`terraform plan -var-file="environments/${{ matrix.environment }}.tfvars"\` | |
| `; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: output | |
| }); | |
| - name: Upload plan artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-plan-${{ matrix.environment }} | |
| path: terraform/${{ matrix.environment }}.tfplan | |
| retention-days: 5 | |
| terraform-apply: | |
| name: Terraform Apply | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'apply') | |
| needs: [terraform-plan] | |
| strategy: | |
| matrix: | |
| environment: [dev] # Only auto-deploy to dev | |
| include: | |
| - environment: staging | |
| manual: true | |
| - environment: prod | |
| manual: true | |
| environment: | |
| name: ${{ matrix.environment }} | |
| url: https://api-${{ matrix.environment }}.ffmpeg.example.com | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-session-name: terraform-apply-${{ matrix.environment }} | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Download plan artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: terraform-plan-${{ matrix.environment }} | |
| path: terraform/ | |
| - name: Terraform Init | |
| working-directory: terraform | |
| run: | | |
| terraform init \ | |
| -backend-config="bucket=${{ secrets.TF_STATE_BUCKET }}" \ | |
| -backend-config="key=ffmpeg-api/${{ matrix.environment }}/terraform.tfstate" \ | |
| -backend-config="region=${{ env.AWS_REGION }}" \ | |
| -backend-config="dynamodb_table=${{ secrets.TF_LOCK_TABLE }}" | |
| - name: Terraform Apply | |
| working-directory: terraform | |
| run: terraform apply -auto-approve ${{ matrix.environment }}.tfplan | |
| - name: Get cluster credentials | |
| run: | | |
| aws eks update-kubeconfig --region ${{ env.AWS_REGION }} --name ffmpeg-api-${{ matrix.environment }} | |
| - name: Deploy Kubernetes manifests | |
| if: success() | |
| run: | | |
| # Apply namespace first | |
| kubectl apply -f k8s/base/namespace.yaml | |
| # Apply RBAC | |
| envsubst < k8s/base/rbac.yaml | kubectl apply -f - | |
| # Apply ConfigMaps and Secrets | |
| kubectl apply -f k8s/base/configmap.yaml | |
| kubectl apply -f k8s/base/secret.yaml | |
| # Apply services | |
| kubectl apply -f k8s/base/services.yaml | |
| # Apply deployments | |
| kubectl apply -f k8s/base/api-deployment.yaml | |
| kubectl apply -f k8s/base/worker-deployment.yaml | |
| # Apply HPA | |
| kubectl apply -f k8s/base/hpa.yaml | |
| # Apply ingress | |
| envsubst < k8s/base/ingress.yaml | kubectl apply -f - | |
| - name: Wait for deployment | |
| run: | | |
| kubectl rollout status deployment/ffmpeg-api -n ffmpeg-api --timeout=300s | |
| kubectl rollout status deployment/ffmpeg-worker -n ffmpeg-api --timeout=300s | |
| helm-deploy: | |
| name: Helm Deploy | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| needs: [terraform-apply] | |
| strategy: | |
| matrix: | |
| environment: [dev] | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Setup Helm | |
| uses: azure/setup-helm@v3 | |
| with: | |
| version: ${{ env.HELM_VERSION }} | |
| - name: Setup kubectl | |
| uses: azure/setup-kubectl@v3 | |
| with: | |
| version: ${{ env.KUBECTL_VERSION }} | |
| - name: Get cluster credentials | |
| run: | | |
| aws eks update-kubeconfig --region ${{ env.AWS_REGION }} --name ffmpeg-api-${{ matrix.environment }} | |
| - name: Add Helm repositories | |
| run: | | |
| helm repo add bitnami https://charts.bitnami.com/bitnami | |
| helm repo add prometheus-community https://prometheus-community.github.io/helm-charts | |
| helm repo add grafana https://grafana.github.io/helm-charts | |
| helm repo update | |
| - name: Deploy with Helm | |
| run: | | |
| helm upgrade --install ffmpeg-api ./helm/ffmpeg-api \ | |
| --namespace ffmpeg-api \ | |
| --create-namespace \ | |
| --values helm/ffmpeg-api/values-${{ matrix.environment }}.yaml \ | |
| --set image.tag=${{ github.sha }} \ | |
| --timeout 10m \ | |
| --wait | |
| - name: Test deployment | |
| run: | | |
| kubectl get pods -n ffmpeg-api | |
| kubectl get services -n ffmpeg-api | |
| kubectl get ingress -n ffmpeg-api | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: 'terraform/' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| - name: Upload Trivy scan results | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| - name: Run tfsec | |
| uses: aquasecurity/tfsec-action@v1.0.3 | |
| with: | |
| working_directory: terraform/ | |
| soft_fail: true | |
| cleanup: | |
| name: Cleanup Resources | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'destroy' | |
| environment: | |
| name: ${{ github.event.inputs.environment }}-destroy | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v3 | |
| with: | |
| terraform_version: ${{ env.TF_VERSION }} | |
| - name: Terraform Init | |
| working-directory: terraform | |
| run: | | |
| terraform init \ | |
| -backend-config="bucket=${{ secrets.TF_STATE_BUCKET }}" \ | |
| -backend-config="key=ffmpeg-api/${{ github.event.inputs.environment }}/terraform.tfstate" \ | |
| -backend-config="region=${{ env.AWS_REGION }}" \ | |
| -backend-config="dynamodb_table=${{ secrets.TF_LOCK_TABLE }}" | |
| - name: Terraform Destroy | |
| working-directory: terraform | |
| run: | | |
| terraform destroy -auto-approve \ | |
| -var-file="environments/${{ github.event.inputs.environment }}.tfvars" |