v1.0.0 - Ready

1What is SonarQube?

SonarQube is a tool that analyzes your source code to find bugs, vulnerabilities, and quality issues. Think of it as a spell checker, but for programming — it scans every line of code and tells you what needs fixing.

1

Find bugs early

Detect problems before they reach production, when they're cheaper to fix.

2

Security by default

Identifies known vulnerabilities in your code following OWASP and CWE standards.

3

Measure quality

Tracks code coverage, duplication, complexity, and technical debt over time.

4

100% private

All analysis stays in your server. Nothing is sent to external services.

i
In simple words

If your code is a building, SonarQube is the inspector that checks every brick, wire, and pipe before it collapses.

2How to access the dashboard

You only need a web browser and the address of your server. Your administrator will provide it.

Open your browser

Any modern browser works: Chrome, Safari, Edge, or Firefox. No installation needed.

Type the URL

In the address bar, type the server address ending in port 9000:

http://your-server-address:9000

Sign in

Use the credentials provided by your administrator. The default ones are shown in the next section.

!
If the page does not load

Ask your administrator to verify that port 9000 is open in the AWS security group for your IP address. This is a technical step they must handle.

3Sign in for the first time

Each instance gets a unique admin password derived from its cloud identifier. Use the credentials provided by your administrator.

Field Default value
Usernameadmin
PasswordI-<instance-id>B!

How to find your password

The password always starts with the letter I, followed by your server identifier, and ends with B!. Example: if your server ID is i-0d267b6251f053ad8, the password is I-0d267b6251f053ad8B!.

!
Change your password now

Go to My Account → Security → Change password. Use a strong password with at least 12 characters. This is critical if your server is exposed to the internet.

4The dashboard at a glance

Once logged in, you will see a clean dashboard with metrics, charts, and a list of recent activity. Everything is designed to be read at a glance.

Menu
Projects
Issues
Measures
Quality Gates
Project Overview
Bugs
3
Vulnerabilities
1
Code Smells
42
[ Chart: Issues over time ]

Main sections

  • Projects: list of all code repositories under analysis.
  • Issues: detailed list of every bug, vulnerability, or code smell.
  • Measures: aggregated metrics like coverage, duplication, and complexity.
  • Quality Gates: rules that determine whether a project passes or fails.

5Reading analysis results

An analysis is a scan of your code that produces a report with everything SonarQube found. Here is how to read it.

What each result means

  • Bug: a piece of code that is likely to break in production.
  • Vulnerability: a security weakness that could be exploited.
  • Code Smell: code that works but is hard to maintain.
  • Security Hotspot: code that needs manual review for security.
  • Coverage: the percentage of your code covered by tests.
  • Duplication: how much of your code is repeated.
+
Useful tip

Start by fixing bugs and vulnerabilities — they affect production. Code smells can wait.

6Managing projects

Each code repository you want to analyze needs to be registered as a project. Your team's developer will handle the technical setup.

What you can do

  • View all projects: see the quality status of every repository at once.
  • Compare projects: see which ones have more issues.
  • Track progress: watch issues go down over time.
  • Export reports: download PDF summaries for management.
i
Quality gates

A "quality gate" is a rule that says whether a project is healthy. A green gate means the code is ready for release.

7Common issues

Issue Solution
The dashboard is empty No projects have been analyzed yet. Ask your developer to run the first scan.
I cannot log in Verify the URL is correct (port 9000). If the password does not work, ask your administrator to reset it.
The page is very slow Ask your administrator to check the server load. With many projects, the database may need optimization.
Numbers look wrong Make sure you are viewing the latest analysis. Old analyses are historical and do not reflect current code.
I see an error message Take a screenshot and send it to your administrator with the timestamp. It will help them find the cause.

8Best practices

For day-to-day use

  • Check the dashboard weekly: ten minutes a week keeps quality visible.
  • Focus on new issues: fix what was just introduced, not what was there for years.
  • Share reports: send screenshots to your team during sprint reviews.
  • Do not change settings: leave configuration to your administrator.

What to avoid

  • Do not share your password with anyone.
  • Do not ignore security vulnerabilities, even if they look minor.
  • Do not use SonarQube results as the only quality signal — combine with tests and code reviews.

You are ready!

Open the dashboard and start exploring your code quality data. The best way to learn is by using it.

1Full stack architecture

Complete SonarQube hardened stack deployed on a single EC2 t3.large instance (8 GB RAM) with all security tools preinstalled.

LayerTechnologyPort
Operating SystemUbuntu 26.04 LTS (resolute) - kernel 7.0 AWS-
Java RuntimeOpenJDK 21 (required by SonarQube 26.x)-
SonarQube ApplicationSonarQube 26.9.0.129388 (native, no Docker)9000
Relational DatabasePostgreSQL 16 (local socket)5432
Security ToolingLynis, ClamAV, OpenSCAP, auditd, fail2ban-
FirewallUFW (deny incoming, allow 22 + 9000)-

Important system paths

# SonarQube application
/opt/sonarqube/
  conf/sonar.properties    # Database and JVM config
  bin/linux-x86-64/sonar.sh
  logs/

# Data directories
/var/sonarqube/
  data/    # Elasticsearch indices
  temp/    # Scratch space
  logs/    # Application logs

# systemd units
/etc/systemd/system/sonarqube.service
/etc/systemd/system/set-sonar-password.service

# Password rotation scripts
/usr/local/bin/set-sonar-password.sh
/usr/local/bin/ver-password.sh

# Credentials (only readable by root)
/root/sonarqube-admin-password.txt
/root/README-AMI.txt

systemd services

sonarqube.service            -> main application (forking)
set-sonar-password.service   -> rotates admin password on boot (oneshot)
postgresql.service           -> database
clamav-freshclam.service     -> antivirus signature updates
fail2ban.service             -> SSH brute-force protection
auditd.service               -> kernel-level audit logging
ufw.service                  -> host firewall (oneshot)

2Endpoints

SonarQube exposes a web UI, a REST API, and a database connection for direct queries.

ServiceEndpointPurpose
SonarQube UIhttp://<host>:9000Web dashboard
SonarQube APIhttp://<host>:9000/apiREST API for automation
System statushttp://<host>:9000/api/system/statusHealth check
PostgreSQLlocalhost:5432Direct database access

Example API calls

# Check SonarQube is up
curl -s http://localhost:9000/api/system/status | jq .

# Verify admin credentials
curl -u admin:AdminDefault1! http://localhost:9000/api/users/current

# List all projects
curl -u admin:PASSWORD http://localhost:9000/api/projects/search

3Password rotation

On every boot, set-sonar-password.service reads the EC2 Instance ID via IMDSv2 and rotates the SonarQube admin password to a deterministic value derived from it.

Password rule

Password = "I-" +  + "B!"

Example:
  Instance ID:  i-0d267b6251f053ad8
  Password:     I-0d267b6251f053ad8B!

Rotation flow

1. Read Instance ID from IMDSv2:
   TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
     -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
   INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
     http://169.254.169.254/latest/meta-data/instance-id)

2. Build PASSWORD = "I-${INSTANCE_ID#i-}B!"

3. Wait for SonarQube to respond on /api/system/status

4. Check if admin/AdminDefault1! still works:
   curl -u admin:AdminDefault1! /api/users/current   -> 200

5. If yes, POST /api/users/change_password with:
   login=admin
   previousPassword=AdminDefault1!
   password=I-B!

6. Save credentials to /root/sonarqube-admin-password.txt (0600)

Manual rotation

# Force rotation at any time
sudo /usr/local/bin/set-sonar-password.sh

# View current credentials
sudo /usr/local/bin/ver-password.sh
sudo cat /root/sonarqube-admin-password.txt
i
Why the AMI ships with AdminDefault1!

The build resets the admin hash to AdminDefault1! before creating the AMI so the rotation script has a known starting point. On the first boot of each new instance, the password is rotated to the Instance-ID-derived value.

4systemd services

Basic commands

# Status
sudo systemctl status sonarqube postgresql clamav-freshclam fail2ban auditd

# Restart SonarQube
sudo systemctl restart sonarqube

# Enable/disable at boot
sudo systemctl enable sonarqube
sudo systemctl disable sonarqube

# Check all our services are enabled
sudo systemctl is-enabled sonarqube set-sonar-password postgresql clamav-freshclam fail2ban auditd ufw

sonarqube.service structure

# /etc/systemd/system/sonarqube.service
[Unit]
Description=SonarQube service
After=syslog.target network.target postgresql.service

[Service]
Type=forking
ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop
User=sonarqube
Group=sonarqube
Restart=on-failure
RestartSec=10
LimitNOFILE=131072
LimitNPROC=8192
LimitCORE=infinity
LimitMEMLOCK=infinity
TasksMax=infinity
Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64"
Environment="SONAR_JAVA_PATH=/usr/lib/jvm/java-21-openjdk-amd64/bin/java"

[Install]
WantedBy=multi-user.target

Adjust JVM memory

sudo vim /opt/sonarqube/conf/sonar.properties

# Default (t3.large / 8 GB):
sonar.web.javaOpts=-Xmx1536m -Xms512m -XX:+HeapDumpOnOutOfMemoryError
sonar.ce.javaOpts=-Xmx1536m -Xms512m -XX:+HeapDumpOnOutOfMemoryError
sonar.search.javaOpts=-Xmx1024m -Xms1024m -XX:+HeapDumpOnOutOfMemoryError

# Restart after changes
sudo systemctl restart sonarqube

5PostgreSQL

SonarQube uses PostgreSQL for its relational data. Default database and user are both called sonarqube.

Connect

# As the postgres user
sudo -u postgres psql

# Directly into the SonarQube DB
sudo -u postgres psql -d sonarqube

Useful queries

-- List tables
\dt

-- Count users
SELECT count(*) FROM users;

-- Show admin row
SELECT login, hash_method, reset_password
FROM users WHERE login='admin';

-- Recent analysis jobs
SELECT uuid, status, submitted_at
FROM ce_queue
ORDER BY submitted_at DESC LIMIT 10;

Reset admin hash (recovery)

If both AdminDefault1! and the Instance-ID password fail, inject a known hash to recover access:

sudo systemctl stop sonarqube

sudo -u postgres psql -d sonarqube <<'SQL'
UPDATE users
SET crypted_password='100000$t2h8AtNs1AlCHuLobDjHQTn9XppwTIx88UjqUm4s8RsfTuXQHSd/fpFexAnewPsO6jGFQUv/24DnO55hY6Xew==',
    salt='k9x9eN127/3e/hf38iNiKwVfaVk=',
    hash_method='PBKDF2',
    reset_password='false',
    user_local='true'
WHERE login='admin';
SQL

sudo systemctl start sonarqube
sleep 120

# admin/admin now works -> change it to AdminDefault1!
curl -u admin:admin -X POST \
    "http://localhost:9000/api/users/change_password" \
    --data-urlencode "login=admin" \
    --data-urlencode "previousPassword=admin" \
    --data-urlencode "password=AdminDefault1!"

# Then re-run rotation
sudo /usr/local/bin/set-sonar-password.sh

6Security tools

This AMI ships with a full set of hardened security tools, all installed and enabled at boot.

Installed tools

ToolVersionPurpose
Lynis3.1.6System hardening audit and score
ClamAV1.5.4Antivirus signature-based scanning
OpenSCAP1.4.3CIS benchmark compliance
auditdlatestKernel-level audit logging
fail2banlatestSSH brute-force protection
UFWlatestHost firewall (deny incoming)
unattended-upgradeslatestAutomatic security patches

How to run them

# Lynis full audit
sudo lynis audit system
sudo grep -E "^\s*(warning|suggestion)" /var/log/lynis-report.dat | head -40

# ClamAV scan
sudo clamscan -r /opt
sudo systemctl status clamav-freshclam

# OpenSCAP CIS Level 1
sudo oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_cis_level1_server \
  --results /root/openscap-results.xml \
  --report /root/openscap-report.html \
  /usr/share/xml/scap/ssg/content/ssg-ubuntu2404-ds.xml

# auditd
sudo systemctl status auditd
sudo ausearch -ts today | head -20

# fail2ban
sudo fail2ban-client status sshd

# UFW
sudo ufw status verbose

Hardening applied at build

  • Kernel sysctl: vm.max_map_count=524288, fs.file-max=131072, kernel.dmesg_restrict=1, kernel.kptr_restrict=2
  • User limits: nofile=131072, nproc=8192 for the sonarqube user
  • Firewall: default deny incoming, ports 22 + 9000 open
  • Audit rules: Neo23x0 baseline loaded into /etc/audit/rules.d/audit.rules
  • Automatic security updates enabled
i
Typical Lynis score

On this image, Lynis produces a hardening index between 75 and 85 out of 100. Remaining suggestions are usually about SSH configuration (which is intentionally left untouched) and optional PAM tweaks.

7Logs and monitoring

Service logs

sudo journalctl -u sonarqube -f
sudo journalctl -u sonarqube -n 200 --no-pager
sudo journalctl -u set-sonar-password --no-pager | tail -30

Application logs

sudo tail -f /var/sonarqube/logs/sonar.log
sudo tail -f /var/sonarqube/logs/web.log
sudo tail -f /var/sonarqube/logs/es.log     # Elasticsearch
sudo tail -f /var/sonarqube/logs/ce.log     # Compute Engine

System monitoring

free -h
df -h /
top -b -n 1 | head -20
sudo ss -tulpn | grep -E ':(5432|9000)'

Ports

sudo ss -tulpn | grep -E ':(22|5432|9000)'

8Troubleshooting

SymptomCauseSolution
SonarQube stuck on STARTING Elasticsearch still booting (cold start) Wait 5 min, then check /var/sonarqube/logs/es.log
Service failed with OOM Instance RAM too small Resize to t3.large (8 GB)
Password rotation never runs IMDSv2 blocked or service disabled sudo systemctl enable --now set-sonar-password.service
Both passwords return 401 Unknown password state Reset hash via PostgreSQL (see PostgreSQL section)
Port 9000 unreachable Security Group missing rule Add inbound TCP 9000
!BA: event not found in bash History expansion in interactive shell Run set +H or use single quotes

Quick diagnostic

# Services
systemctl is-active sonarqube postgresql clamav-freshclam fail2ban auditd
systemctl is-enabled sonarqube set-sonar-password postgresql clamav-freshclam fail2ban auditd ufw

# Ports
sudo ss -tulpn | grep -E ':(22|5432|9000)'

# SonarQube API
curl -s http://localhost:9000/api/system/status | jq .

# Default password check
set +H
curl -u 'admin:AdminDefault1!' -s -o /dev/null -w "%{http_code}\n" \
    http://localhost:9000/api/users/current

# Rotation log
sudo journalctl -u set-sonar-password.service --no-pager | tail -20

# Resources
free -h
df -h /

9AMI notes

+
Automatic startup

This AMI starts SonarQube, PostgreSQL, ClamAV, fail2ban, auditd, and UFW automatically via systemd on every boot. No manual intervention is required.

Startup timeline

TimeEvent
T+0sInstance starts
T+10sPostgreSQL starts
T+15sSonarQube service begins startup
T+90sElasticsearch ready, web server starting
T+180sSonarQube reports UP
T+185sPassword rotation runs and completes
T+190sUI available at http://<ip>:9000

Launching multiple instances

To launch several instances from this AMI, ensure your security group allows inbound traffic to port 9000 from your management CIDR:

aws ec2 authorize-security-group-ingress \
  --group-id sg-xxxxxxxx \
  --protocol tcp \
  --port 9000 \
  --cidr <your-ip>/32

Instance recommendations

Instance TypeRAMVerdict
t3.small / t3.micro2 GBWill OOM
t3.medium4 GBMinimum
t3.large8 GBRecommended
t3.xlarge16 GBComfortable
i
Default credentials

Username: admin — Default password before rotation: AdminDefault1!. After the first boot, the password is I-<instance-id>B!. Change it after first login in production.

Files to know about

PathPurpose
/root/README-AMI.txtFull usage guide
/root/sonarqube-admin-password.txtAuto-generated credentials file
/root/openscap-report.htmlCIS benchmark report
/usr/local/bin/ver-password.shShow credentials
/usr/local/bin/set-sonar-password.shForce password rotation
/opt/sonarqube/conf/sonar.propertiesApplication config