feat: add trivy scan to plan to staging #68
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: Plan PR updates on Staging env | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| jobs: | |
| plan-security: | |
| name: Terraform Plan (security) | |
| runs-on: ubuntu-latest | |
| environment: staging | |
| permissions: | |
| id-token: write # OIDC | |
| contents: read | |
| pull-requests: write | |
| env: | |
| TF_VAR_region: ${{ secrets.AWS_REGION }} | |
| TF_VAR_environment: staging | |
| TF_VAR_app_id: trip-planner-app | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: 1.12.2 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::387836084035:role/githubTripPlannerInfraManager | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Terraform Validate | |
| working-directory: terraform/layers/security | |
| run: | | |
| terraform init \ | |
| -input=false -upgrade \ | |
| -backend-config="bucket=trip-planner-states" \ | |
| -backend-config="key=security/staging/terraform.tfstate" \ | |
| -backend-config="region=eu-central-1" \ | |
| -backend-config="dynamodb_table=staging-trip-planner-terraform-locks" \ | |
| -backend-config="encrypt=true" | |
| terraform validate | |
| - name: Trivy IaC Scan | |
| uses: aquasecurity/trivy-action@0.20.0 | |
| with: | |
| scan-type: config | |
| scan-ref: terraform/layers/security | |
| severity: HIGH,CRITICAL | |
| exit-code: '1' | |
| - name: Terraform Plan (staging) | |
| working-directory: terraform/layers/security | |
| run: | | |
| terraform plan -out=tfplan -input=false | |
| terraform show -no-color tfplan > tfplan.txt | |
| - name: Upload plan as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-plan-staging-security | |
| path: terraform/layers/security/tfplan.txt | |
| plan-networking: | |
| name: Terraform Plan (networking) | |
| runs-on: ubuntu-latest | |
| environment: staging | |
| needs: plan-security | |
| permissions: | |
| id-token: write # OIDC | |
| contents: read | |
| pull-requests: write | |
| env: | |
| TF_VAR_region: ${{ secrets.AWS_REGION }} | |
| TF_VAR_environment: staging | |
| TF_VAR_azs: '["${{ secrets.AWS_REGION }}a", "${{ secrets.AWS_REGION }}b", "${{ secrets.AWS_REGION }}c"]' | |
| TF_VAR_vpc_cidr: 10.0.0.0/16 | |
| TF_VAR_public_subnets_ips: '["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]' | |
| TF_VAR_private_subnets_ips: '["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]' | |
| TF_VAR_app_id: trip-planner-app | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: 1.12.2 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::387836084035:role/githubTripPlannerInfraManager | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Terraform Validate | |
| working-directory: terraform/layers/networking | |
| run: | | |
| terraform init \ | |
| -input=false -upgrade \ | |
| -backend-config="bucket=trip-planner-states" \ | |
| -backend-config="key=networking/staging/terraform.tfstate" \ | |
| -backend-config="region=eu-central-1" \ | |
| -backend-config="dynamodb_table=staging-trip-planner-terraform-locks" \ | |
| -backend-config="encrypt=true" | |
| terraform validate | |
| - name: Trivy IaC Scan | |
| uses: aquasecurity/trivy-action@0.20.0 | |
| with: | |
| scan-type: config | |
| scan-ref: terraform/layers/networking | |
| severity: HIGH,CRITICAL | |
| exit-code: '1' | |
| - name: Terraform Plan (staging) | |
| working-directory: terraform/layers/networking | |
| run: | | |
| terraform plan -out=tfplan -input=false | |
| terraform show -no-color tfplan > tfplan.txt | |
| - name: Upload plan as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-plan-staging-networking | |
| path: terraform/layers/networking/tfplan.txt | |
| plan-database: | |
| name: Terraform Plan (database) | |
| runs-on: ubuntu-latest | |
| environment: staging | |
| needs: plan-networking | |
| permissions: | |
| id-token: write # OIDC | |
| contents: read | |
| pull-requests: write | |
| env: | |
| TF_VAR_region: ${{ secrets.AWS_REGION }} | |
| TF_VAR_environment: staging | |
| TF_VAR_app_id: trip-planner-app | |
| TF_VAR_notification_email: ${{secrets.ALERT_EMAIL}} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: 1.12.2 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::387836084035:role/githubTripPlannerInfraManager # Updtate this | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Terraform Validate | |
| working-directory: terraform/layers/database | |
| run: | | |
| terraform init \ | |
| -input=false -upgrade \ | |
| -backend-config="bucket=trip-planner-states" \ | |
| -backend-config="key=database/staging/terraform.tfstate" \ | |
| -backend-config="region=eu-central-1" \ | |
| -backend-config="dynamodb_table=staging-trip-planner-terraform-locks" \ | |
| -backend-config="encrypt=true" | |
| terraform validate | |
| - name: Trivy IaC Scan | |
| uses: aquasecurity/trivy-action@0.20.0 | |
| with: | |
| scan-type: config | |
| scan-ref: terraform/layers/database | |
| severity: HIGH,CRITICAL | |
| exit-code: '1' | |
| - name: Terraform Plan (staging) | |
| working-directory: terraform/layers/database | |
| run: | | |
| terraform plan -out=tfplan -input=false | |
| terraform show -no-color tfplan > tfplan.txt | |
| - name: Upload plan as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-plan-staging-database | |
| path: terraform/layers/database/tfplan.txt | |
| plan-backend: | |
| name: Terraform Plan (backend) | |
| runs-on: ubuntu-latest | |
| environment: staging | |
| needs: plan-database | |
| permissions: | |
| id-token: write # OIDC | |
| contents: read | |
| pull-requests: write | |
| env: | |
| TF_VAR_region: ${{ secrets.AWS_REGION }} | |
| TF_VAR_environment: staging | |
| TF_VAR_app_id: trip-planner-app | |
| TF_VAR_alb_domain_name: staging-alb.epic-trip-planner.com | |
| TF_VAR_hosted_zone_id: ${{secrets.HOSTED_ZONE_ID}} | |
| TF_VAR_route53_zone_name: epic-trip-planner.com | |
| TF_VAR_container_image: lrasata/trip-planner-backend-app:1.1.0 | |
| TF_VAR_allowed_origins: https://staging.epic-trip-planner.com | |
| TF_VAR_notification_email: ${{secrets.ALERT_EMAIL}} | |
| TF_VAR_api_file_upload_domain_name: staging-api-file-upload.epic-trip-planner.com | |
| TF_VAR_backend_certificate_arn: ${{secrets.BACKEND_CERTIFICATE_ARN}} | |
| TF_VAR_use_bucketav: false | |
| TF_VAR_bucketav_sns_findings_topic_name: "" | |
| TF_VAR_uploads_bucket_name: file-uploads-bucket | |
| TF_VAR_enable_transfer_acceleration: true | |
| TF_VAR_secret_store_name: ${{secrets.SECRET_STORE_NAME}} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: 1.12.2 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::387836084035:role/githubTripPlannerInfraManager | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Terraform Validate | |
| working-directory: terraform/layers/backend | |
| run: | | |
| terraform init \ | |
| -input=false -upgrade \ | |
| -backend-config="bucket=trip-planner-states" \ | |
| -backend-config="key=backend/staging/terraform.tfstate" \ | |
| -backend-config="region=eu-central-1" \ | |
| -backend-config="dynamodb_table=staging-trip-planner-terraform-locks" \ | |
| -backend-config="encrypt=true" | |
| terraform validate | |
| - name: Trivy IaC Scan | |
| uses: aquasecurity/trivy-action@0.20.0 | |
| with: | |
| scan-type: config | |
| scan-ref: terraform/layers/backend | |
| severity: HIGH,CRITICAL | |
| exit-code: '1' | |
| - name: Terraform Plan (staging) | |
| working-directory: terraform/layers/backend | |
| run: | | |
| terraform plan -out=tfplan -input=false | |
| terraform show -no-color tfplan > tfplan.txt | |
| - name: Upload plan as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-plan-staging-backend | |
| path: terraform/layers/backend/tfplan.txt | |
| plan-frontend: | |
| name: Terraform Plan (frontend) | |
| runs-on: ubuntu-latest | |
| environment: staging | |
| needs: plan-security | |
| permissions: | |
| id-token: write # OIDC | |
| contents: read | |
| pull-requests: write | |
| env: | |
| TF_VAR_region: ${{ secrets.AWS_REGION }} | |
| TF_VAR_environment: staging | |
| TF_VAR_app_id: trip-planner-app | |
| TF_VAR_cloudfront_domain_name: staging.epic-trip-planner.com | |
| TF_VAR_cloudfront_certificate_arn: ${{secrets.CLOUDFRONT_CERTIFICATE_ARN}} | |
| TF_VAR_backend_certificate_arn: ${{secrets.BACKEND_CERTIFICATE_ARN}} | |
| TF_VAR_static_web_app_bucket_name: trip-planner-static-webapp-bucket | |
| TF_VAR_api_file_upload_domain_name: staging-api-file-upload.epic-trip-planner.com | |
| TF_VAR_api_locations_domain_name: staging-api-locations.epic-trip-planner.com | |
| TF_VAR_API_CITIES_GEO_DB_URL: ${{secrets.API_CITIES_GEO_DB_URL}} | |
| TF_VAR_GEO_DB_RAPID_API_HOST: ${{secrets.GEO_DB_RAPID_API_HOST}} | |
| TF_VAR_API_COUNTRIES_GEO_DB_URL: ${{secrets.API_COUNTRIES_GEO_DB_URL}} | |
| TF_VAR_notification_email: ${{secrets.ALERT_EMAIL}} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: 1.12.2 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::387836084035:role/githubTripPlannerInfraManager | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Terraform Validate | |
| working-directory: terraform/layers/frontend | |
| run: | | |
| terraform init \ | |
| -input=false -upgrade \ | |
| -backend-config="bucket=trip-planner-states" \ | |
| -backend-config="key=frontend/staging/terraform.tfstate" \ | |
| -backend-config="region=eu-central-1" \ | |
| -backend-config="dynamodb_table=staging-trip-planner-terraform-locks" \ | |
| -backend-config="encrypt=true" | |
| terraform validate | |
| - name: Trivy IaC Scan | |
| uses: aquasecurity/trivy-action@0.20.0 | |
| with: | |
| scan-type: config | |
| scan-ref: terraform/layers/frontend | |
| severity: HIGH,CRITICAL | |
| exit-code: '1' | |
| - name: Terraform Plan (staging) | |
| working-directory: terraform/layers/frontend | |
| run: | | |
| terraform plan -out=tfplan -input=false | |
| terraform show -no-color tfplan > tfplan.txt | |
| - name: Upload plan as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-plan-staging-frontend | |
| path: terraform/layers/frontend/tfplan.txt | |
| combine-and-comment: | |
| name: Combine Plans and Comment | |
| runs-on: ubuntu-latest | |
| needs: [plan-security, plan-networking, plan-database, plan-backend, plan-frontend] # Wait for all sequential jobs | |
| if: github.event_name == 'pull_request' | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - name: Download all plan artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: plans/ # Download to plans/ directory | |
| - name: Combine plans and post comment | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const plansDir = 'plans'; | |
| let combinedBody = '### Terraform Plan (staging - All Layers)\n\n'; | |
| const layers = ['security', 'networking', 'database', 'backend', 'frontend']; | |
| for (const layer of layers) { | |
| const planPath = path.join(plansDir, `terraform-plan-staging-${layer}`, 'tfplan.txt'); | |
| if (fs.existsSync(planPath)) { | |
| const body = fs.readFileSync(planPath, 'utf8'); | |
| const MAX_LEN = 15000; // Shorter per layer to fit combined | |
| const planPreview = body.length > MAX_LEN ? body.slice(0, MAX_LEN - 1000) + '\n\n...(truncated)' : body; | |
| combinedBody += `#### ${layer}\n<details>\n<summary>Click to expand</summary>\n\n\`\`\`\n${planPreview}\n\`\`\`\n\n</details>\n\n`; | |
| } | |
| } | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: combinedBody | |
| }); |