Scan your AWS fleet for Ubuntu versions and Pro status with one SSM script

With Ubuntu 20.04 reaching end of standard support on May 31, 2025, AWS users need a fast way to identify which EC2 instances are still running outdated versions and whether those machines are covered by an Ubuntu Pro subscription for extended security.

This guide shows you how to audit your entire Ubuntu AWS fleet in minutes, by running custom scripts in your fleet using AWS Systems Manager (SSM). You’ll get an Excel-friendly list of each instance’s ID, Ubuntu version, and Pro subscription status

Requirements

To follow this guide, you need:

  • A Linux machine: This could be your workstation or another EC2 instance.
  • AWS CLI installed.
  • SSM permissions: Either AWS CLI configured with an account that has permission to run SSM commands or an EC2 machine with SSM permissions attached as a role.
  • SSM-managed instances: Your machines must appear under the “Fleet Management” menu in AWS Systems Manager.

The AWS CLI allows you to run SSM commands just like in the console, but with added flexibility for automation and integration.

Our goal is to generate an Excel-readable sheet containing the instance ID, Ubuntu version, and whether the instance is attached to an Ubuntu Pro subscription.

Below, we outline the process before presenting a complete Bash script to automate the task.


Step 1: Get all Your Ubuntu managed machines

We start by querying all managed instances and filtering for Ubuntu:

aws ssm describe-instance-information \
  --query "InstanceInformationList[*].[InstanceId, PlatformName, PlatformVersion]" \
  --no-paginate \
  --output text | grep 'Ubuntu'

Note: There is no built-in OS filter in this command, so we use grep to narrow down results.


Step 2: Send an Ad-hoc Command to Check Ubuntu Pro Status

To determine if an instance is attached to Ubuntu Pro, we need to run the following command inside each machine:

sudo pro status --format yaml | grep attached

This extracts the attached status from the pro status output in YAML format. If the instance is Pro-enabled, the output will be:

attached: true

To execute this command remotely on each instance, we use aws ssm send-command with the AWS-RunShellScript document:

aws ssm send-command \
  --instance-ids "$instanceID" \
  --document-name "AWS-RunShellScript" \
  --comment "Pro Status" \
  --parameters commands="sudo pro status --format yaml | grep attached" \
  --query "Command.CommandId" \
  --output text

Since this command runs asynchronously, it returns a CommandId that we will use to retrieve the output later.


Step 3: Retrieve the command output

To check the command execution status:

aws ssm list-command-invocations \
  --command-id "$command_id" \
  --details \
  --query "CommandInvocations[0].Status" \
  --output text

If the status is Success, we can extract the output:

aws ssm list-command-invocations \
  --command-id "$command_id" \
  --details \
  --query "CommandInvocations[0].CommandPlugins[0].Output" \
  --output text

This command fetches only the relevant output from the command invocation.


Step 4: Automate the process with a Bash script

Now that we know how to fetch information from a remote machine using SSM, the final step should be to automate the whole process to be run at scale with a single script.

The script will have to:

  • Retrieve all Ubuntu instances managed by SSM.
  • Send the pro status command to each instance.
  • Implement a retry mechanism to handle delays in command execution.
  • Output instance details in a structured format.
#!/bin/bash

# Get all Ubuntu managed instances
instances=$(aws ssm describe-instance-information --query "InstanceInformationList[*].[InstanceId, PlatformName, PlatformVersion]" --no-paginate --output text | grep 'Ubuntu')

# Query each instance by running a shell-script command
while read -r line; do
    # Extract the instance ID (first column)
    instanceID=$(echo "$line" | awk '{print $1}')

    # Send the command and capture the Command ID
    command_id=$(aws ssm send-command \
        --instance-ids "$instanceID" \
        --document-name "AWS-RunShellScript" \
        --comment "UA Status" \
        --parameters commands="sudo pro status --format yaml | grep attached" \
        --query "Command.CommandId" \
        --output text)

    if [[ -z "$command_id" ]]; then
        echo "$line Failed to send command"
        continue
    fi

    # Retry mechanism
    max_retries=10
    sleep_time=5
    attempt=1
    status="InProgress"

    while [[ "$status" == "InProgress" || "$status" == "Pending" ]]; do
        if (( attempt > max_retries )); then
            echo "$line Max retries reached. Skipping..."
            break
        fi

        status=$(aws ssm list-command-invocations \
            --command-id "$command_id" \
            --details \
            --query "CommandInvocations[0].Status" \
            --output text)

        if [[ "$status" == "Success" ]]; then
            output=$(aws ssm list-command-invocations \
                --command-id "$command_id" \
                --details \
                --query "CommandInvocations[0].CommandPlugins[0].Output" \
                --output text)
            break
        fi

        sleep "$sleep_time"
        ((attempt++))
    done

    echo "$line $output"
done <<< "$instances"

Save this bash script with a name, say ubuntu-state.sh add execute permissions with chmod +x ubuntu-state.sh and run it as follows, to generate a csv file (it will be separated by tabs instead of commas):

./ubuntu-state.sh >> my_ubuntu_state.csv

Example Output

i-0f45639632b5b0a79    Ubuntu  22.04   attached: true
i-0027c5909b1d95b96    Ubuntu  24.04   attached: false
i-05837539fc263ddbe    Ubuntu  20.04   attached: true
i-0d014199681cfa791    Ubuntu  22.04   attached: true

Customization Tips

  • Add more commands (e.g., available ESM packages, security updates).
  • Join this data with EC2 instance tags or metadata for better fleet reports.
  • Integrate into monitoring dashboards or compliance checks.

Final Thoughts

By using AWS SSM and the AWS CLI, you can quickly audit Ubuntu versions and subscription statuses across all EC2 instances, avoiding manual checks and ensuring compliance as Ubuntu 20.04 reaches its end of life.

This solution is scalable, flexible, and easily customizable for your needs. Stay ahead of 20.04 End of Support risks and security gaps by automating this audit today.