A Docker image for validating IaC files with support for AWS CloudFormation and Terraform.
2.9K
๐ Comprehensive DevOps Security Scanner
A comprehensive Docker-based security scanner for your infrastructure code with intelligent error handling and helpful command suggestions. This scanner supports multiple formats including Terraform, CloudFormation, Docker images, Azure ARM/Bicep templates, and GCP Deployment Manager configurations. It uses industry-standard tools like TFLint, TFSec, Checkov, Trivy, and more to ensure your infrastructure is secure and compliant.
โ
One simple command structure for all scan types
โ
Comprehensive LOG format with full terminal output capture
โ
Intelligent error handling with helpful command suggestions
โ
Cross-platform Docker commands with clear examples
โ
Lightweight Alpine-based image for faster performance and smaller footprint
Simple usage with Docker:
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
The DevOps Universal Scanner is built on Alpine Linux to provide a lightweight, fast, and efficient container:
spd109/devops-uat:20250529)The new multi-stage optimized image provides significant improvements over previous versions:
| Metric | Original Version | Optimized Version (Current) | Improvement |
|---|---|---|---|
| Image Size | ~1.58GB | ~1.02GB | 35.4% smaller |
| Pull Time | ~3-4 minutes | ~2-3 minutes | 33% faster |
| Build Time | ~2.5 minutes | ~1.1 minutes | 56% faster |
| Python Layer | 542MB | 196MB | 63.8% smaller |
| Base Layer | 180MB | 134MB | 25.6% smaller |
| ARM-TTK | 16MB | 8.6MB | 46% smaller |
The optimized image uses a multi-stage build approach:
๐ง Builder Stage: Compiles tools and installs Python packages with build dependencies
๐ Runtime Stage: Only includes runtime dependencies and compiled binaries
๐ฆ Virtual Environment: Isolated Python packages for better dependency management
๐งน Cleanup: Removes .git directories and unnecessary files
Key Size Reductions:
Why Multi-Stage Builds?
| Category | Tools |
|---|---|
| Terraform | Terraform CLI, TFLint, TFSec, Checkov |
| AWS | CFN-Lint, Checkov |
| Azure | Bicep CLI, ARM-TTK, Checkov |
| GCP | Google Cloud Libraries, Checkov |
| Container | Trivy (vulnerabilities, secrets, misconfigurations) |
All commands generate detailed .log files with full terminal output:
| Command | Purpose | Tools Used |
|---|---|---|
scan-terraform | Terraform configurations | TFLint, TFSec, Checkov |
scan-cloudformation | CloudFormation templates | CFN-Lint, Checkov |
scan-docker | Container images | Trivy (vulnerabilities, secrets, misconfigurations) |
scan-arm | Azure ARM templates | ARM-TTK, Checkov |
scan-bicep | Azure Bicep templates | Bicep CLI, Checkov |
scan-gcp | GCP Deployment Manager | Checkov, GCloud validation |
# Pull the Docker image
docker pull spd109/devops-uat:latest
๐ฏ Basic Commands:
# Windows (PowerShell)
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-terraform terraform/
# Windows (Command Prompt)
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-terraform terraform/
# Linux/macOS
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
Example Commands:
# Terraform configurations
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
# CloudFormation templates
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-cloudformation template.yaml
# Container images for vulnerabilities
docker run -it --rm spd109/devops-uat:latest scan-docker nginx:latest
# Azure ARM templates
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-arm template.json
# Azure Bicep templates
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-bicep template.bicep
# GCP templates
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-gcp template.yaml
PowerShell:
# Current directory
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-terraform ./terraform/
# Full path to directory
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-terraform ./infrastructure/terraform/
# Specific file with explicit path
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-cloudformation ./cloudformation/template.yaml
# With environment variables for AWS
$env:AWS_ACCESS_KEY_ID="your_key"
$env:AWS_SECRET_ACCESS_KEY="your_secret"
docker run -it --rm -v "${PWD}:/work" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY spd109/devops-uat:latest scan-cloudformation template.yaml
# Scan Docker image with output to specific location
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-docker nginx:latest
Command Prompt (CMD):
REM Current directory
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-terraform terraform\
REM Full path (note the backslash escaping for Windows paths)
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-terraform C:\path\to\terraform\
REM Scan a specific file
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-arm azure-arm\template.json
Bash/ZSH:
# Current directory
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform ./terraform/
# Absolute path
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform /path/to/terraform/
# Single file scan
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-bicep ./azure-bicep/template.bicep
# With environment variables
AWS_ACCESS_KEY_ID=your_key AWS_SECRET_ACCESS_KEY=your_secret docker run -it --rm -v "$(pwd):/work" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY spd109/devops-uat:latest scan-cloudformation template.yaml
Fish Shell:
# Current directory
docker run -it --rm -v (pwd):/work spd109/devops-uat:latest scan-terraform ./terraform/
# Absolute path
docker run -it --rm -v (pwd):/work spd109/devops-uat:latest scan-terraform /path/to/terraform/
Command Prompt (cmd.exe):
REM Basic scan
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-terraform terraform\
REM With environment variables
set AWS_ACCESS_KEY_ID=your_key
set AWS_SECRET_ACCESS_KEY=your_secret
docker run -it --rm -v "%cd%:/work" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY spd109/devops-uat:latest scan-cloudformation template.yaml
PowerShell Core (pwsh):
# Basic scan
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-terraform terraform/
# With environment variables
$env:AWS_ACCESS_KEY_ID="your_key"
$env:AWS_SECRET_ACCESS_KEY="your_secret"
docker run -it --rm -v "${PWD}:/work" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY spd109/devops-uat:latest scan-cloudformation template.yaml
Bash:
# Basic scan
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
# With environment variables
export AWS_ACCESS_KEY_ID="your_key"
export AWS_SECRET_ACCESS_KEY="your_secret"
docker run -it --rm -v "$(pwd):/work" -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY spd109/devops-uat:latest scan-cloudformation template.yaml
Zsh:
# Basic scan (same as bash)
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
# With array environment variables
typeset -A env_vars
env_vars[AWS_ACCESS_KEY_ID]="your_key"
env_vars[AWS_SECRET_ACCESS_KEY]="your_secret"
docker run -it --rm -v "$(pwd):/work" -e AWS_ACCESS_KEY_ID="${env_vars[AWS_ACCESS_KEY_ID]}" -e AWS_SECRET_ACCESS_KEY="${env_vars[AWS_SECRET_ACCESS_KEY]}" spd109/devops-uat:latest scan-cloudformation template.yaml
Each scan creates two files:
*-scan-report.log) - Full terminal output with timestamps*-summary.txt) - Human-readable findings overview=================================================================
DOCKER SECURITY SCAN REPORT
=================================================================
Target: nginx:latest
Scan Started: Thu Dec 26 15:30:45 UTC 2024
Scanner: Trivy (Vulnerabilities + Secrets + Misconfigurations)
=================================================================
[2024-12-26 15:30:45] โ
SUCCESS: Target image found: nginx:latest
[2024-12-26 15:30:46] โ ๏ธ WARNING: 17 vulnerabilities found
[2024-12-26 15:30:46] โ
SUCCESS: No secrets detected
[2024-12-26 15:30:46] โ
SUCCESS: Scan completed successfully
Set these for cloud provider authentication:
# AWS (for CloudFormation validation)
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
# Azure (for ARM/Bicep validation)
export AZURE_CLIENT_ID=your_client_id
export AZURE_CLIENT_SECRET=your_secret
# GCP (for Deployment Manager validation)
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
# AWS (for CloudFormation validation)
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
# Azure (for ARM/Bicep validation)
export AZURE_CLIENT_ID=your_client_id
export AZURE_CLIENT_SECRET=your_secret
# GCP (for Deployment Manager validation)
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
name: Infrastructure Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Scanner
run: |
docker pull spd109/devops-uat:latest
- name: Scan Infrastructure
run: |
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-cloudformation cloudformation/
- name: Upload Reports
uses: actions/upload-artifact@v3
with:
name: security-reports
path: |
*-scan-report.log
*-summary.txt
# .gitlab-ci.yml
stages:
- security-scan
infrastructure-security:
stage: security-scan
image: python:3.9
services:
- docker:dind
tags:
- docker # Most likely your runner name
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
before_script:
- docker pull spd109/devops-uat:latest
script:
- docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
- docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-cloudformation cloudformation/
- docker run -it --rm spd109/devops-uat:latest scan-docker $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
artifacts:
reports:
# GitLab will parse these as security reports
sast: "*-scan-report.log"
paths:
- "*-scan-report.log"
- "*-summary.txt"
expire_in: 1 week
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# azure-pipelines.yml
trigger:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: SecurityScan
displayName: 'Infrastructure Security Scan'
jobs:
- job: SecurityAnalysis
displayName: 'Run Security Scanners'
steps:
- task: Docker@2
displayName: 'Pull Scanner Image'
inputs:
command: 'pull'
arguments: 'spd109/devops-uat:latest'
- task: PythonScript@0
displayName: 'Scan Terraform'
inputs:
scriptSource: 'inline'
script: |
import subprocess
result = subprocess.run(['docker', 'run', '-it', '--rm', '-v', '$(pwd):/work', 'spd109/devops-uat:latest', 'scan-terraform', 'terraform/'],
capture_output=True, text=True)
print(result.stdout)
if result.stderr:
print("STDERR:", result.stderr)
- task: PythonScript@0
displayName: 'Scan CloudFormation'
inputs:
scriptSource: 'inline'
script: |
import subprocess
result = subprocess.run(['docker', 'run', '-it', '--rm', '-v', '$(pwd):/work', 'spd109/devops-uat:latest', 'scan-cloudformation', 'cloudformation/'],
capture_output=True, text=True)
print(result.stdout)
if result.stderr:
print("STDERR:", result.stderr)
- task: PublishBuildArtifacts@1
displayName: 'Publish Security Reports'
inputs:
pathToPublish: '.'
artifactName: 'security-reports'
artifactType: 'container'
includeRootFolder: false
# Only include scan reports and summaries
contents: |
*-scan-report.log
*-summary.txt
- task: PublishTestResults@2
displayName: 'Publish Security Test Results'
condition: always()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '*-scan-report.log'
failTaskOnFailedTests: false
testRunTitle: 'Infrastructure Security Scan Results'
pipeline {
agent any
stages {
stage('Security Scan') {
steps {
sh 'docker pull spd109/devops-uat:latest'
sh 'docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/'
sh 'docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-cloudformation cloudformation/'
archiveArtifacts artifacts: '*-scan-report.log, *-summary.txt'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: '.',
reportFiles: '*-summary.txt',
reportName: 'Security Scan Report'
])
}
}
}
}
The repository includes comprehensive test files with intentional security vulnerabilities for validating the scanner's capabilities.
โ ๏ธ WARNING: These files contain intentional security misconfigurations and should NEVER be used in production! Do not deploy them in any live environment. They are strictly for testing and educational purposes. Like really, don't use these in production! I'm serious, these files are designed to break things and expose vulnerabilities. Use them wisely in isolated environments only. Don't say I didn't warn you! If you deploy these in production, you're asking for trouble. Seriously, don't do it! Consider this your final warning: these files are for testing only. They will cause security issues if used in production. Use at your own risk! Cause if you deploy these in production, you're basically inviting hackers to your system. So please, for the love of security, don't use these files in any live environment! And remember, these files are meant to help you learn about security vulnerabilities, not to create them in your production systems. Use them wisely and responsibly! Just don't deploy these in production, okay? They're meant to help you learn about security vulnerabilities, not to create them in your production systems. Use them wisely and responsibly! Exactly, these files are meant to help you learn about security vulnerabilities, not to create them in your production systems. Use them wisely and responsibly!
test-files/
โโโ terraform/ # Terraform configurations with vulnerabilities
โโโ cloudformation/ # AWS CloudFormation templates with issues
โโโ azure-arm/ # Azure ARM templates with misconfigurations
โโโ azure-bicep/ # Azure Bicep templates with security issues
โโโ gcp-deployment-manager/ # GCP templates with vulnerabilities
โโโ kubernetes/ # Kubernetes manifests with security flaws
โโโ docker/ # Docker and container configuration issues
Terraform (terraform/):
main.tf - Multi-cloud infrastructure with hardcoded credentials, unencrypted resourcesvariables.tf - Sensitive data in defaults, no input validationoutputs.tf - Outputting credentials and sensitive informationproviders.tf - Hardcoded credentials, weak security settingskubernetes-clusters.tf - Multi-cloud K8s clusters with security vulnerabilitiesCloudFormation (cloudformation/):
ec2-instance.yaml - Unencrypted storage, overly permissive security groupsrds-database.json - Public access, weak passwords, no encryptions3-iam-vulnerable.json - Public bucket access, overly permissive IAMnetworking-vulnerable.yaml - Wide-open security groups and network ACLsserverless-vulnerable.yaml - Lambda, API Gateway, DynamoDB with security issuesAzure ARM (azure-arm/):
vm-with-storage.json - Unencrypted storage, weak authenticationkeyvault-sql-vulnerable.json - Weak access policies, public network accessAzure Bicep (azure-bicep/):
storage-account.bicep - Public access, no encryption, weak TLSweb-app.bicep - HTTPS not enforced, hardcoded secretsGCP Deployment Manager (gcp-deployment-manager/):
vulnerable-infrastructure.yaml - Overly permissive firewall rules, public storagevm-template.jinja - Default service accounts, no shielded VMKubernetes (kubernetes/):
vulnerable-pod.yaml - Privileged containers, host access, security context issuesvulnerable-deployment.yaml - Insecure deployments, exposed secrets, no resource limitsDocker (docker/):
Dockerfile.vulnerable - Running as root, hardcoded secrets, insecure base imagesdocker-compose.vulnerable.yml - Privileged containers, exposed services, weak passwordsโ
Authentication & Authorization - Hardcoded credentials, weak passwords, overly permissive IAM
โ
Network Security - 0.0.0.0/0 access, public subnets, missing VPC flow logs
โ
Data Protection - Unencrypted storage, public read/write access, no backup encryption
โ
Monitoring & Logging - Disabled audit logging, no security monitoring
โ
Configuration Security - Debug modes enabled, default configurations, insecure protocols
โ
Information Disclosure - Outputting sensitive data, storing secrets in plain text
Windows (Command Prompt):
REM Test all scanners with included sample files
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-terraform test-files/terraform/
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-cloudformation test-files/cloudformation/
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-arm test-files/azure-arm/
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-bicep test-files/azure-bicep/
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-gcp test-files/gcp-deployment-manager/
docker run -it --rm spd109/devops-uat:latest scan-docker nginx:latest
REM Test specific vulnerable files
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-terraform test-files/terraform/kubernetes-clusters.tf
docker run -it --rm -v "%cd%:/work" spd109/devops-uat:latest scan-cloudformation test-files/cloudformation/serverless-vulnerable.yaml
Windows (PowerShell):
# Test all scanners with included sample files
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-terraform test-files/terraform/
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-cloudformation test-files/cloudformation/
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-arm test-files/azure-arm/
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-bicep test-files/azure-bicep/
docker run -it --rm -v "${PWD}:/work" spd109/devops-uat:latest scan-gcp test-files/gcp-deployment-manager/
docker run -it --rm spd109/devops-uat:latest scan-docker nginx:latest
Linux/macOS:
# Test all scanners with included sample files
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform test-files/terraform/
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-cloudformation test-files/cloudformation/
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-arm test-files/azure-arm/
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-bicep test-files/azure-bicep/
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-gcp test-files/gcp-deployment-manager/
docker run -it --rm spd109/devops-uat:latest scan-docker nginx:latest
Windows (Command Prompt):
REM Run the validation script to test all scanners
validate-setup.bat
Windows (PowerShell):
# Run the validation script to test all scanners
.\validate-setup.ps1
Linux/macOS:
# Create and run validation script
chmod +x validate-setup.sh
./validate-setup.sh
The validation scripts will:
Each test file should trigger multiple security findings:
scanners/scan-terraform.sh - TFLint + TFSec + Checkovscanners/scan-cloudformation.sh - CFN-Lint + Checkovscanners/scan-docker.sh - Trivy comprehensive scanningscanners/scan-arm.sh - ARM-TTK + Checkovscanners/scan-bicep.sh - Bicep CLI + Checkovscanners/scan-gcp.sh - Checkov + GCloud validation"Docker not found"
# Ensure Docker is installed and running
docker --version
docker info
"Permission denied"
# On Linux/macOS, ensure Docker is running
sudo systemctl start docker
"Volume mount failed"
# Ensure you're in the correct directory with your files
ls terraform/ # Should show your .tf files
docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/
MIT License - see LICENSE file for details.
docker pull spd109/devops-uat:latestvalidate-setup.bat (Windows) or ./validate-setup.sh (Linux/macOS)docker run -it --rm -v "$(pwd):/work" spd109/devops-uat:latest scan-terraform terraform/๐ Ready to scan? Start with: docker run -it --rm spd109/devops-uat:latest scan-docker nginx:latest
Content type
Image
Digest
sha256:6b14c2211โฆ
Size
408.1 MB
Last updated
6 months ago
docker pull spd109/devops-uat