CI/CD Integration¶
Gate infrastructure changes at the pull request. Every flag, every policy violation, every cost spike: caught before it merges.
GitHub Actions¶
Recommended
The reference implementation uses actions/cache@v4 for Go module caching and github/codeql-action/upload-sarif@v3 for Security tab integration.
name: CloudSlash Scan
on:
pull_request:
branches: [main]
paths:
- '**.tf'
- '**.tfvars'
- '**cloudslash*.yaml'
permissions:
contents: read
pull-requests: write
security-events: write
jobs:
scan:
name: Infrastructure Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: go-${{ runner.os }}-${{ hashFiles('go.sum') }}
restore-keys: go-${{ runner.os }}-
- name: Build CloudSlash
run: go build -o cloudslash ./cmd/cloudslash-cli
- name: Run Scan
run: |
./cs scan --format=github-pr --fail-on=critical --region=${{ vars.AWS_REGION || 'us-east-1' }} \
> scan-report.md
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: SARIF Upload
if: always()
run: |
./cs scan --format=sarif --output=results.sarif --fail-on=none
- name: Upload to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: cloudslash
- name: Post PR Comment
if: always()
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
body-path: scan-report.md
SARIF Category
The category: cloudslash parameter groups all CloudSlash findings under a single Security tab section, preventing collision with other SARIF producers (CodeQL, Semgrep).
Terraform Plan¶
Diff Scanning
The --plan flag enables true shift-left scanning. Instead of analyzing the full cloud account state, the engine evaluates only the resources being created, modified, or destroyed by the proposed Terraform change.
# Generate a plan file
terraform plan -out=tfplan.out
# Convert to JSON
terraform show -json tfplan.out > tfplan.json
# Scan only the resources being changed
cs scan --plan=tfplan.json --format=sarif --output=results.sarif --fail-on=critical
The plan parser extracts resource_changes[] from the JSON structure and constructs a targeted graph. Resources being destroyed are automatically flagged with a risk score of 60 and the terraform_destroy waste reason.
GitHub Actions¶
With Plan Scanning
- name: Terraform Plan
run: |
terraform init
terraform plan -out=tfplan.out
terraform show -json tfplan.out > tfplan.json
- name: Scan Plan Diff
run: |
./cs scan --plan=tfplan.json --format=sarif --output=results.sarif --fail-on=critical
Shift-Left IaC Analysis¶
Credential-Free CI Environments
For pull requests where cloud provider credentials are intentionally omitted, CloudSlash evaluates Terraform plan diffs directly via --plan=tfplan.json. This provides 100% deterministic policy verification before merge without granting CI runners any cloud IAM roles.
terraform show -json tfplan.binary > tfplan.json
cloudslash scan --plan=tfplan.json --fail-on=critical
GitLab CI¶
cloudslash-scan:
stage: test
image: golang:1.23
script:
- go build -o cloudslash ./cmd/cloudslash-cli
- ./cs scan --format=json --fail-on=warning --timeout=5m --region eu-west-1
variables:
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
allow_failure: false
artifacts:
reports:
sast: results.sarif
Azure DevOps¶
steps:
- task: GoTool@0
inputs:
version: '1.23'
- script: |
go build -o cloudslash ./cmd/cloudslash-cli
./cs scan --format=sarif --output=$(Build.ArtifactStagingDirectory)/results.sarif --region eastus
displayName: 'CloudSlash Scan'
env:
AZURE_CLIENT_ID: $(AZURE_CLIENT_ID)
AZURE_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
AZURE_TENANT_ID: $(AZURE_TENANT_ID)
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: '$(Build.ArtifactStagingDirectory)/results.sarif'
artifactName: 'CodeAnalysisLogs'