1+ name : Azure Terraform Security Scan
2+
3+ on :
4+ push :
5+ paths :
6+ - ' **.tf'
7+ - ' .github/workflows/terraform-scan.yml'
8+ pull_request :
9+ paths :
10+ - ' **.tf'
11+ - ' .github/workflows/terraform-scan.yml'
12+ workflow_dispatch : # Allow manual triggering
13+
14+ jobs :
15+ security-scan :
16+ name : Azure Terraform Security Scan
17+ runs-on : ubuntu-latest
18+ steps :
19+ - name : Checkout repository
20+ uses : actions/checkout@v4
21+
22+ - name : Setup Terraform
23+ uses : hashicorp/setup-terraform@v3
24+ with :
25+ terraform_version : " 1.6.0"
26+
27+ - name : Install Terrascan
28+ run : |
29+ TERRASCAN_VERSION=$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | jq -r '.tag_name')
30+ TERRASCAN_VERSION=${TERRASCAN_VERSION#v}
31+ wget https://github.com/tenable/terrascan/releases/download/v${TERRASCAN_VERSION}/terrascan_${TERRASCAN_VERSION}_Linux_x86_64.tar.gz -O terrascan.tar.gz
32+ tar -xf terrascan.tar.gz terrascan
33+ rm terrascan.tar.gz
34+ sudo install terrascan /usr/local/bin
35+ rm terrascan
36+
37+ - name : Initialize Terraform
38+ run : terraform init -backend=false
39+
40+ - name : Run Terrascan for Azure
41+ id : terrascan
42+ run : |
43+ # Create scan config file for Azure
44+ cat > config.toml << EOF
45+ [rules]
46+ skip-rules = [
47+ "AC_AZURE_0356", # Skip rule for public network access as we're using firewall rules
48+ "AC_AZURE_0185" # Skip rule for default virtual network as we're defining custom ones
49+ ]
50+
51+ [severity]
52+ level = "HIGH"
53+
54+ [notifications]
55+ webhook = false
56+ EOF
57+
58+ # Run scan with Azure-specific configuration
59+ terrascan scan \
60+ --config config.toml \
61+ -t azure \
62+ -i terraform \
63+ --non-recursive \
64+ -d . \
65+ -o json | tee terrascan-results.json
66+
67+ # Generate human readable output
68+ terrascan scan \
69+ --config config.toml \
70+ -t azure \
71+ -i terraform \
72+ --non-recursive \
73+ -d . \
74+ -o human | tee terrascan-human.txt
75+ continue-on-error : true
76+
77+ - name : Run Azure Policy Compliance Check
78+ run : |
79+ terraform show -json | jq . > plan.json
80+ # Add Azure policy compliance check here if needed
81+
82+ - name : Parse Results
83+ id : parse
84+ run : |
85+ HIGH_COUNT=$(jq -r '.results.violations | map(select(.severity == "HIGH")) | length' terrascan-results.json || echo "0")
86+ MEDIUM_COUNT=$(jq -r '.results.violations | map(select(.severity == "MEDIUM")) | length' terrascan-results.json || echo "0")
87+ echo "high_severity_count=${HIGH_COUNT}" >> $GITHUB_ENV
88+ echo "medium_severity_count=${MEDIUM_COUNT}" >> $GITHUB_ENV
89+
90+ echo "Summary of Azure Security Findings:"
91+ echo "High severity issues: ${HIGH_COUNT}"
92+ echo "Medium severity issues: ${MEDIUM_COUNT}"
93+
94+ # Extract specific Azure-related violations
95+ jq -r '.results.violations[] | select(.severity == "HIGH") | "Rule: \(.rule_id)\nDescription: \(.description)\n"' terrascan-results.json > azure-high-severity.txt
96+
97+ - name : Upload Results
98+ uses : actions/upload-artifact@v4
99+ if : always()
100+ with :
101+ name : azure-terraform-scan-results
102+ path : |
103+ terrascan-results.json
104+ terrascan-human.txt
105+ azure-high-severity.txt
106+ plan.json
107+
108+ - name : Check Results and Apply Azure-Specific Policies
109+ run : |
110+ if [ "${{ env.high_severity_count }}" -gt 0 ]; then
111+ echo "::error::Found ${{ env.high_severity_count }} high severity Azure security issues!"
112+ cat azure-high-severity.txt
113+ exit 1
114+ fi
115+ if [ "${{ env.medium_severity_count }}" -gt 5 ]; then
116+ echo "::warning::Found more than 5 medium severity Azure security issues"
117+ fi
0 commit comments