Databases AWS

SQL Server 2025 Express on AWS User Guide

| Product: SQL Server 2025 Express on AWS

Overview

This image runs Microsoft SQL Server 2025 Express Edition, the free, entry-level edition for small databases, prototypes and learning. SQL Server is the only workload on the image, so the platform stays lean, predictable and easy to reason about.

Express Edition is the free entry-level engine, ideal for small databases, prototypes, learning and lightweight applications.

This guide covers the Express delivery option. SQL Server 2025 is also offered in other editions on the same listing -- see the SQL Server 2025 on AWS hub to compare and choose.

SQL Server is installed from the official Microsoft APT repository for Ubuntu 24.04. The mssql-tools18 package and the sqlcmd command-line utility are preinstalled.

On the first boot of your instance a one-shot service generates a fresh SA password, sets it via mssql-conf, re-applies the Express edition, creates a dedicated cloudimg SQL login, removes the build-time memory cap and writes all credentials to /root/mssql-credentials.txt, a file that only the root user can read. No shared or default credentials ship in the image. SQL Server listens on port 1433 and starts on boot via systemd.

Express edition at a glance: A maximum database size of 10 GB, roughly 1.4 GB of buffer-pool memory, and 1 socket or 4 cores. Backup compression is not available on Express.

This is a headless image. SQL Server has no web interface; you administer it over SSH with the sqlcmd command-line tool and any compatible SQL Server client on port 1433, both covered below.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Recommended instance type: t3.large or m5.large (Express is lightweight; larger types bring no benefit beyond its limits).

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for SQL Server 2025. Select the cloudimg listing and choose Select, then on the subscription summary pick the SQL Server 2025 Express on Ubuntu 24.04 delivery option and choose Continue.

Pick an instance type appropriate for your workload (see Prerequisites). Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network. Add port 1433 to the security group if you want external clients to connect to SQL Server directly. Leave the root volume at the default size or larger.

Select Launch instance. First-boot initialisation, which generates the SA password and starts SQL Server, takes a minute or two after the instance state becomes Running and the status checks pass.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg SQL Server 2025 Express Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing for the Express delivery option, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens inbound port 22 (and optionally 1433 for external SQL connections).

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.xlarge \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --metadata-options HttpTokens=required \
  --block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":40,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mssql-01}]'

The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running:

aws ec2 describe-instances \
  --instance-ids <instance-id> \
  --query "Reservations[].Instances[].PublicIpAddress" \
  --output text

Step 3: Connect over SSH

Connect over SSH with the key pair you selected and the public IP address from step 2. This delivery option is built on Ubuntu 24.04, so the SSH login user is ubuntu:

ssh ubuntu@<your-instance-ip>

Wait until the instance has passed both EC2 status checks before connecting. The first-boot service runs before the SSH daemon is ready, so SQL Server is initialised by the time you can log in.

Step 4: Retrieve the Generated SA Password

The first-boot service generates a fresh SA password for this instance and writes it, with the connection details, to /root/mssql-credentials.txt. The file is readable only by the root user. Display it from your SSH session:

sudo cat /root/mssql-credentials.txt

The file looks like this, with unique passwords on your instance:

# SQL Server 2025 Express Edition -- Per-Instance Credentials
# Generated: Wed Jun 04 09:00:00 UTC 2026
# Instance IP: 3.86.159.217
#
SA_USER=SA
SA_PASSWORD=Az6b3036366161212d18!fec2e071
CLOUDIMG_USER=cloudimg
CLOUDIMG_PASSWORD=Cle3946a05c9368d3c62!3510bba3
CLOUDIMG_DATABASE=cloudimg
#
# Connect: sqlcmd -S 3.86.159.217 -U SA -P 'Az6b3036366161212d18!fec2e071' -C

Keep this file secure. It contains the SA password for the SQL Server instance. The cloudimg login has db_owner membership on the cloudimg database and is suitable for application connections.

Step 5: Connect to SQL Server with sqlcmd

The sqlcmd command-line utility is preinstalled at /opt/mssql-tools18/bin/sqlcmd. Connect to the local SQL Server instance using the SA password from the credentials file:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C

The -C flag trusts the server certificate (the image uses a self-signed certificate). From the 1> prompt you can run T-SQL statements. Type GO to execute a batch and exit to quit.

To verify the SQL Server version and confirm the Express edition:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q "SELECT @@VERSION"

Output from this instance:

Microsoft SQL Server 2025 (RTM-CU5-GDR) (KB5095565) - 17.0.4050.1 (X64)
    May 15 2026 12:06:45
    Copyright (C) 2025 Microsoft Corporation
    Express Edition (64-bit) on Linux (Ubuntu 24.04.4 LTS) <X64>

Licensing

SQL Server Express Edition is a free edition and requires no product key. It is fully licensed for production use within its edition limits (see Overview).

Step 6: Check the SQL Server Service

SQL Server runs as a systemd service. Check its status with:

sudo systemctl status mssql-server --no-pager

Expected output:

mssql-server.service - Microsoft SQL Server Database Engine
     Loaded: loaded (/usr/lib/systemd/system/mssql-server.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-06-04 09:00:35 UTC; 16s ago
       Docs: https://docs.microsoft.com/en-us/sql/linux
   Main PID: 6640 (sqlservr)
      Tasks: 87
     Memory: 503.9M (peak: 503.9M)
        CPU: 8.057s

Manage the service with standard systemctl commands:

sudo systemctl stop mssql-server
sudo systemctl start mssql-server
sudo systemctl restart mssql-server

Step 7: Create a Database and Table

Connect to SQL Server and create a database with the following commands:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q "IF DB_ID('myapp') IS NULL CREATE DATABASE [myapp];"
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -d myapp -Q "IF OBJECT_ID('customers') IS NULL CREATE TABLE customers (id INT IDENTITY PRIMARY KEY, name NVARCHAR(100), email NVARCHAR(200), created_at DATETIME2 DEFAULT GETDATE()); INSERT INTO customers (name, email) VALUES ('Alice Smith', 'alice@example.com'); INSERT INTO customers (name, email) VALUES ('Bob Jones', 'bob@example.com'); SELECT id, name, email, created_at FROM customers;"

Sample output:

id name        email              created_at
-- ----------- ------------------ --------------------------
1  Alice Smith alice@example.com  2026-06-04 09:05:00.0000000
2  Bob Jones   bob@example.com    2026-06-04 09:05:00.1000000

(2 rows affected)

Express edition: backup compression is not supported. Omit WITH ... COMPRESSION from the BACKUP command (use WITH INIT only). Databases are also capped at 10 GB.

Step 8: Connect from a Remote Client

SQL Server listens on port 1433. To connect from a remote machine, add port 1433 to the instance security group inbound rules. Then connect using any SQL Server compatible client (SQL Server Management Studio, Azure Data Studio, DBeaver, or sqlcmd on another machine):

/opt/mssql-tools18/bin/sqlcmd -S <your-instance-ip>,1433 -U SA -P "<SA_PASSWORD>" -C

For production deployments, consider enabling SSL/TLS with a trusted certificate. See the Microsoft documentation on SQL Server on Linux encryption.

Step 9: Configuration with mssql-conf

The mssql-conf utility manages SQL Server configuration. View the current settings:

sudo /opt/mssql/bin/mssql-conf list

Set the maximum server memory (replace 8192 with your desired limit in MB):

sudo /opt/mssql/bin/mssql-conf set memory.memorylimitmb 8192
sudo systemctl restart mssql-server

The first-boot service removes the build-time memory cap automatically, so SQL Server starts with no explicit memory limit on your instance (within the edition's own buffer-pool ceiling). Set an explicit limit only if you need to share the host with other workloads.

Step 10: Backup and Restore

Create the backup directory and back up the cloudimg database to a local file:

sudo mkdir -p /var/opt/mssql/backup
sudo chown mssql:mssql /var/opt/mssql/backup
SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q \
  "BACKUP DATABASE [cloudimg] TO DISK = N'/var/opt/mssql/backup/cloudimg.bak' WITH INIT;"

Restore from a backup file:

SA_PASS=$(sudo grep '^SA_PASSWORD=' /root/mssql-credentials.txt | cut -d= -f2-)
/opt/mssql-tools18/bin/sqlcmd -S 127.0.0.1 -U SA -P "${SA_PASS}" -C -Q \
  "RESTORE DATABASE [cloudimg] FROM DISK = N'/var/opt/mssql/backup/cloudimg.bak' WITH REPLACE;"

Troubleshooting

SQL Server will not start. Check the SQL Server error log:

sudo cat /var/opt/mssql/log/errorlog | tail -50

Check the systemd journal:

sudo journalctl -u mssql-server -n 50 --no-pager

Port 1433 not reachable from the internet. Check the EC2 security group inbound rules for the instance. Port 1433 must be open from your client IP or CIDR range.

Permission denied reading credentials. The credentials file is owned by root with mode 600. Use sudo:

sudo cat /root/mssql-credentials.txt

First-boot did not run. Check the first-boot service log:

sudo journalctl -u mssql-firstboot -n 50 --no-pager
sudo cat /var/log/mssql-firstboot.log

cloudimg Support

This image is supported by cloudimg. For technical assistance with SQL Server deployment, configuration, performance tuning, high availability, query optimisation or database administration, contact support at support@cloudimg.co.uk.

Support is available 24 hours a day, 7 days a week.