Set up SonarQube scanner in Kubernetes pods with admission controllers for automated security scanning. Configure CI/CD pipeline integration and security reporting for continuous code quality analysis in containerized environments.
Prerequisites
- Kubernetes cluster with kubectl access
- SonarQube server instance
- Helm 3.x installed
- Administrative privileges
- Basic understanding of YAML and containers
What this solves
This tutorial configures SonarQube security scanning within Kubernetes workflows to automatically analyze code quality and security vulnerabilities in containerized applications. You'll set up scanner pods, admission controllers, and automated reporting to catch security issues before deployment.
Step-by-step configuration
Install prerequisites and update system
Start by updating your system packages and installing required tools for Kubernetes and SonarQube integration.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget jq git kubectl helm
Create SonarQube namespace and security contexts
Set up a dedicated namespace for SonarQube operations with proper security contexts and RBAC permissions.
kubectl create namespace sonarqube-security
apiVersion: v1
kind: ServiceAccount
metadata:
name: sonarqube-scanner
namespace: sonarqube-security
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: sonarqube-scanner-role
rules:
- apiGroups: [""]
resources: ["pods", "configmaps", "secrets"]
verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingadmissionwebhooks"]
verbs: ["get", "list", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sonarqube-scanner-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: sonarqube-scanner-role
subjects:
- kind: ServiceAccount
name: sonarqube-scanner
namespace: sonarqube-security
kubectl apply -f sonarqube-rbac.yaml
Configure SonarQube scanner ConfigMap
Create a ConfigMap with SonarQube scanner configuration and security scanning rules for different programming languages.
apiVersion: v1
kind: ConfigMap
metadata:
name: sonarqube-scanner-config
namespace: sonarqube-security
data:
sonar-scanner.properties: |
sonar.host.url=https://sonarqube.example.com
sonar.projectKey=${PROJECT_KEY}
sonar.projectName=${PROJECT_NAME}
sonar.projectVersion=${BUILD_NUMBER}
sonar.sources=.
sonar.exclusions=/test/,/vendor/,/node_modules/
sonar.security.hotspots=REVIEW
sonar.qualitygate.wait=true
sonar.qualitygate.timeout=300
security-rules.json: |
{
"securityRules": {
"java": {
"rules": ["java:S2068", "java:S2078", "java:S5146"],
"severity": "BLOCKER"
},
"javascript": {
"rules": ["javascript:S2068", "javascript:S4426", "javascript:S5122"],
"severity": "CRITICAL"
},
"python": {
"rules": ["python:S2068", "python:S5245", "python:S4507"],
"severity": "CRITICAL"
},
"docker": {
"rules": ["docker:S6471", "docker:S6472", "docker:S6473"],
"severity": "MAJOR"
}
}
}
kubectl apply -f scanner-config.yaml
Create SonarQube scanner pod template
Set up a pod template for running SonarQube scans with security contexts and resource limits.
apiVersion: v1
kind: Pod
metadata:
name: sonarqube-scanner-pod
namespace: sonarqube-security
labels:
app: sonarqube-scanner
spec:
serviceAccountName: sonarqube-scanner
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
initContainers:
- name: git-clone
image: alpine/git:2.40.1
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
command: ['/bin/sh']
args:
- -c
- |
git clone ${GIT_REPO_URL} /workspace
cd /workspace
git checkout ${GIT_BRANCH:-main}
env:
- name: GIT_REPO_URL
value: "https://github.com/example/app.git"
- name: GIT_BRANCH
value: "main"
volumeMounts:
- name: workspace
mountPath: /workspace
- name: tmp
mountPath: /tmp
containers:
- name: sonar-scanner
image: sonarsource/sonar-scanner-cli:5.0.1
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
env:
- name: SONAR_TOKEN
valueFrom:
secretKeyRef:
name: sonarqube-token
key: token
- name: PROJECT_KEY
value: "k8s-security-scan"
- name: PROJECT_NAME
value: "Kubernetes Security Scan"
- name: BUILD_NUMBER
value: "1.0"
workingDir: /workspace
volumeMounts:
- name: workspace
mountPath: /workspace
- name: scanner-config
mountPath: /opt/sonar-scanner/conf
readOnly: true
- name: tmp
mountPath: /tmp
resources:
limits:
memory: "2Gi"
cpu: "1000m"
requests:
memory: "1Gi"
cpu: "500m"
volumes:
- name: workspace
emptyDir: {}
- name: scanner-config
configMap:
name: sonarqube-scanner-config
- name: tmp
emptyDir: {}
restartPolicy: Never
Create SonarQube authentication secret
Store your SonarQube authentication token securely as a Kubernetes secret.
kubectl create secret generic sonarqube-token \
--from-literal=token="your-sonarqube-token-here" \
--namespace=sonarqube-security
Deploy admission controller webhook
Set up a validating admission controller that triggers SonarQube scans before allowing deployments.
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonarqube-admission-controller
namespace: sonarqube-security
spec:
replicas: 2
selector:
matchLabels:
app: sonarqube-admission-controller
template:
metadata:
labels:
app: sonarqube-admission-controller
spec:
serviceAccountName: sonarqube-scanner
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: admission-controller
image: admission-controller:latest
ports:
- containerPort: 8443
name: webhook
env:
- name: TLS_CERT_FILE
value: "/etc/certs/tls.crt"
- name: TLS_KEY_FILE
value: "/etc/certs/tls.key"
- name: SONAR_URL
value: "https://sonarqube.example.com"
- name: SONAR_TOKEN
valueFrom:
secretKeyRef:
name: sonarqube-token
key: token
volumeMounts:
- name: certs
mountPath: "/etc/certs"
readOnly: true
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
volumes:
- name: certs
secret:
secretName: admission-controller-certs
---
apiVersion: v1
kind: Service
metadata:
name: sonarqube-admission-service
namespace: sonarqube-security
spec:
selector:
app: sonarqube-admission-controller
ports:
- port: 443
targetPort: webhook
protocol: TCP
name: webhook
Configure validating admission webhook
Create the admission webhook configuration that intercepts deployment requests and triggers security scans.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionWebhook
metadata:
name: sonarqube-security-validator
webhooks:
- name: security-scan.sonarqube.example.com
clientConfig:
service:
name: sonarqube-admission-service
namespace: sonarqube-security
path: "/validate"
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
namespaceSelector:
matchLabels:
sonarqube-scan: "enabled"
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Fail
timeoutSeconds: 30
kubectl apply -f validating-webhook.yaml
Create CI/CD integration CronJob
Set up automated scanning with a CronJob that triggers regular security scans and integrates with your CI/CD pipeline.
apiVersion: batch/v1
kind: CronJob
metadata:
name: sonarqube-scheduled-scan
namespace: sonarqube-security
spec:
schedule: "0 2 *"
jobTemplate:
spec:
template:
spec:
serviceAccountName: sonarqube-scanner
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
initContainers:
- name: git-clone
image: alpine/git:2.40.1
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
command: ['/bin/sh']
args:
- -c
- |
git clone ${GIT_REPO_URL} /workspace
cd /workspace
git checkout ${GIT_BRANCH:-main}
env:
- name: GIT_REPO_URL
value: "https://github.com/example/app.git"
- name: GIT_BRANCH
value: "main"
volumeMounts:
- name: workspace
mountPath: /workspace
- name: tmp
mountPath: /tmp
containers:
- name: security-scanner
image: sonarsource/sonar-scanner-cli:5.0.1
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
env:
- name: SONAR_TOKEN
valueFrom:
secretKeyRef:
name: sonarqube-token
key: token
- name: PROJECT_KEY
value: "scheduled-security-scan"
workingDir: /workspace
command: ['/bin/sh']
args:
- -c
- |
sonar-scanner \
-Dsonar.projectKey=${PROJECT_KEY} \
-Dsonar.sources=. \
-Dsonar.host.url=https://sonarqube.example.com \
-Dsonar.login=${SONAR_TOKEN} \
-Dsonar.qualitygate.wait=true
# Send results to webhook
curl -X POST https://webhook.example.com/sonar-results \
-H "Content-Type: application/json" \
-d "{\"project\": \"${PROJECT_KEY}\", \"status\": \"completed\"}"
volumeMounts:
- name: workspace
mountPath: /workspace
- name: tmp
mountPath: /tmp
resources:
limits:
memory: "2Gi"
cpu: "1000m"
requests:
memory: "1Gi"
cpu: "500m"
volumes:
- name: workspace
emptyDir: {}
- name: tmp
emptyDir: {}
restartPolicy: OnFailure
kubectl apply -f cicd-cronjob.yaml
Deploy security reporting service
Create a service that collects SonarQube scan results and generates security reports with alerting capabilities.
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonarqube-reporting
namespace: sonarqube-security
spec:
replicas: 1
selector:
matchLabels:
app: sonarqube-reporting
template:
metadata:
labels:
app: sonarqube-reporting
spec:
serviceAccountName: sonarqube-scanner
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: reporting
image: python:3.11-alpine
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
env:
- name: SONAR_URL
value: "https://sonarqube.example.com"
- name: SONAR_TOKEN
valueFrom:
secretKeyRef:
name: sonarqube-token
key: token
- name: SLACK_WEBHOOK
valueFrom:
secretKeyRef:
name: notification-secrets
key: slack-webhook
command: ['/bin/sh']
args:
- -c
- |
pip install --user requests
python3 -c "
import requests
import json
import os
import time
def check_quality_gates():
headers = {'Authorization': f'Bearer {os.environ["SONAR_TOKEN"]}'}
response = requests.get(f'{os.environ["SONAR_URL"]}/api/qualitygates/project_status', headers=headers)
return response.json()
def send_alert(message):
webhook_url = os.environ.get('SLACK_WEBHOOK')
if webhook_url:
requests.post(webhook_url, json={'text': message})
while True:
try:
status = check_quality_gates()
if status.get('projectStatus', {}).get('status') == 'ERROR':
send_alert(f'🚨 Security scan failed for project: {status.get("projectStatus", {}).get("projectKey")}' )
time.sleep(300) # Check every 5 minutes
except Exception as e:
print(f'Error: {e}')
time.sleep(60)
"
volumeMounts:
- name: tmp
mountPath: /tmp
resources:
limits:
memory: "256Mi"
cpu: "200m"
requests:
memory: "128Mi"
cpu: "100m"
volumes:
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: sonarqube-reporting-service
namespace: sonarqube-security
spec:
selector:
app: sonarqube-reporting
ports:
- port: 8080
targetPort: 8080
kubectl apply -f reporting-service.yaml
Enable namespace for security scanning
Label target namespaces to enable automatic security scanning for deployments.
kubectl label namespace default sonarqube-scan=enabled
kubectl label namespace production sonarqube-scan=enabled
Create notification secrets
Configure notification endpoints for security alerts and scan results.
kubectl create secret generic notification-secrets \
--from-literal=slack-webhook="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK" \
--from-literal=email-smtp="smtp.example.com:587" \
--namespace=sonarqube-security
Verify your setup
Test the SonarQube Kubernetes integration by running scans and checking admission controller functionality.
# Check all components are running
kubectl get pods -n sonarqube-security
kubectl get validatingadmissionwebhooks
Test manual scan
kubectl apply -f scanner-pod-template.yaml
kubectl logs -f sonarqube-scanner-pod -n sonarqube-security
Verify admission controller
kubectl get events -n sonarqube-security --sort-by='.lastTimestamp'
Check CronJob status
kubectl get cronjobs -n sonarqube-security
kubectl get jobs -n sonarqube-security
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Scanner pod fails with permission denied | Incorrect security context or RBAC | kubectl describe pod -n sonarqube-security and check RBAC rules |
| Admission controller webhook timeout | Service not responding or TLS issues | Check service endpoints: kubectl get endpoints -n sonarqube-security |
| SonarQube authentication fails | Invalid or expired token | Regenerate token in SonarQube and update secret |
| Quality gate check fails | Network connectivity or API issues | Test connection: kubectl exec -it pod-name -- curl https://sonarqube.example.com/api/system/status |
| CronJob not triggering scans | Schedule syntax or resource limits | Check CronJob logs: kubectl describe cronjob sonarqube-scheduled-scan -n sonarqube-security |
Next steps
- Install and configure SonarQube for code quality analysis with PostgreSQL and SSL
- Setup SonarQube scanner for multiple programming languages with automated code quality analysis
- Implement Kubernetes admission controllers with OPA Gatekeeper for policy enforcement
- Configure Kubernetes network policies with Calico for container security
- Setup Tekton Pipelines for Kubernetes CI/CD with security scanning integration
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# SonarQube Kubernetes Security Scanning Integration Installer
# Usage: ./install_sonarqube_k8s.sh [SONARQUBE_URL] [PROJECT_KEY]
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SONARQUBE_URL="${1:-https://sonarqube.example.com}"
PROJECT_KEY="${2:-default-project}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Usage message
usage() {
cat << EOF
Usage: $0 [SONARQUBE_URL] [PROJECT_KEY]
Arguments:
SONARQUBE_URL SonarQube server URL (default: https://sonarqube.example.com)
PROJECT_KEY Default project key (default: default-project)
Example:
$0 https://sonarqube.mycompany.com my-app-project
EOF
exit 1
}
# Cleanup function
cleanup() {
if [ $? -ne 0 ]; then
log_error "Installation failed. Cleaning up..."
kubectl delete namespace sonarqube-security --ignore-not-found=true 2>/dev/null || true
fi
}
trap cleanup ERR
# Check if running as root or with sudo
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run as root or with sudo"
exit 1
fi
# Detect distribution
echo "[1/8] Detecting distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
PKG_LIST="dpkg -l"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
PKG_LIST="rpm -qa"
;;
fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
PKG_LIST="rpm -qa"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
PKG_LIST="rpm -qa"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_success "Detected $PRETTY_NAME using $PKG_MGR"
else
log_error "Cannot detect distribution"
exit 1
fi
# Update system packages
echo "[2/8] Updating system packages..."
$PKG_UPDATE
# Install prerequisites
echo "[3/8] Installing prerequisites..."
case "$PKG_MGR" in
apt)
$PKG_INSTALL curl wget jq git
# Install kubectl
if ! command -v kubectl &> /dev/null; then
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod 755 kubectl
mv kubectl /usr/local/bin/
fi
# Install helm
if ! command -v helm &> /dev/null; then
curl https://get.helm.sh/helm-v3.13.0-linux-amd64.tar.gz | tar xz
mv linux-amd64/helm /usr/local/bin/
chmod 755 /usr/local/bin/helm
rm -rf linux-amd64
fi
;;
dnf|yum)
if [ "$ID" = "centos" ] || [ "$ID" = "rhel" ] || [ "$ID" = "almalinux" ] || [ "$ID" = "rocky" ]; then
$PKG_INSTALL epel-release 2>/dev/null || true
fi
$PKG_INSTALL curl wget jq git
# Install kubectl
if ! command -v kubectl &> /dev/null; then
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod 755 kubectl
mv kubectl /usr/local/bin/
fi
# Install helm
if ! command -v helm &> /dev/null; then
curl https://get.helm.sh/helm-v3.13.0-linux-amd64.tar.gz | tar xz
mv linux-amd64/helm /usr/local/bin/
chmod 755 /usr/local/bin/helm
rm -rf linux-amd64
fi
;;
esac
log_success "Prerequisites installed"
# Verify kubectl connection
echo "[4/8] Verifying Kubernetes connection..."
if ! kubectl cluster-info &> /dev/null; then
log_error "Cannot connect to Kubernetes cluster. Please configure kubectl first."
exit 1
fi
log_success "Kubernetes cluster connection verified"
# Create SonarQube namespace and RBAC
echo "[5/8] Creating SonarQube namespace and RBAC..."
kubectl create namespace sonarqube-security --dry-run=client -o yaml | kubectl apply -f -
# Create RBAC configuration
cat > /tmp/sonarqube-rbac.yaml << 'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
name: sonarqube-scanner
namespace: sonarqube-security
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: sonarqube-scanner-role
rules:
- apiGroups: [""]
resources: ["pods", "configmaps", "secrets"]
verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingadmissionwebhooks"]
verbs: ["get", "list", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sonarqube-scanner-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: sonarqube-scanner-role
subjects:
- kind: ServiceAccount
name: sonarqube-scanner
namespace: sonarqube-security
EOF
kubectl apply -f /tmp/sonarqube-rbac.yaml
log_success "RBAC configuration applied"
# Create scanner ConfigMap
echo "[6/8] Creating SonarQube scanner configuration..."
cat > /tmp/scanner-config.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: sonarqube-scanner-config
namespace: sonarqube-security
data:
sonar-scanner.properties: |
sonar.host.url=${SONARQUBE_URL}
sonar.projectKey=${PROJECT_KEY}
sonar.projectName=\${PROJECT_NAME}
sonar.projectVersion=\${BUILD_NUMBER}
sonar.sources=.
sonar.exclusions=/test/,/vendor/,/node_modules/
sonar.security.hotspots=REVIEW
sonar.qualitygate.wait=true
sonar.qualitygate.timeout=300
security-rules.json: |
{
"securityRules": {
"java": {
"rules": ["java:S2068", "java:S2078", "java:S5146"],
"severity": "BLOCKER"
},
"javascript": {
"rules": ["javascript:S2068", "javascript:S4426", "javascript:S5122"],
"severity": "CRITICAL"
},
"python": {
"rules": ["python:S2068", "python:S5245", "python:S4507"],
"severity": "CRITICAL"
},
"docker": {
"rules": ["docker:S6471", "docker:S6472", "docker:S6473"],
"severity": "MAJOR"
}
}
}
EOF
kubectl apply -f /tmp/scanner-config.yaml
log_success "Scanner configuration created"
# Create scanner pod template
echo "[7/8] Creating scanner pod template..."
cat > /tmp/scanner-pod.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: sonarqube-scanner-pod
namespace: sonarqube-security
labels:
app: sonarqube-scanner
spec:
serviceAccountName: sonarqube-scanner
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
initContainers:
- name: git-clone
image: alpine/git:2.40.1
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
command: ['/bin/sh']
args:
- -c
- |
git clone ${GIT_REPO_URL} /workspace
cd /workspace
git checkout ${GIT_BRANCH:-main}
env:
- name: GIT_REPO_URL
value: "https://github.com/example/app.git"
- name: GIT_BRANCH
value: "main"
volumeMounts:
- name: workspace
mountPath: /workspace
- name: tmp
mountPath: /tmp
containers:
- name: sonar-scanner
image: sonarsource/sonar-scanner-cli:5.0
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
volumeMounts:
- name: workspace
mountPath: /usr/src
- name: scanner-config
mountPath: /opt/sonar-scanner/conf
- name: tmp
mountPath: /tmp
volumes:
- name: workspace
emptyDir: {}
- name: scanner-config
configMap:
name: sonarqube-scanner-config
- name: tmp
emptyDir: {}
restartPolicy: Never
EOF
kubectl apply -f /tmp/scanner-pod.yaml --dry-run=client -o yaml > /opt/sonarqube-scanner-pod.yaml
chmod 644 /opt/sonarqube-scanner-pod.yaml
log_success "Scanner pod template created at /opt/sonarqube-scanner-pod.yaml"
# Verification
echo "[8/8] Verifying installation..."
# Check namespace
if kubectl get namespace sonarqube-security &> /dev/null; then
log_success "✓ SonarQube namespace created"
else
log_error "✗ SonarQube namespace not found"
exit 1
fi
# Check service account
if kubectl get serviceaccount sonarqube-scanner -n sonarqube-security &> /dev/null; then
log_success "✓ Service account created"
else
log_error "✗ Service account not found"
exit 1
fi
# Check ConfigMap
if kubectl get configmap sonarqube-scanner-config -n sonarqube-security &> /dev/null; then
log_success "✓ Scanner configuration created"
else
log_error "✗ Scanner configuration not found"
exit 1
fi
# Cleanup temporary files
rm -f /tmp/sonarqube-rbac.yaml /tmp/scanner-config.yaml /tmp/scanner-pod.yaml
log_success "SonarQube Kubernetes security scanning integration installed successfully!"
echo ""
echo "Next steps:"
echo "1. Update SonarQube URL in ConfigMap: kubectl edit configmap sonarqube-scanner-config -n sonarqube-security"
echo "2. Create SonarQube authentication token and store as secret"
echo "3. Deploy scanner pod: kubectl apply -f /opt/sonarqube-scanner-pod.yaml"
echo "4. Configure your CI/CD pipeline to use the scanner pod template"
Review the script before running. Execute with: bash install.sh