GitHub Actions
Integrate Cloud Cost Analyzer into your GitHub Actions workflows.
Quick Start (Recommended)
Use the official GitHub Action for the simplest setup:
# .github/workflows/cost-analysis.yml
name: Cost Analysis
on:
pull_request:
branches: [main]
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- uses: dragonfractal/cca-scan-action@v1
with:
api-key: ${{ secrets.CCA_API_KEY }}
That's it — 3 steps. The action runs CCA (via its container image), scans your account, and posts results as a PR comment.
Scanning Azure
Set provider: azure and give the job Azure credentials — the action forwards the
standard AZURE_* variables into the scan container. Two options:
OIDC (recommended, no stored secret) — azure/login provides a federated token
that the action mounts into the container:
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: dragonfractal/cca-scan-action@v1
with:
api-key: ${{ secrets.CCA_API_KEY }}
provider: azure
Service principal secret — pass the credentials as env on the action step:
- uses: dragonfractal/cca-scan-action@v1
env:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
with:
api-key: ${{ secrets.CCA_API_KEY }}
provider: azure
The scan needs only the Reader role (plus Cost Management Reader for cost data) on the subscription.
Action Inputs
| Input | Required | Default | Description |
|---|---|---|---|
api-key | Yes | — | CCA API key (get one here) |
provider | No | aws | Cloud provider (aws, azure) |
regions | No | — | Comma-separated regions (e.g. us-east-1,us-west-2) |
version | No | latest | CCA Docker image version |
output-file | No | cca-scan-results.json | Path to save the JSON scan results |
comment-on-pr | No | true | Post summary as PR comment |
fail-on-findings | No | 0 | Fail if findings exceed threshold (0 = never) |
Action Outputs
| Output | Description |
|---|---|
findings-count | Number of findings detected |
total-savings | Total potential monthly savings (USD) |
Required Secrets
Add these in Settings > Secrets and variables > Actions:
| Secret | Description |
|---|---|
CCA_API_KEY | CCA API key (sign up here) |
AWS_ROLE_ARN | IAM role ARN for OIDC authentication (recommended) |
Or use static credentials:
| Secret | Description |
|---|---|
AWS_ACCESS_KEY_ID | AWS access key |
AWS_SECRET_ACCESS_KEY | AWS secret key |
For Azure (see Scanning Azure above):
| Secret | Description |
|---|---|
AZURE_CLIENT_ID | Service principal client ID |
AZURE_TENANT_ID | Azure AD tenant ID |
AZURE_SUBSCRIPTION_ID | Subscription to scan |
AZURE_CLIENT_SECRET | Service principal secret (only for the non-OIDC path) |
Use Cases
Weekly Scheduled Scan
name: Weekly Cost Scan
on:
schedule:
- cron: '0 9 * * 1' # Monday 9am UTC
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- uses: dragonfractal/cca-scan-action@v1
with:
api-key: ${{ secrets.CCA_API_KEY }}
comment-on-pr: 'false'
PR Cost Impact Check
name: Cost Impact Check
on:
pull_request:
branches: [main]
paths:
- 'terraform/**'
- 'infrastructure/**'
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
cost-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- uses: dragonfractal/cca-scan-action@v1
with:
api-key: ${{ secrets.CCA_API_KEY }}
comment-on-pr: 'true'
Upload findings to code scanning (SARIF)
Emit SARIF and upload it so findings show up in the repo's Security > Code
scanning tab. Note the security-events: write permission, required to upload.
name: Cost Findings (Code Scanning)
on:
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
permissions:
id-token: write
contents: read
security-events: write # required to upload SARIF
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Install CCA
run: curl -sSL https://releases.dragonfractal.com/install.sh | sh
- name: Scan to SARIF
env:
CCA_API_KEY: ${{ secrets.CCA_API_KEY }}
run: cca scan --provider aws --output sarif --output-file cca.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: cca.sarif
Multi-Region Scan
name: Multi-Region Scan
on:
schedule:
- cron: '0 6 * * *'
permissions:
id-token: write
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- uses: dragonfractal/cca-scan-action@v1
with:
api-key: ${{ secrets.CCA_API_KEY }}
regions: us-east-1,us-west-2,eu-west-1
comment-on-pr: 'false'
Fail on Too Many Findings
- uses: dragonfractal/cca-scan-action@v1
with:
api-key: ${{ secrets.CCA_API_KEY }}
fail-on-findings: '20' # Fail if more than 20 findings
Use Outputs in Subsequent Steps
- uses: dragonfractal/cca-scan-action@v1
id: cca
with:
api-key: ${{ secrets.CCA_API_KEY }}
- name: Check results
run: |
echo "Found ${{ steps.cca.outputs.findings-count }} findings"
echo "Potential savings: $${{ steps.cca.outputs.total-savings }}/mo"
Alternative: Docker Image
If you prefer to run CCA directly without the action:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
- name: Run CCA
run: |
docker run --rm \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
dragonfractal/cca:latest \
scan --api-key ${{ secrets.CCA_API_KEY }} -r us-east-1
Alternative: Install Script
- name: Install CCA
run: curl -sSL https://releases.dragonfractal.com/install.sh | sh
- name: Scan
env:
CCA_API_KEY: ${{ secrets.CCA_API_KEY }}
run: cca scan -r us-east-1
Next Steps
- GitLab CI — GitLab CI/CD integration
- Jenkins — Jenkins pipeline integration
- Generic CI — Any CI platform