SonarQube Service Mesh

SonarQube Code Quality Analysis Service Mesh Istio Kubernetes CI/CD Quality Gate Bug Vulnerability Coverage Duplication mTLS

MetricTargetImpactGate
Coverage (New Code)> 80%ลด Bug ใน ProductionBlock if < 80%
Bugs (New)0ป้องกัน Bug เข้า ProductionBlock if > 0
Vulnerabilities (New)0ป้องกันช่องโหว่Block if > 0
Code Smell (New)< 10MaintainabilityWarning if > 10
Duplication (New)< 3%ลด Technical DebtBlock if > 3%
Security Hotspots100% ReviewedSecurity ReviewBlock if < 100%

Kubernetes Deployment

# === SonarQube on Kubernetes with Istio ===

# helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
# helm repo update
#
# helm install sonarqube sonarqube/sonarqube \
#   --namespace sonarqube \
#   --create-namespace \
#   --set persistence.enabled=true \
#   --set persistence.size=20Gi \
#   --set resources.requests.cpu=1 \
#   --set resources.requests.memory=2Gi \
#   --set resources.limits.cpu=2 \
#   --set resources.limits.memory=4Gi \
#   --set postgresql.enabled=true

# Istio VirtualService
# apiVersion: networking.istio.io/v1beta1
# kind: VirtualService
# metadata:
#   name: sonarqube
#   namespace: sonarqube
# spec:
#   hosts:
#     - sonar.internal.example.com
#   gateways:
#     - istio-system/internal-gateway
#   http:
#     - route:
#         - destination:
#             host: sonarqube-sonarqube
#             port:
#               number: 9000

# AuthorizationPolicy - Only CI/CD runners can access
# apiVersion: security.istio.io/v1beta1
# kind: AuthorizationPolicy
# metadata:
#   name: sonarqube-access
#   namespace: sonarqube
# spec:
#   selector:
#     matchLabels:
#       app: sonarqube
#   rules:
#     - from:
#         - source:
#             namespaces: ["ci-cd", "dev"]
#             principals: ["cluster.local/ns/ci-cd/sa/runner"]

from dataclasses import dataclass

@dataclass
class K8sResource:
    resource: str
    purpose: str
    namespace: str
    config: str

resources = [
    K8sResource("Deployment (SonarQube)",
        "SonarQube Server + Sidecar",
        "sonarqube",
        "CPU: 2 cores, RAM: 4Gi, PV: 20Gi, Sidecar: Istio"),
    K8sResource("StatefulSet (PostgreSQL)",
        "Database สำหรับ SonarQube",
        "sonarqube",
        "CPU: 1 core, RAM: 2Gi, PV: 10Gi, Sidecar: Istio"),
    K8sResource("VirtualService",
        "Istio Ingress Routing",
        "sonarqube",
        "Host: sonar.internal.example.com → Port 9000"),
    K8sResource("PeerAuthentication",
        "mTLS STRICT Mode",
        "sonarqube",
        "mtls.mode: STRICT (เข้ารหัสทุก Traffic)"),
    K8sResource("AuthorizationPolicy",
        "จำกัด Access เฉพาะ CI/CD",
        "sonarqube",
        "Allow from: ci-cd namespace, runner SA only"),
    K8sResource("NetworkPolicy",
        "จำกัด Network Traffic",
        "sonarqube",
        "Ingress: Port 9000 from ci-cd, Egress: PostgreSQL only"),
]

print("=== K8s Resources ===")
for r in resources:
    print(f"  [{r.resource}] {r.purpose}")
    print(f"    Namespace: {r.namespace}")
    print(f"    Config: {r.config}")

CI/CD Integration

# === CI/CD Pipeline with SonarQube ===

# GitHub Actions Example
# name: SonarQube Analysis
# on: [pull_request]
# jobs:
#   sonar:
#     runs-on: ubuntu-latest
#     steps:
#       - uses: actions/checkout@v4
#         with:
#           fetch-depth: 0
#       - name: SonarQube Scan
#         uses: SonarSource/sonarqube-scan-action@v2
#         env:
#           SONAR_TOKEN: }
#           SONAR_HOST_URL: }
#       - name: Quality Gate Check
#         uses: SonarSource/sonarqube-quality-gate-action@v1
#         timeout-minutes: 5
#         env:
#           SONAR_TOKEN: }

# sonar-project.properties
# sonar.projectKey=my-service
# sonar.sources=src
# sonar.tests=tests
# sonar.language=py
# sonar.python.coverage.reportPaths=coverage.xml
# sonar.qualitygate.wait=true

@dataclass
class PipelineStep:
    step: int
    action: str
    tool: str
    on_fail: str

pipeline = [
    PipelineStep(1, "Checkout Code (fetch-depth: 0 สำหรับ blame)",
        "actions/checkout@v4",
        "Pipeline Fail"),
    PipelineStep(2, "Run Unit Tests + Coverage Report",
        "pytest --cov --cov-report=xml",
        "Pipeline Fail (Tests ไม่ผ่าน)"),
    PipelineStep(3, "SonarQube Scan (ส่ง Code + Coverage)",
        "sonarqube-scan-action / sonar-scanner",
        "Pipeline Fail (Scan Error)"),
    PipelineStep(4, "Wait for Quality Gate Result",
        "sonarqube-quality-gate-action",
        "Block PR Merge (Quality Gate ไม่ผ่าน)"),
    PipelineStep(5, "Post Result to PR Comment",
        "SonarQube GitHub Integration",
        "แสดง Warning แต่ไม่ Block"),
    PipelineStep(6, "Deploy (ถ้า Quality Gate ผ่าน)",
        "kubectl apply / helm upgrade",
        "ไม่ Deploy"),
]

print("=== CI/CD Pipeline ===")
for p in pipeline:
    print(f"  Step {p.step}: {p.action}")
    print(f"    Tool: {p.tool}")
    print(f"    On Fail: {p.on_fail}")

Security in Service Mesh

# === Security Considerations ===

@dataclass
class SecurityConfig:
    concern: str
    solution: str
    config: str
    impact: str

security = [
    SecurityConfig("Traffic Encryption",
        "Istio mTLS STRICT Mode",
        "PeerAuthentication mtls.mode: STRICT",
        "ทุก Traffic เข้ารหัส รวมถึง SonarQube ↔ PostgreSQL"),
    SecurityConfig("Access Control",
        "AuthorizationPolicy จำกัดเฉพาะ CI/CD",
        "Allow from ci-cd namespace + runner SA",
        "Developer เข้าผ่าน UI ได้ แต่ Scan ต้องจาก CI/CD"),
    SecurityConfig("Secret Management",
        "Kubernetes Secret + External Secret Operator",
        "SONAR_TOKEN เก็บใน Secret ไม่ Hardcode",
        "Token ไม่รั่วไหล Rotate ได้"),
    SecurityConfig("Network Isolation",
        "NetworkPolicy จำกัด Ingress/Egress",
        "Ingress: 9000 from ci-cd, Egress: PostgreSQL 5432",
        "ป้องกัน Lateral Movement ถ้า Pod ถูก Compromise"),
    SecurityConfig("RBAC",
        "SonarQube User/Group Permission",
        "Project Admin Execute Analysis Browse View",
        "แยก Permission ตาม Role Developer Admin CI"),
    SecurityConfig("Audit Log",
        "SonarQube Activity Log + Istio Access Log",
        "ดูใน Administration → Audit Logs",
        "ติดตามว่าใครทำอะไรกับ SonarQube"),
]

print("=== Security Configs ===")
for s in security:
    print(f"  [{s.concern}]")
    print(f"    Solution: {s.solution}")
    print(f"    Config: {s.config}")
    print(f"    Impact: {s.impact}")

เคล็ดลับ

  • Quality Gate: ตั้ง Quality Gate ให้เข้มงวด Block PR ถ้าไม่ผ่าน
  • New Code: Focus ที่ New Code Period ไม่ใช่ Overall ลด Technical Debt ค่อยๆ
  • mTLS: เปิด STRICT mTLS ทุก Traffic ใน SonarQube Namespace
  • Resource: ให้ SonarQube อย่างน้อย 2 CPU 4Gi RAM ไม่งั้น Scan ช้า
  • Webhook: ใช้ Webhook แจ้ง CI/CD ว่า Quality Gate ผ่านหรือไม่

SonarQube คืออะไร

Code Quality Platform Bug Vulnerability Code Smell Duplication Coverage Quality Gate Quality Profile 30+ Languages CI/CD Jenkins GitHub Actions